一、AOP 概念 Joinpoint:它定義在哪里加入你的邏輯功能,對于Spring AOP,Jointpoint指的就是Method。 Advice:特定的Jointpoint處運行的代碼,對于Spring AOP 來講,有Before advice、AfterreturningAdvice、ThrowAdvice、AroundAdvice(MethodInteceptor)等。 Pointcut:一組Joinpoint,就是說一個Advice可能在多個地方織入, Aspect:這個我一直迷惑,它實際是Advice和Pointcut的組合,但是Spring AOP 中的Advisor也是這樣一個東西,但是Spring中為什么叫Advisor而不叫做Aspect。 Weaving:將Aspect加入到程序代碼的過程,對于Spring AOP,由ProxyFactory或者ProxyFactoryBean負責織入動作。 Target:這個很容易理解,就是需要Aspect功能的對象。 Introduction:引入,就是向?qū)ο笾屑尤胄碌膶傩曰蚍椒?,一般是一個實例一個引用對象。當然如果不引入屬性或者引入的屬性做了線程安全性處理或者只讀屬性,則一個Class一個引用也是可以的(自己理解)。Per-class lifecycle or per-instance life cycle 二、AOP 種類 1、靜態(tài)織入:指在編譯時期就織入Aspect代碼,AspectJ好像是這樣做的。 2、動態(tài)織入:在運行時期織入,Spring AOP屬于動態(tài)織入,動態(tài)織入又分靜動兩種,靜則指織入過程只在第一次調(diào)用時執(zhí)行;動則指根據(jù)代碼動態(tài)運行的中間狀態(tài)來決定如何操作,每次調(diào)用Target的時候都執(zhí)行(性能較差)。 三、Spring AOP 代理原理 Spring AOP 是使用代理來完成的,Spring 會使用下面兩種方式的其中一種來創(chuàng)建代理: 1、JDK動態(tài)代理,特點只能代理接口,性能相對較差,需要設(shè)定一組代理接口。 2、CGLIB 代理,可代理接口和類(final method除外),性能較高(生成字節(jié)碼)。
四、Spring AOP 通知類型 1、BeforeAdvice:前置通知需實現(xiàn)MethodBeforeAdvice,但是該接口的Parent是BeforeAdvice,致于什么用處我想可能是擴展性需求的設(shè)計吧?;蛘逽pring未來也并不局限于Method的JoinPoint(胡亂猜測)。BeforeAdvice可以修改目標的參數(shù),也可以通過拋出異常來阻止目標運行。 2、AfterreturningAdvice:實現(xiàn)AfterreturningAdvice,我們無法修改方法的返回值,但是可以通過拋出異常阻止方法運行。 3、AroundAdvice:Spring 通過實現(xiàn)MethodInterceptor(aopalliance)來實現(xiàn)包圍通知,最大特點是可以修改返回值,當然它在方法前后都加入了自己的邏輯代碼,因此功能異常強大。通過MethodInvocation.proceed()來調(diào)用目標方法(甚至可以不調(diào)用)。 4、ThrowsAdvice:通過實現(xiàn)若干afterThrowing()來實現(xiàn)。 5、IntroductionInterceptor:Spring 的默認實現(xiàn)為DelegatingIntroductionInterceptor 五、Spring AOP Pointcut 以上只是Advice,如果不指定切入點,Spring 則使用所有可能的Jointpoint進行織入(當然如果你在Advice中進行方法檢查除外)。因此切入點在AOP中扮演一個十分重要的角色。Spring 2.0 推薦使用AspectJ的Annocation的切入點表達式來定義切入點,或者使用<aop:xxx/>來定義AOP,這方面本篇不做考慮。 1、Pointcut:它是Spring AOP Pointcut的核心,定義了getClassFilter()和getMethodMatcher()兩個方法。 2、ClassFilter:定義了matches(Class cls)一個方法。 3、MethodMatcher() 定義了matches(Method,Class),isRuntime(),matches(Mathod,Class,Object[])三個方法,如果isRuntime()返回true則表示為動態(tài)代理(實際是動態(tài)代理的動態(tài)代理),則調(diào)用第三個方法(每訪問一次調(diào)用一次),否則調(diào)用第一個方法(并且只調(diào)用一次) 4、Spring AOP 靜態(tài)切入點的幾個實現(xiàn)。 ComposablePointcut 太復雜一個切入點無法表達就用這個,union MethodMatcher和ClassFilter或者intersection MethodMatcher、ClassFilter和Pointcut。為什么不實現(xiàn)union Pointcut? 而只能通過Pointcuts類對Pointcut進行union操作。 ControlFlowPointcut 想對程序的運行過程進行追蹤就用這個 DynamicMatchMatcherPointcut 想用動態(tài)AOP 就用這個 JdkRegexpMethodPointcut 想使用正則表達式就用這個 Perl5RegexpMethodPointcut NameMatchMethodPointcut 想用方法名字來匹配就用這個 StaticMethodMatcherPointcut 靜態(tài)切入點就用這個 沒有人反對你直接實現(xiàn)Pointcut:)。 六、Spring AOP 中的Advisor其實就是Aspect 1、 PointcutAdvisor 其實一般使用DefaultPointcutAdvisor就足夠了,給它Advice和Pointcut。 當然如果想少寫那么幾行代碼也可以使用NameMatchMethodPointcutAdvisor,RegexpMethodPointcutAdvisor等。 更多Advisor可以查看API文檔。
2、 IntroductionAdvisor 默認實現(xiàn)為DefaultIntroductionAdvisor。 七、AOP ProxyFactory 使用代碼實現(xiàn)AOP 可使用ProxyFactory 聲明式AOP 可使用ProxyFactoryBean ProxyFactoryBean 需要設(shè)定 target,interceptorNames(可以是Advice或者Advisor,注意順序) 對接口代理需設(shè)置proxyInterfaces 八、自動代理 BeanNameAutoProxyCreator 代碼 - <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
- <property name="beanNames"><value>jdk*,onlyJdk</value></property>
- <property name="interceptorNames">
- <list>
- <value>myInterceptor</value>
- </list>
- </property>
- </bean>
DefaultAdvisorAutoProxyCreator 代碼 - <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
- <bean class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor">
- <property name="transactionInterceptor" ref="transactionInterceptor"/>
- </bean>
- <bean id="customAdvisor" class="com.mycompany.MyAdvisor"/>
- <bean id="businessObject1" class="com.mycompany.BusinessObject1">
- <!-- Properties omitted -->
- </bean>
- <bean id="businessObject2" class="com.mycompany.BusinessObject2"/>
九、Spring 2.0 AOP 略 以上為本人這段時間來看Spring AOP的一些學習體會,有什么說的不對的地方請批評指正。 |