spring學習筆記(七)

前言

        春節放假歸來,收心繼續工做學習,前面的筆記介紹了Spring AOP的簡單使用,但使用ProxyFactoryBean建立織入切面的代理時,每個須要代理的Bean都須要一個ProxyFactoryBean配置,在有不少的Bean都須要代理時,將增長大量的配置信息,並且這些配置信息有不少都是相同的,這種狀況下就應該使用Spring提供的自動建立代理了。
java

自動建立代理

        在內部,Spring使用BeanPostProcessor完成自動建立代理的工做,而BeanPostProcessor的自動代理建立起的實現類,根據匹配規則的不一樣大概分紅了三類:
spring

  • 匹配Bean的名稱自動建立匹配到的Bean的代理,實現類BeanNameAutoProxyCreator學習

  • 根據Advisor的匹配機制自動建立代理,會對容器中全部的Advisor進行掃描,自動將這些切面應用到匹配的Bean中,實現類DefaultAdvisorAutoProxyCreatorspa

  • 根據Bean中的AspectJ註解自動建立代理,實現類AnnotationAwareAspectJAutoProxyCreator.net

BeanNameAutoProxyCreator

        例:如今有一個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

DefaultAdvisorAutoProxyCreator

        例:如今有一個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

        使用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 />
 -->

不一樣的加強對應的AspectJ註解

        @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

    對應引介加強

相關文章
相關標籤/搜索