AOP架構之AspectJ簡介,aop架構aspectj

來源:互聯網
上載者:User

AOP架構之AspectJ簡介,aop架構aspectj

        這幾天看JAVA基礎看的有點頭疼,決定時不時的換換口味,準備開始調研一些現在流行的技術,於是,開始埋頭思考自己知識的盲區(當時,自己的知識盲區茫茫多...),想了幾天后,決定要開始研究一下幾種技術及實現原理。

1、AOP技術應用及實現原理。

2、quartz調度的DB持久模式及叢集模式的實現及原理。

3、Mysql分庫分表的方法。

4、JFinal架構的學習。

目前先暫訂這個日常把,畢竟想搞定一塊以我的水平來看,都得一周時間。

       那麼今兒我們就先來談一談AspectJ的實現吧,類似這樣的文章在CSDN茫茫多,我為什麼寫這篇文章呢,因為我發現一提到AOP都是各路神仙開始講SpringAOP與AspectJ的區別,要麼就是SpringAOP的實現原理,感覺市面上缺少小白層級的文章,恰逢鄙人不才~SpringAOP的源碼看著沒啥靈感,也就只能寫寫這種教學文章了。

       下面正式開始!

1、首先是Maven配置,下面是需要引的包:

  <dependencies>    <dependency>      <groupId>junit</groupId>      <artifactId>junit</artifactId>        <version>4.10</version>      <scope>test</scope>    </dependency>      <!--springr容器-->    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-context</artifactId>      <version>${spring.version}</version>    </dependency>    <!--AspectJ包-->    <dependency>      <groupId>org.aspectj</groupId>      <artifactId>aspectjweaver</artifactId>      <version>1.7.4</version>    </dependency>    <!--通過SpringJUnit4ClassRunner註解測試-->    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-test</artifactId>      <version>3.1.0.RELEASE</version>      <scope>test</scope>    </dependency>

整個工程我採用了spring的架構結構,版本號碼為3.2.0.RELEASE。

Junit我用了4.1版本,為了方便測試的時候不用再編寫一連串的代碼來讀取spring容器。

2、下面看設定檔:

    <!--啟動AspectJ註解模式-->    <aop:aspectj-autoproxy/>    <!--spring容器掃描包路徑-->    <context:component-scan base-package="com.test"/>

就兩行~註解都解釋的很清楚了。

3、定義切面類

import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.*;import org.springframework.stereotype.Service;/** * Created with IntelliJ IDEA. * User: 菜鳥大明 * Date: 14-7-11 * Time: 上午10:03 * To change this template use File | Settings | File Templates. */@Service@Aspectpublic class AspectBean {    /** 必須為final String類型的,註解裡要使用的變數只能是靜態常量類型的 */    final static String expression = "execution(* com.test.*..*.*(..))";    // 第一種方式,定義Pointcut標籤    @Pointcut("execution(* com.test.*..*.*(..))")    private void pointCutMethod() {    }    // Before裡傳入@Pointcut所註解的方法    @Before("pointCutMethod()")    public void before() {        System.out.println("before");    }    @After(expression)    public void after() {        System.out.println("after");    }    // 第二種方式,直接傳入執行運算式    @Around(expression)    public void around(ProceedingJoinPoint joinPoint) {        System.out.println("around before");        try {            joinPoint.proceed();        } catch (Throwable throwable) {            throwable.printStackTrace();        }        System.out.println("around after");    }}

這裡我稍微說詳細一點,那麼@Service我就一句帶過了,就是注入容器,否則的話,你需要在spring-config.xml裡定義這個bean。

@Aspect就是定義這個類為切面,這塊其實挺不好理解的,如果理解不上去,就把@Aspect的註解類,當成是AOP橫切的母體。

@Before就是在這個類執行前運行。

@After就是在這個類執行後運行。

@Around這個其實跟Struts2裡的攔截器功能是一樣的,內部的實現也是類似。這種模式更靈活,也是我們平時運用最多的方式。但要記得這可是代理模式,如果想用反射操作業務類的話,你取到的可是代理。


4、業務類

@Servicepublic class Cat {    public void run () {        System.out.println("在跑");    }}


5、測試類別

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations = { "classpath*:spring-config.xml" })public class SpringAOPTest1 {    @Resource    Cat cat;    @Test    public void run() {        cat.run();    }}

