春節放假歸來,收心繼續工做學習,前面的筆記介紹了Spring AOP的簡單使用,但使用ProxyFactoryBean建立織入切面的代理時,每個須要代理的Bean都須要一個ProxyFactoryBean配置,在有不少的Bean都須要代理時,將增長大量的配置信息,並且這些配置信息有不少都是相同的,這種狀況下就應該使用Spring提供的自動建立代理了。
java
在內部,Spring使用BeanPostProcessor完成自動建立代理的工做,而BeanPostProcessor的自動代理建立起的實現類,根據匹配規則的不一樣大概分紅了三類:
spring
匹配Bean的名稱自動建立匹配到的Bean的代理,實現類BeanNameAutoProxyCreator學習
根據Advisor的匹配機制自動建立代理,會對容器中全部的Advisor進行掃描,自動將這些切面應用到匹配的Bean中,實現類DefaultAdvisorAutoProxyCreatorspa
根據Bean中的AspectJ註解自動建立代理,實現類AnnotationAwareAspectJAutoProxyCreator.net
例:如今有一個Waiter類和Seller類都須要織入GreetingBeforeAdvice的加強,使用BeanNameAutoProxyCreator自動建立代理咱們能夠以下配置:代理
...... <bean id="waiter" class="com.advisor.Waiter"/> <bean id="seller" class="com.advisor.Seller"/> <bean id="advisor" class="com.advisor.GreetingBeforeAdvice" /> <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator" p:beanNames="*er" p:interceptorNames="advisor" p:optimize="true" />
BeanNameAutoProxyCreator中的beanNames屬性值用來匹配其餘Bean的名稱,例子中*er表示匹配Bean名稱以er結尾的Bean織入GreetingBeforeAdvice加強,BeanNameAutoProxyCreator會自動建立代理,使用時直接用獲取對應的Bean返回的其實已是代理對象了code
例:如今有一個Waiter類和Seller類,他們都有一個greetTo()方法,咱們但願爲兩個類中的這個方法都織入GreetingBeforeAdvice加強對象
...... <bean id="waiter" class="com.advisor.Waiter"/> <bean id="seller" class="com.advisor.Seller"/> <bean id="advice" class="com.advisor.GreetingBeforeAdvice" /> <bean id="advisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor" p:patterns=".*greetTo.*" p:advice-ref="advice" /> <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" />
DefaultAdvisorAutoProxyCreator會對容器中全部的Advisor進行掃描,自動將這些切面應用到匹配的Bean中blog
使用AnnotationAwareAspectJAutoProxyCreator自動建立代理須要先學習AspectJ表達式,這裏就不詳細講解AspectJ表達式了,須要學習的請參考:spring AspectJ的Execution表達式 AspectJ表達式除了execution還有其餘的如args()、within()、target()等,有興趣能夠自行研究。繼承
例:使用Aspect實現上一樣的例子,在advisor中須要加入AspectJ註解
...... @AspectJ public class GreetingBeforeAdvisor { @Before("execution (* greetTo(..))") public void beforeGreeting() { ...... } }
能夠看到如今GreetingBeforeAdvice沒有繼承任何類,或實現任何接口,@AspectJ已經標註了他是一個切面,而方法上的@Before()表示下面方法中的代碼是前置加強的橫切邏輯。而後只須要在配置文件中配置:
...... <bean id="waiter" class="com.advisor.Waiter"/> <bean id="seller" class="com.advisor.Seller"/> <bean id="advice" class="com.advisor.GreetingBeforeAdvisor" /> <bean class="org.springframework.aop.aspectJ.annotation.AnnotationAwareAspectJAutoProxyCreator" /> <!-- 或者也能夠直接使用aop命名空間 <aop:aspectj-autoproxy /> -->
@Before
對應前置加強,有兩個成員:
value:用於定義切點(使用AspectJ表達式)
argNames:用於一共方法的參數名稱(必須與方法參數名稱一致,可選成員),因爲Java反射機制不可以獲得方法的入參名稱,有須要時能夠用這個成員變量提供出來
@AfterReturning
對應後置加強,有四個成員:
value:同上
pointcut:表示切點信息,能夠顯示指定pointcut,若指定覆蓋value效果
returning:邦隊目標對象方法放回加強方法中
argNames:同上
@Around
對應環繞加強,成員value、argNames同上
@AfterThrowing
異常拋出加強,有4個成員
value:同上
pointcut:同上
throwing;將拋出的異常綁定到加強中
argNames:同上
@After
沒有對應的加強接口,無論是拋出異常仍是正常退出總會獲得執行,通常用來釋放資源,value、argNames同上
@DeclareParents
對應引介加強