二、AOP相關概念
(1)AOP是什麼?AOP與攔截器的區別?
太抽象的不說,如果你知道Struts2的攔截器,攔截器就是應用的AOP的思想,它用於攔截Action以進行一些預處理或結果處理。而spring的AOP是一種更通用的模式,可以攔截Spring管理的Bean,功能更強大,適用範圍也更廣,它是通過動態代理與反射機制實現的。(更詳細的解釋可參看博客 http://blog.csdn.NET/zhangliangzi/article/details/51648032 )
(2)使用AOP需要的一些概念。
1.通知(Advice)
通知定義了在切入點代碼執行時間點附近需要做的工作。
Spring支持五種類型的通知:
Before(前) org.apringframework.aop.MethodBeforeAdvice
After-returning(返回後) org.springframework.aop.AfterReturningAdvice
After-throwing(拋出後) org.springframework.aop.ThrowsAdvice
Arround(周圍) org.aopaliance.intercept.MethodInterceptor
Introduction(引入) org.springframework.aop.IntroductionInterceptor
2.連接點(Joinpoint)
程序能夠應用通知的一個“時機”,這些“時機”就是連接點,例如方法調用時、異常拋出時、方法返回後等等。
3.切入點(Pointcut)
通知定義了切面要發生的“故事”,連接點定義了“故事”發生的時機,那麼切入點就定義了“故事”發生的地點,例如某個類或方法的名稱,Spring中允許我們方便的用正則表達式來指定。
4.切面(Aspect)
通知、連接點、切入點共同組成了切面:時間、地點和要發生的“故事”。
5.引入(Introduction)
引入允許我們向現有的類添加新的方法和屬性(Spring提供了一個方法注入的功能)。
6.目標(Target)
即被通知的對象,如果沒有AOP,那麼通知的邏輯就要寫在目標對象中,有了AOP之後它可以只關注自己要做的事,解耦合!
7.代理(proxy)
應用通知的對象,詳細內容參見設計模式裏面的動態代理模式。
8.織入(Weaving)
把切面應用到目標對象來創建新的代理對象的過程,織入一般發生在如下幾個時機:
(1)編譯時:當一個類文件被編譯時進行織入,這需要特殊的編譯器纔可以做的到,例如AspectJ的織入編譯器;
(2)類加載時:使用特殊的ClassLoader在目標類被加載到程序之前增強類的字節代碼;
(3)運行時:切面在運行的某個時刻被織入,SpringAOP就是以這種方式織入切面的,原理應該是使用了JDK的動態代理技術。
三、使用AOP的幾種方式
1.經典的基於代理的AOP
2.@AspectJ註解驅動的切面
3.純POJO切面
4.注入式AspectJ切面
四、Demo詳解
在講Demo之前,先把項目結構貼一下,我用的的一般的Java Project+Maven進行測試,用Web Project的小區別一會會說到。有一點很重要,jar依賴必須導入正確,我在測試過程中,很多bug都是因爲依賴問題引起的,這裏也貼一下。
包結構:
pom.xml:
下面開始正式的講解:
1、經典的基於代理的AOP實現,以一個睡覺的例子實現。
(1)可睡覺的接口,任何可以睡覺的人或機器都可以實現它。
(2)接口實現類,“Me”可以睡覺,“Me”就實現可以睡覺的接口。
(3)Me關注於睡覺的邏輯,但是睡覺需要其他功能輔助,比如睡前脫衣服,起牀脫衣服,這裏開始就需要AOP替“Me”完成!解耦!首先需要一個SleepHelper類。因爲一個是切入點前執行、一個是切入點之後執行,所以實現對應接口。
(4)最關鍵的來了,Spring核心配置文件application.xml配置AOP。
其中:
<beans>是Spring的配置標籤,beans裏面幾個重要的屬性:
xmlns:
是默認的xml文檔解析格式,即spring的beans。地址是http://www.springframework.org/schema/beans;通過設置這個屬性,所有在beans裏面聲明的屬性,可以直接通過<>來使用,比如<bean>等等。一個XML文件,只能聲明一個默認的語義解析的規範。例如上面的xml中就只有beans一個是默認的,其他的都需要通過特定的標籤來使用,比如aop,它自己有很多的屬性,如果要使用,前面就必須加上aop:xxx纔可以。類似的,如果默認的xmlns配置的是aop相關的語義解析規範,那麼在xml中就可以直接寫config這種標籤了。
xmlns:xsi:
是xml需要遵守的規範,通過URL可以看到,是w3的統一規範,後面通過xsi:schemaLocation來定位所有的解析文件。
xmlns:aop:
這個是重點,是我們這裏需要使用到的一些語義規範,與面向切面AOP相關。
xmlns:tx:
Spring中與事務相關的配置內容。
(5)測試類,Test,其中,通過AOP代理的方式執行Me的sleep()方法,會把執行前、執行後的操作執行,實現了AOP的效果!
執行結果:
(6)通過org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator簡化配置。
將配置文件中設置代理的代碼去掉,加上:
然後,在Test中,直接獲取me對象,執行sleep方法,就可以實現同樣的功能!
通過自動匹配,切面會自動匹配符合切入點的bean,會被自動代理,實現功能!
2、更簡單的方式,通過AspectJ提供的註解實現AOP。
(1)同樣的例子,修改後的SleepHelper:
(2)在方法中,可以加上JoinPoint參數以進行相關操作,如:
(3)然後修改配置爲:
(4)最後測試,一樣的結果!
3、使用Spring來定義純粹的POJO切面(名字很繞口,其實就是純粹通過<aop:fonfig>標籤配置,也是一種比較簡單的方式)。
(1)修改後的SleepHelper類,很正常的類,所以這種方式的優點就是在代碼中不體現任何AOP相關配置,純粹使用xml配置。
(2)配置文件:
(3)配置的另一種寫法
學東西還是要深入進去的,推薦一篇網評還不錯的博文,http://blog.csdn.net/moreevan/article/details/11977115/
二、AOP相關概念
(1)AOP是什麼?AOP與攔截器的區別?
太抽象的不說,如果你知道Struts2的攔截器,攔截器就是應用的AOP的思想,它用於攔截Action以進行一些預處理或結果處理。而spring的AOP是一種更通用的模式,可以攔截Spring管理的Bean,功能更強大,適用範圍也更廣,它是通過動態代理與反射機制實現的。(更詳細的解釋可參看博客 http://blog.csdn.NET/zhangliangzi/article/details/51648032 )
(2)使用AOP需要的一些概念。
1.通知(Advice)
通知定義了在切入點代碼執行時間點附近需要做的工作。
Spring支持五種類型的通知:
Before(前) org.apringframework.aop.MethodBeforeAdvice
After-returning(返回後) org.springframework.aop.AfterReturningAdvice
After-throwing(拋出後) org.springframework.aop.ThrowsAdvice
Arround(周圍) org.aopaliance.intercept.MethodInterceptor
Introduction(引入) org.springframework.aop.IntroductionInterceptor
2.連接點(Joinpoint)
程序能夠應用通知的一個“時機”,這些“時機”就是連接點,例如方法調用時、異常拋出時、方法返回後等等。
3.切入點(Pointcut)
通知定義了切面要發生的“故事”,連接點定義了“故事”發生的時機,那麼切入點就定義了“故事”發生的地點,例如某個類或方法的名稱,Spring中允許我們方便的用正則表達式來指定。
4.切面(Aspect)
通知、連接點、切入點共同組成了切面:時間、地點和要發生的“故事”。
5.引入(Introduction)
引入允許我們向現有的類添加新的方法和屬性(Spring提供了一個方法注入的功能)。
6.目標(Target)
即被通知的對象,如果沒有AOP,那麼通知的邏輯就要寫在目標對象中,有了AOP之後它可以只關注自己要做的事,解耦合!
7.代理(proxy)
應用通知的對象,詳細內容參見設計模式裏面的動態代理模式。
8.織入(Weaving)
把切面應用到目標對象來創建新的代理對象的過程,織入一般發生在如下幾個時機:
(1)編譯時:當一個類文件被編譯時進行織入,這需要特殊的編譯器纔可以做的到,例如AspectJ的織入編譯器;
(2)類加載時:使用特殊的ClassLoader在目標類被加載到程序之前增強類的字節代碼;
(3)運行時:切面在運行的某個時刻被織入,SpringAOP就是以這種方式織入切面的,原理應該是使用了JDK的動態代理技術。
三、使用AOP的幾種方式
1.經典的基於代理的AOP
2.@AspectJ註解驅動的切面
3.純POJO切面
4.注入式AspectJ切面
四、Demo詳解
在講Demo之前,先把項目結構貼一下,我用的的一般的Java Project+Maven進行測試,用Web Project的小區別一會會說到。有一點很重要,jar依賴必須導入正確,我在測試過程中,很多bug都是因爲依賴問題引起的,這裏也貼一下。
包結構:
pom.xml:
下面開始正式的講解:
1、經典的基於代理的AOP實現,以一個睡覺的例子實現。
(1)可睡覺的接口,任何可以睡覺的人或機器都可以實現它。
(2)接口實現類,“Me”可以睡覺,“Me”就實現可以睡覺的接口。
(3)Me關注於睡覺的邏輯,但是睡覺需要其他功能輔助,比如睡前脫衣服,起牀脫衣服,這裏開始就需要AOP替“Me”完成!解耦!首先需要一個SleepHelper類。因爲一個是切入點前執行、一個是切入點之後執行,所以實現對應接口。
(4)最關鍵的來了,Spring核心配置文件application.xml配置AOP。
其中:
<beans>是Spring的配置標籤,beans裏面幾個重要的屬性:
xmlns:
是默認的xml文檔解析格式,即spring的beans。地址是http://www.springframework.org/schema/beans;通過設置這個屬性,所有在beans裏面聲明的屬性,可以直接通過<>來使用,比如<bean>等等。一個XML文件,只能聲明一個默認的語義解析的規範。例如上面的xml中就只有beans一個是默認的,其他的都需要通過特定的標籤來使用,比如aop,它自己有很多的屬性,如果要使用,前面就必須加上aop:xxx纔可以。類似的,如果默認的xmlns配置的是aop相關的語義解析規範,那麼在xml中就可以直接寫config這種標籤了。
xmlns:xsi:
是xml需要遵守的規範,通過URL可以看到,是w3的統一規範,後面通過xsi:schemaLocation來定位所有的解析文件。
xmlns:aop:
這個是重點,是我們這裏需要使用到的一些語義規範,與面向切面AOP相關。
xmlns:tx:
Spring中與事務相關的配置內容。
(5)測試類,Test,其中,通過AOP代理的方式執行Me的sleep()方法,會把執行前、執行後的操作執行,實現了AOP的效果!
執行結果:
(6)通過org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator簡化配置。
將配置文件中設置代理的代碼去掉,加上:
然後,在Test中,直接獲取me對象,執行sleep方法,就可以實現同樣的功能!
通過自動匹配,切面會自動匹配符合切入點的bean,會被自動代理,實現功能!
2、更簡單的方式,通過AspectJ提供的註解實現AOP。
(1)同樣的例子,修改後的SleepHelper:
(2)在方法中,可以加上JoinPoint參數以進行相關操作,如:
(3)然後修改配置爲:
(4)最後測試,一樣的結果!
3、使用Spring來定義純粹的POJO切面(名字很繞口,其實就是純粹通過<aop:fonfig>標籤配置,也是一種比較簡單的方式)。
(1)修改後的SleepHelper類,很正常的類,所以這種方式的優點就是在代碼中不體現任何AOP相關配置,純粹使用xml配置。
(2)配置文件:
(3)配置的另一種寫法
學東西還是要深入進去的,推薦一篇網評還不錯的博文,http://blog.csdn.net/moreevan/article/details/11977115/