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就會攔截下它來,並給它加上事物的處理了