Spring中的AOP配置

Spring中的配置文件,一般情況下命名爲applicationContext.xml,myeclipse會自動用spring編輯器進行編輯。


加載順序:

1、首先讀取配置配置文件,掃描所有的配置的bean對象,將其實例化。(因爲懶加載的原因,某些情況下如果客戶端沒有getbean的話不會爲該bean實例化)

2、然後讀取aop切面配置,爲目標類創建代理對象。

3、然後將所有注入信息的bean,屬性,代理對象注入到對應的位置。


涉及的一些命名 空間的整理:

基於xml的方式的命名空間:隨着使用功能的增多,命名空間也會越來越多,暫時只列出夠基本使用的。以後慢慢補充

xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">


在<bean id="" class="">中配置要交由spring來管理的javabean。spring會在啓動時自動創建該類的實例。

而在默認情況下,bean的模式是單例模式,在於struts2整合時不太合適,需要在bean中聲明屬性 將scope=“prototype”即可。

例:

         <bean id="testSalary" class="com.itheima.some.TestSalary" scope="prototype"></bean>

同其他的框架配置文件一樣id必須是唯一的。不 能重複。

而在某些情況下如果配置了name屬性,需要注意的是name屬性是可以重複的,並且後加載的name會將之前name相同的覆蓋掉。


在spring中如果要使用事務必須進行如下配置  <aop:config>標籤。在該標籤中需要:

           <aop:pointcut expression="execution(* com.itheima.some.*.*(..))"    id="perform"></aop:pointcut>

其中expression=execution是寫死的,後面的括號中的內容是按照匹配正則表達式的要求來掃描需要創建的代理對象。

這裏的匹配一定要書寫正確否則報的錯誤很難排查。



關於spring中的幾種通知:


前置通知:


1、在切面類中,沒有必要實現接口,但方法名稱要與<aop:before method=”checkSecurity” 中的checkSecurity一樣。

2checkSecurity方法中通過JoinPoint參數可以獲得目標類的目標方法名稱、參數值等信息。可以用來判斷調用的是哪個方法等。


例: <aop:aspect ref="logs">
            <aop:before method="startLogs" pointcut-ref="perform"></aop:before>
        </aop:aspect>


A. 後置通知

1、 沒有特殊說明的地方和前置通知是一樣的。

2、 在spring配置文件中

        

3、 在攔截器中的方法要和checkSecurity方法一樣,有兩個參數

              JoinPoint   point    可以獲得目標方法和參數值

              Object      val    這裏的名字要和returning=”val”中保持一致,指的是方法的返回值。

4、 returning=”val”時,通知裏可以有返回參數,這個參數只能決定通知裏能不能拿到方法的返回值,和客戶端沒有關係。

5、  在執行目標類的目標方法中遇到異常,則不執行後置通知。


B. 異常通知

1、 沒有特殊說明的地方和前置通知一樣

2、 在spring配置文件中

              

其中throwing指定了傳遞異常的參數名稱

3、 在異常通知中(攔截器)中,必須是checkSecurity方法。方法中有兩個參數

                JoinPoint    point   可以獲得方法的名稱、參數

               Throwable   ex    利用ex.getMessage()可以獲得異常信息

C. 最終通知

1、 沒有特殊說明,和前置通知的配置一樣。

2、 在spring配置文件裏:

                 

            

說明:在最終通知中不受異常的影響。也就是說不論目標方法執行的過程中是否拋出異常,最終通知都將執行。

D. 環繞通知

1、 沒有特殊說明和前置通知的配置保持一致。

2、 在spring文件中


                

3、 在環繞通知中,方法名稱爲checkSecurity。參數 類型 爲ProceedingJoinPoint。

ProceedingJoinPointproceed方法相當於invoke方法,調用目標類的目標方法。ProceedingJoinPoint繼承了JoinPoint

4、  能在方法執行的前後加入額外的代碼。例如進行權限的判斷。


在spring中的配置例子:

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
    <!--
        1、目標類
        2、切面
        3、進行AOP的配置
     -->
     <bean id="classDao" class="cn.itheima03.spring.aop.xml.ClassesDaoImpl"></bean>
     <bean id="myTransaction" class="cn.itheima03.spring.aop.xml.MyTransaction"></bean>
    
     <aop:config>
         <!--
             切入點表達式
                 expression切入點表達式
                 id  唯一標示
          -->
         <aop:pointcut expression="execution(* cn.itheima03.spring.aop.xml.ClassesDaoImpl.*(..))" id="perform"/>
         <!--
             ref引向切面
          -->
         <aop:aspect ref="myTransaction">
         
             <aop:before method="beginTransaction" pointcut-ref="perform"/>
         
             <!--
                 後置通知
                     returning 返回值
              -->
              <!--
             <aop:after-returning method="commit" pointcut-ref="perform" returning="val"/>
              -->
             <!--
                 最終通知
                        無論目標方法是否有異常,都執行
              -->
              <!--
             <aop:after method="finnalyMethod" pointcut-ref="perform"/>
              -->
             <!--
                 異常通知
                     throwing 獲取目標方法拋出的異常信息
              -->
             <aop:after-throwing method="throwingMethod" pointcut-ref="perform" throwing="ex"/>
             <!--
             <aop:around method="aroundMethod" pointcut-ref="perform"/>
              -->
         </aop:aspect>
     </aop:config>
</beans>




其中:切入點表達式的匹配方式示例:

          execution(public * *(..))  所有的公共方法

          execution(* set*(..))  以set開頭的任意方法

          execution(* com.xyz.service.AccountService.*(..))com.xyz.service.AccountService類裏的所有的方法

          execution(* com.xyz.service.*.*(..)) com.xyz.service包下的所有類的所有的方法

          execution(* com.xyz.service..*.*(..)) com.xyz.service包及子包中所有的類的所有的方法

          execution(* cn.itheima03.spring..*.*(String,*,Integer))

          execution(* cn.itheima03.*.*.spring.*..*.*(..))  參數..代表任意類型的任意參數,參數可以是0個
   

          cn.itheima03.a.b.spring.c.d.A.a()



springAOP的原理:
   1、當啓動spring容器的時候,
         <bean id="classDao" class="cn.itheima03.spring.aop.xml.ClassesDaoImpl"></bean>
         <bean id="myTransaction" class="cn.itheima03.spring.aop.xml.MyTransaction"></bean>
       把這兩個bean創建對象了
   2、解析aop:config
        1、解析切入點表達式,把表達式解除出來以後和spring中的bean進行匹配
        2、如果匹配成功,則爲該bean創建代理對象,在創建代理對象的過程中,把目標方法和通知結合在一起了
           如果匹配不成功,則直接報錯
        3、當客戶端調用context.getBean時,獲取到的
                                          1、如果該對象有代理對象,則返回代理對象
                                          2、如果該對象沒有代理對象,則返回對象本身


說明:
   spring容器內部會自動判斷:
              如果目標類實現了接口,則採用jdkproxy
              如果目標類沒有實現接口,則採用cglibproxy

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章