Spring AOP介紹
1、介紹
AOP(面向切面編程)對OOP(面向對象編程)是一種補充,它提供了另一種程序結構的思路。OOP的模塊單元是class,而AOP的模塊單元是aspect。Spring中一個關鍵的組件是AOP框架,然而,Spring IoC容器並不依賴於AOP,也就是說如果你不想用AOP的話可以不用。
在Spring框架中AOP用來做什麽呢?
- 提供聲明式的企業服務,特別是代替EJB的聲明式服務。最重要的的服務是聲明式事務管理。
- 允許用戶實現自定義的aspect
1.1、AOP概念
- Aspect(方面):橫切多個class的一個關註點的模塊化。事務管理是一個很好的例子。在Spring AOP中,aspect可以用普通類或者帶有@Aspect註解的普通類來實現。
- Join point(連接點):程序執行期間的一個點,比如方法的執行或者異常的處理。在Spring AOP中,一個連接點總是代表一個方法執行。
- Advice(通知):一個aspect在一個特定的連接點所采取的動作。通知的類型包括"around"、"before"、"after"。許多AOP框架,包括Spring也是,它們把一個通知作為一個攔截器,維護一個攔截器鏈環繞在連接點上。
- Pointcut(切入點):匹配連接點的一個謂詞。Advice關聯一個切點表達式。Spring默認用AspectJ切點表達式。
- Target object(目標對象):被一個或多個aspect通知的對象。在Spring AOP中是用運行時代理來實現的,因此這個對象總是一個代理對象。
- AOP proxy(AOP代理):為了實現aspect而被AOP框架所創建的一個對象。在Spring框架中,一個AOP proxy可能是一個JDK動態代理或者一個CGLIB代理。
1.2、通知的類型
- Before advice(前置通知):在一個連接點之前執行的通知,但是沒有能力阻止後面的執行(除非它拋異常)
- After returning advice(返回通知):在一個連接點正常執行完以後執行的通知:例如,在一個不拋異常的方法返回時執行
- After throwing advice(異常通知):如果方法因為拋出異常而退出了才會執行的通知
- After (finally) advice(後置通知):無論連接點正常退出還是異常退出都會執行
- Around advice(環繞通知):環繞一個連接點比如方法調用的通知。這是最強的一種通知。環繞通知可以在方法調用之前或之後執行自定義的行為。它也負責選擇是否處理連接點方法執行,通過返回一個它自己的返回或者拋出異常。環繞通知是用得最普遍的一種通知。
1.3、Spring AOP的能力和目標
Spring AOP用純Java實現。目前只支持方法執行的連接點,字段攔截沒有實現。
1.4、AOP Proxies
Spring AOP defaults to using standard JDK dynamic proxies for AOP proxies. This enables any interface (or set of interfaces) to be proxied.
Spring AOP can also use CGLIB proxies. This is necessary to proxy classes rather than interfaces.
CGLIB is used by default if a business object does not implement an interface. As it is good practice to program to interfaces rather than classes; business classes normally will implement one or more business interfaces.
默認JDK動態代理,如果對象沒有實現接口則用CGLIB
2、@AspectJ支持
@AspectJ是用註解來標註常規的Java類的一種聲明aspect的風格。
2.1、啟用@AspectJ支持
你需要開啟Spring對於基於@AspectJ aspects的Spring AOP配置的支持,和autoproxying beans的支持。autoproxying的意思是如果Spring檢測到一個bean被一個或多個aspect通知,它將自動為這個bean生產代理以攔截方法調用並確保通知被執行。
可以用XML或者Java配置的方式來開啟對@AspectJ的支持。你需要確保在你的工程的classpath下有aspectweaver.jar。
2.2、聲明一個aspect
2.3、聲明一個pointcut
A pointcut declaration has two parts: a signature comprising a name and any parameters, and a pointcut expression that determines exactly which method executions we are interested in. In the @AspectJ annotation-style of AOP, a pointcut signature is provided by a regular method definition, and the pointcut expression is indicated using the @Pointcut annotation (the method serving as the pointcut signature must have a void return type).
聲明一個pointcut有兩部分:一個簽名和一個切點表達式。簽名由一個name和任意參數組成,切點表達式決定對哪些方法執行感興趣。在註解風格的AOP中,一個pointcut簽名就是一個常規方法定義,而pointcut表達式用@Pointcut註解來標識(作為pointcut簽名的方法的返回值必須是void)
Spring AOP還支持下面這樣的切點表達式:
切點表達式可以組合使用
The format of an execution expression is:
2.4、聲明advice
3、基於XML格式的AOP支持
the keywords ‘and‘, ‘or‘ and ‘not‘ can be used in place of ‘&&‘, ‘||‘ and ‘!‘ respectively
4、選擇哪種AOP聲明方式
4.1、Spring AOP or full AspectJ?
4.2、@AspectJ or XML for Spring AOP?
如果你選擇用Spring AOP,那麽你可以選擇用@AspectJ或者XML風格。推薦用@AspectJ。
5、代理機制
Spring AOP用JDK動態代理或者CGLIB來創建目標對象的代理。(首選JDK動態代理)
如果被代理的目標對象至少實現了一個接口,那麽JDK動態代理將會被使用。而且,目標對象實現的所有接口都將被代理。
如果目標對象沒有實現任何接口,那麽一個CGLIB代理將會被創建。
如果你想強制使用CGLIB代理也是可以的,但是你需要考慮一個問題,那就是final方法不能被通知,因為它們不能被覆蓋。
如果你想強制使用CGLIB代理可以這樣做,二者選其一即可:
5.1、理解AOP代理
Spring AOP is proxy-based.(Spring AOP是基於代理的)
理解這個語義是極其重要的。
參考
《Spring Framework Reference Documentation》 4.3.14.RELEASE
Spring文檔下載地址
http://repo.springsource.org/libs-release-local/org/springframework/spring/
Spring AOP介紹