Spring AOP 學習筆記

1、通過xml配置aop

1.1 新建一個aop的切面類

@Aspect
public class MkztAspect {
    private static final Logger log = LogManager.getLogger(MkztAspect.class);

    public void mkztAround(JoinPoint point) {
        System.out.print("開始執行模塊狀態切面.");
        MethodInvocationProceedingJoinPoint b = (MethodInvocationProceedingJoinPoint) point;
        Object obj = b.getTarget();
        Object[] args = point.getArgs();
        String pointStr = b.toString();
        String func = pointStr.substring(pointStr.indexOf("(") + 1, pointStr
                .indexOf(")"));
        try {
            if ("rwFxMkzt".equals(func)) {
                List<Map> mkztList = MkjdgzUtils.getMkzt(args);
                if (mkztList != null && mkztList.size() > 0) {
                    MkjdgzUtils.setMkzt(mkztList);
                }
            }
            if ("setModuleMkztBaseOnCslb".equals(func)) {
                String lc = StringUtil.toString(args[0]);
                List<Map> moduleids = (List<Map>) args[1];
                MkjdgzUtils.setModuleMkztBaseOnCslb(lc, moduleids);
            }
            if ("updateMkztBaseOnCslxWhenCstg".equals(func)) {
                String cslx = StringUtil.toString(args[0]);
                String moduleId = StringUtil.toString(args[1]);
                MkjdgzUtils.updateMkztBaseOnCslxWhenCstg(cslx, moduleId);
            }
            if ("updateMkztBaseOnCslxWhenCsbtg".equals(func)) {
                String cslx = StringUtil.toString(args[0]);
                String moduleId = StringUtil.toString(args[1]);
                MkjdgzUtils.updateMkztBaseOnCslxWhenCsbtg(cslx, moduleId);
            }
            if ("sbUpdateMkzt".equals(func)) {
                String ddid = StringUtil.toString(args[0]);
                String xmid = StringUtil.toString(args[1]);
                MkjdgzUtils.sbUpdateMkztSetHistory(ddid, xmid);
            }
        } catch (Throwable e) {
            log.error("模塊狀態切面類執行方法異常.");
            e.printStackTrace();
        }
        try {
            b.proceed();//執行代理的方法
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }
}
<?xml version="1.0" encoding="UTF-8"?>

<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"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd            http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd"
    default-autowire="byName" default-lazy-init="true">
    <!-- 支持 @AspectJ 標記-->
    <aop:aspectj-autoproxy />
    <!-- 以AspectJ方式 定義 AOP -->

    <!-- 測試模塊狀態aop -->
    <bean id="mkztAspect" class="com.hnisi.scpt.gzl.mkjdgz.aop.MkztAspect">
    </bean>


    <aop:config proxy-target-class="true">
        <!-- 要監控的路徑 多個以||分隔開-->
        <aop:pointcut id="mkztUpdate"
            expression="execution(* com.hnisi.scpt.gzl.mkjdgz.service.MkztService.*(..))" />

        <aop:aspect id="aopAspect" ref="mkztAspect">
            <!--模塊狀態更新環繞通知 -->
            <aop:around pointcut-ref="mkztUpdate" method="mkztAround" />