文章開頭我說過,引入Junit 4.1以上的版本的目的就是為了省略那一長串讀取容器的寫法。

省略了ApplicationContext ac = new FileSystemXmlApplicationContext("applicationContext.xml");
    ac.getBean("beanId");


6、輸出結果:

around before
before
在跑
around after
after

我們不用關心是Around 和 Before After的執行順序,因為在正常的情況下,Around 與 Before、After很少在一起使用的。


總結:AspectJ給我的感覺比SpringAOP寫法更方便,不需要在xml裡嵌入過多的代碼。但有一個問題,實際項目中,使用這種POJO註解方式可能會給我們帶來“幽靈攔截器”。我們仔細觀察發現,要實現這個AOP功能,我們不需要嵌入任何業務代碼、業務上下文中,在自己的地盤兒寫好代碼,但這會造成什麼問題呢?

如果我們項目的管理目錄沒有做好,@AspectJ類到處飄,我們很難判斷到底有多少攔截器在對“封裝”我們的邏輯,要想尋找這些攔截器,只能全文檢索搜尋“@Aspect”再一個個去檢查。因此,想正確的使用AspectJ,不僅要做好代碼管理,還要寫好注釋,這樣才能方便別人來維護這些代碼。

下次我會帶來SpringAOP的簡單實現,下下次應該會做原理的分析,不過如果自己感覺吃力,就會考慮轉載一篇高手的解讀~







AspectJ怎實現AOP

我們只需要提供兩個不同的Aspect--認證Aspect和事務Aspect。 比如,我們有一個Bank(銀行)類。Bank有兩個方法,deposit(存錢)和withdraw(取錢)。 class Bank { public float deposit(AccountInfo account, float money){// 增加account賬戶的錢數,返回賬戶裡當前的錢數 }public float withdraw(AccountInfo account, float money){// 減少account賬戶的錢數,返回取出的錢數 }} 這兩個方法涉及到使用者的賬戶資金等重要訊息,必須要非常小心,所以編寫完上面的商業邏輯之後,項目負責人又提出了新的要求--給Bank類的每個重要方法加上安全認證特性。 於是,我們不得不分別在上面的兩個方法中加入安全認證的代碼。 class Bank { public float deposit(AccountInfo account, float money){// 驗證account是否為合法使用者 // 增加account賬戶的錢數,返回賬戶裡當前的錢數 }public float withdraw(AccountInfo account, float money){// 驗證account是否為合法使用者 // 減少account賬戶的錢數,返回取出的錢數 }}這兩個方法都需要操作資料庫,為了保持資料完整性,項目負責人又提出了新的要求--給Bank類的每個操作資料庫的方法加上事務控制。 於是,我們不得不分別在上面的兩個方法中加入安全認證的代碼。 class Bank { public float deposit(AccountInfo account, float money){// 驗證account是否為合法使用者 // Begin Transaction// 增加account賬戶的錢數,返回賬戶裡當前的錢數 // End Transaction}public float withdraw(AccountInfo account, float money){// 驗證account是否為合法使用者 // Begin Transaction// 減少account賬戶的錢數,返回取出的錢數 // End Transaction}}我們看到,這些與商業邏輯無關的重複代碼遍布在整個程式中。實際的工程項目中涉及到的類和函數,遠遠不止兩個。如何解決這種問題? 我們首先來看看OOP能否解決這個問題。 我們利用Design Pattern的Template Pattern,可以抽出一個架構,改變上面的例子的整個設計結構。 abstract class Base {public float importantMethod(AccountInfo account, float money){// 驗證account是否為合法使用者 // Begin Transactionfloat result = yourBusiness(account, money)// End Transactionreturn result;}pro......餘下全文>>
 
有人可以通俗介紹下SPRING的AOP?

想簡單通俗的說,額,有難度.AOP主要是針對事物處理來說吧,而且是相對於以前的編程式事物處理的,不用AOP的話,我們得通過硬式編碼方式將事物處理寫在方法中,有了AOP之後,我們只需要在spring的設定檔中配置一下事物就可以了,這就叫聲明式事物處理.一般配置時是通過配置匹配某個格式的方法名,當運行到這種方法的時候spring就會攔截下它來,並給它加上事物的處理了
 

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.