官术网_书友最值得收藏!

3.2 Spring AOP的設(shè)計與實現(xiàn)

3.2.1 JVM的動態(tài)代理特性

前面已經(jīng)介紹了橫切關(guān)注點的一些概念,以及它們在Spring中的具體設(shè)計和實現(xiàn)。具體來說,在Spring AOP實現(xiàn)中,使用的核心技術(shù)是動態(tài)代理,而這種動態(tài)代理實際上是JDK的一個特性(在JDK 1.3以上的版本里,實現(xiàn)了動態(tài)代理模式)。通過JDK的動態(tài)代理特性,可以為任意Java對象創(chuàng)建代理對象,對于具體使用來說,這個特性是通過Java Reflection API來完成的。在了解具體的Java Reflection之前,先簡要地復(fù)習(xí)一下Proxy模式,其靜態(tài)類圖如圖3-9所示。

圖3-9 Proxy模式的靜態(tài)類圖

在圖3-9中,可以看到有一個RealSubject,這個對象是目標(biāo)對象,而在代理模式的設(shè)計中,會設(shè)計一個接口和目標(biāo)對象一致的代理對象Proxy,它們都實現(xiàn)了接口Subject的request方法。在這種情況下,對目標(biāo)對象的request的調(diào)用,往往就被代理對象“渾水摸魚”給攔截了,通過這種攔截,為目標(biāo)對象的方法操作做了鋪墊,所以稱之為代理模式。了解了如圖3-10所示的調(diào)用關(guān)系,就可以清楚地了解這里的過程。

圖3-10 Proxy模式的調(diào)用關(guān)系

在Proxy的調(diào)用過程中,如果客戶(Client)調(diào)用Proxy的request方法,會在調(diào)用目標(biāo)對象的request方法的前后調(diào)用一系列的處理,而這一系列的處理相對于目標(biāo)對象來說是透明的,目標(biāo)對象對這些處理可以毫不知情,這就是Proxy模式。

通過前面的介紹可以知道,JDK中已經(jīng)實現(xiàn)了這個Proxy模式,在基于Java虛擬機(jī)設(shè)計應(yīng)用程序時,只需要直接使用這個特性就可以了。具體來說,可以在Java的reflection包中看到Proxy對象,這個對象生成后,所起的作用就類似于Proxy模式中的Proxy對象。在使用時,還需要為代理對象(Proxy)設(shè)計一個回調(diào)方法,這個回調(diào)方法起到的作用是,在其中加入了作為代理需要額外處理的動作,或者說,在這個方法中,所謂額外動作,可以參考Proxy模式中的preOperation()和postOperation()方法。這個回調(diào)方法,如果在JDK中實現(xiàn),需要實現(xiàn)下面所示的InvocationHandler接口:

        public interface InvocationHandler {
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
        }

在這個接口方法中,只聲明了一個invoke方法,這個invoke方法的第一個參數(shù)是代理對象實例,第二個參數(shù)是Method方法對象,代表的是當(dāng)前Proxy被調(diào)用的方法,最后一個參數(shù)是被調(diào)用的方法中的參數(shù)。通過這些信息,在invoke方法實現(xiàn)中,已經(jīng)可以了解Proxy對象的調(diào)用背景了。至于怎樣讓invoke方法和Proxy掛上鉤,熟悉Proxy用法的讀者都知道,只要在實現(xiàn)通過調(diào)用Proxy.newIntance方法生成具體Proxy對象時把InvocationHandler設(shè)置到參數(shù)里面就可以了,剩下的由Java虛擬機(jī)來完成。

3.2.2 Spring AOP的設(shè)計分析

大家都知道,AOP模塊是Spring的核心模塊,雖然在Java社區(qū)里AspectJ是最完整的AOP框架,但Spring AOP也提供了另外一種實現(xiàn),這種實現(xiàn)并不是AspectJ的競爭者,相反,Spring AOP還將AspectJ集成了進(jìn)來,為IoC容器和Spring應(yīng)用開發(fā)提供了一個一致性的AOP解決方案。

Spring AOP的核心技術(shù)是上一小節(jié)介紹的JDK動態(tài)代理技術(shù)。以動態(tài)代理技術(shù)為基礎(chǔ),設(shè)計出了一系列AOP的橫切實現(xiàn),比如前置通知、返回通知、異常通知等。同時,Spring AOP還提供了一系列的Pointcut來匹配切入點,可以使用現(xiàn)有的切入點來設(shè)計橫切面,也可以擴(kuò)展相關(guān)的Pointcut方法來實現(xiàn)切入需求。

在Spring AOP中,雖然對于AOP的使用者來說,只需要配置相關(guān)的Bean定義即可,但仔細(xì)分析Spring AOP的內(nèi)部設(shè)計可以看到,為了讓AOP起作用,需要完成一系列過程,比如,需要為目標(biāo)對象建立代理對象,這個代理對象可以通過使用JDK的Proxy來完成,也可以通過第三方的類生成器CGLIB來完成。然后,還需要啟動代理對象的攔截器來完成各種橫切面的織入,這一系列的織入設(shè)計是通過一系列Adapter來實現(xiàn)的。通過一系列Adapter的設(shè)計,可以把AOP的橫切面設(shè)計和Proxy模式有機(jī)地結(jié)合起來,從而實現(xiàn)在AOP中定義好的各種織入方式。具體的設(shè)計實現(xiàn)可以參考后面的內(nèi)容,這里只是簡要介紹一下。

3.2.3 Spring AOP的應(yīng)用場景

Spring AOP為IoC的使用提供了更多的便利,一方面,應(yīng)用可以直接使用AOP的功能,設(shè)計應(yīng)用的橫切關(guān)注點,把跨越應(yīng)用程序多個模塊的功能抽象出來,并通過簡單的AOP的使用,靈活地編制到模塊中,比如可以通過AOP實現(xiàn)應(yīng)用程序中的日志功能。另一方面,在Spring內(nèi)部,一些支持模塊也是通過Spring AOP來實現(xiàn)的,比如后面將要詳細(xì)介紹的事務(wù)處理。從這兩個角度就已經(jīng)可以看到Spring AOP的核心地位了。下面以ProxyFactoryBean的實現(xiàn)為例,和大家一起來了解Spring AOP的具體設(shè)計和實現(xiàn)。

主站蜘蛛池模板: 竹溪县| 曲阳县| 榆林市| 西青区| 安龙县| 梁山县| 乌拉特中旗| 灵台县| 崇阳县| 色达县| 扎鲁特旗| 瑞金市| 桐柏县| 赤水市| 浪卡子县| 金塔县| 嘉黎县| 温宿县| 易门县| 高青县| 清新县| 咸丰县| 修武县| 兴国县| 锦州市| 肥乡县| 安新县| 五华县| 太仆寺旗| 和硕县| 孝昌县| 沂南县| 芦溪县| 宁河县| 洪洞县| 布尔津县| 黔江区| 天祝| 云浮市| 西城区| 常宁市|