        </aop:aspect>
    </aop:config>
</beans>

新建一個applicationContext-aop.xml文件,配置的內容寫在aop:config標籤下,這裏只配置了一個環繞通知 aop:around

1,首先把所有原始對象的bean配置好
2,然後把所有切面bean配置好,配置切面的bean 的id與切面類的映射。
3,配置aop
(1)配置切點:關係到哪些方法執行時會調用相關切面的通知。切點先配置好,一會兒留着引用。
(2)配置每一個切面:
a。配置切面bean的id與order切面優先級的映射,以及切面內的各個通知。
b。配置各個切面內部的通知與切點的映射,切點以引用方式給出。
面向切面編程(AOP)通過提供另外一種思考程序結構的途經來彌補面向對象編程(OOP)的不足。在OOP中模塊化的關鍵單元是類(classes),而在AOP中模塊化的單元則是切面。切面能對關注點進行模塊化,例如橫切多個類型和對象的事務管理。(在AOP術語中通常稱作橫切(crosscutting)關注點。)
AOP框架是Spring的一個重要組成部分。但是Spring IoC容器並不依賴於AOP,這意味着你有權利選擇是否使用AOP,AOP做爲Spring IoC容器的一個補充,使它成爲一個強大的中間件解決方案。
Spring 2.0的AOP
Spring 2.0允許用戶選擇使用更簡單、更強大的基於模式或@AspectJ註解的方式來自定義切面。這兩種風格都支持所有類型的通知(advice)和AspectJ的切入點語言,雖然實際上仍然使用Spring AOP進行織入(Weaving)。
本章主要討論Spring 2.0對基於模式和基於@AspectJ的AOP支持。Spring 2.0完全保留了對Spring 1.2的向下兼容,下一章將討論Spring 1.2 API所提供的底層的AOP支持。
AOP在Spring Framework中的作用
提供聲明式企業服務,特別是爲了替代EJB聲明式服務。最重要的服務是聲明性事務管理。
允許用戶實現自定義切面,用AOP來完善OOP的使用。
如果你只打算使用通用的聲明式服務或者封裝好的聲明式中間件服務,例如緩衝池(pooling),那麼你不必與Spring AOP直接打交道,並且本章的大部分內容可以跳過了。
6.1.1. AOP概念
首先讓我們從一些重要的AOP概念和術語開始。這些術語不是Spring特有的。不過AOP術語並不是特別的直觀,如果Spring使用自己的術語,將會變得更加令人困惑。
切面(Aspect):一個關注點的模塊化,這個關注點可能會橫切多個對象。事務管理是J2EE應用中一個關於橫切關注點的很好的例子。在Spring AOP中,切面可以使用基於模式)或者基於@Aspect註解的方式來實現。
連接點(Joinpoint):在程序執行過程中某個特定的點,比如某方法調用的時候或者處理異常的時候。在Spring AOP中,一個連接點總是表示一個方法的執行。
通知(Advice):在切面的某個特定的連接點上執行的動作。其中包括了“around”、“before”和“after”等不同類型的通知(通知的類型將在後面部分進行討論)。許多AOP框架(包括Spring)都是以攔截器做通知模型,並維護一個以連接點爲中心的攔截器鏈。
切入點(Pointcut):匹配連接點的斷言。通知和一個切入點表達式關聯,並在滿足這個切入點的連接點上運行(例如,當執行某個特定名稱的方法時)。切入點表達式如何和連接點匹配是AOP的核心:Spring缺省使用AspectJ切入點語法。
引入(Introduction):用來給一個類型聲明額外的方法或屬性(也被稱爲連接類型聲明(inter-type declaration))。Spring允許引入新的接口(以及一個對應的實現)到任何被代理的對象。例如,你可以使用引入來使一個bean實現IsModified接口,以便簡化緩存機制。
目標對象(Target Object): 被一個或者多個切面所通知的對象。也被稱做被通知(advised)對象。 既然Spring AOP是通過運行時代理實現的,這個對象永遠是一個被代理(proxied)對象。
AOP代理(AOP Proxy):AOP框架創建的對象,用來實現切面契約(例如通知方法執行等等)。在Spring中,AOP代理可以是JDK動態代理或者CGLIB代理。
織入(Weaving):把切面連接到其它的應用程序類型或者對象上,並創建一個被通知的對象。這些可以在編譯時(例如使用AspectJ編譯器),類加載時和運行時完成。Spring和其他純Java AOP框架一樣,在運行時完成織入。
通知類型:
前置通知(Before advice):在某連接點之前執行的通知,但這個通知不能阻止連接點之前的執行流程(除非它拋出一個異常)。
後置通知(After returning advice):在某連接點正常完成後執行的通知:例如,一個方法沒有拋出任何異常,正常返回。
異常通知(After throwing advice):在方法拋出異常退出時執行的通知。
最終通知(After (finally) advice):當某連接點退出的時候執行的通知(不論是正常返回還是異常退出)。
環繞通知(Around Advice):包圍一個連接點的通知,如方法調用。這是最強大的一種通知類型。環繞通知可以在方法調用前後完成自定義的行爲。它也會選擇是否繼續執行連接點或直接返回它自己的返回值或拋出異常來結束執行。
環繞通知是最常用的通知類型。和AspectJ一樣,Spring提供所有類型的通知,我們推薦你使用儘可能簡單的通知類型來實現需要的功能。例如,如果你只是需要一個方法的返回值來更新緩存,最好使用後置通知而不是環繞通知,儘管環繞通知也能完成同樣的事情。用最合適的通知類型可以使得編程模型變得簡單,並且能夠避免很多潛在的錯誤。比如,你不需要在JoinPoint上調用用於環繞通知的proceed()方法,就不會有調用的問題。
在Spring 2.0中,所有的通知參數都是靜態類型,因此你可以使用合適的類型(例如一個方法執行後的返回值類型)作爲通知的參數而不是使用Object數組。
通過切入點匹配連接點的概念是AOP的關鍵,這使得AOP不同於其它僅僅提供攔截功能的舊技術。 切入點使得通知可以獨立對應到面向對象的層次結構中。例如,一個提供聲明式事務管理 的環繞通知可以被應用到一組橫跨多個對象的方法上(例如服務層的所有業務操作)。

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