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

3.3 建立AopProxy代理對象

3.3.1 設(shè)計(jì)原理

在Spring的AOP模塊中,一個(gè)主要的部分是代理對象的生成,而對于Spring應(yīng)用,可以看到,是通過配置和調(diào)用Spring的ProxyFactoryBean來完成這個(gè)任務(wù)的。在ProxyFactoryBean中,封裝了主要代理對象的生成過程。在這個(gè)生成過程中,可以使用JDK的Proxy和CGLIB兩種生成方式。

以ProxyFactory的設(shè)計(jì)為中心,可以看到相關(guān)的類繼承關(guān)系如圖3-11所示。

圖3-11 類繼承關(guān)系

在這個(gè)類繼承關(guān)系中,可以看到完成AOP應(yīng)用的類,比如AspectJProxyFactory、ProxyFactory和ProxyFactoryBean,它們都在同一個(gè)類的繼承體系下,都是ProxyConfig、AdvisedSupport和ProxyCreatorSupport的子類。作為共同基類,可以將ProxyConfig看成是一個(gè)數(shù)據(jù)基類,這個(gè)數(shù)據(jù)基類為ProxyFactoryBean這樣的子類提供了配置屬性;在另一個(gè)基類AdvisedSupport的實(shí)現(xiàn)中,封裝了AOP對通知和通知器的相關(guān)操作,這些操作對于不同的AOP的代理對象的生成都是一樣的,但對于具體的AOP代理對象的創(chuàng)建,AdvisedSupport把它交給它的子類們?nèi)ネ瓿桑粚τ赑roxyCreatorSupport,可以將它看成是其子類創(chuàng)建AOP代理對象的一個(gè)輔助類。通過繼承以上提到的基類的功能實(shí)現(xiàn),具體的AOP代理對象的生成,根據(jù)不同的需要,分別由ProxyFactoryBean、AspectJProxyFactory和ProxyFactory來完成。對于需要使用AspectJ的AOP應(yīng)用,AspectJProxyFactory起到集成Spring和AspectJ的作用;對于使用Spring AOP的應(yīng)用,ProxyFactoryBean和ProxyFactoy都提供了AOP功能的封裝,只是使用ProxyFactoryBean,可以在IoC容器中完成聲明式配置,而使用ProxyFactory,則需要編程式地使用Spring AOP的功能;對于它們是如何封裝實(shí)現(xiàn)AOP功能的,會在本章小結(jié)中給出詳細(xì)的分析,在這里,通過這些類層次關(guān)系的介紹,先給讀者留下一個(gè)大致的印象。Proxy-FactoryBean相關(guān)的類層次關(guān)系如圖3-12所示。

圖3-12 ProxyFactoryBean相關(guān)的類層次關(guān)系

關(guān)于AOP的實(shí)現(xiàn)過程,在了解其設(shè)計(jì)原理之后,下面詳細(xì)分析從配置ProxyFactoryBean開始到具體的代理對象生成。

3.3.2 配置ProxyFactoryBean

從這部分開始,進(jìn)入到Spring AOP的實(shí)現(xiàn)部分,在分析Spring AOP的實(shí)現(xiàn)原理中,主要以ProxyFactoryBean的實(shí)現(xiàn)作為例子和實(shí)現(xiàn)的基本線索進(jìn)行分析。這是因?yàn)镻roxyFactoryBean是在Spring IoC環(huán)境中創(chuàng)建AOP應(yīng)用的底層方法,也是最靈活的方法,Spring通過它完成了對AOP使用的封裝。以ProxyFactoryBean的實(shí)現(xiàn)為入口,逐層深入,是一條幫助我們快速理解Spring AOP實(shí)現(xiàn)的學(xué)習(xí)路徑。

在了解ProxyFactoryBean的實(shí)現(xiàn)之前,先簡要介紹一下ProxyFactoryBean的配置和使用,在基于XML配置Spring的Bean時(shí),往往需要一系列的配置步驟來使用ProxyFactoryBean和AOP。

1)定義使用的通知器Advisor,這個(gè)通知器應(yīng)該作為一個(gè)Bean來定義。很重要的一點(diǎn)是,這個(gè)通知器的實(shí)現(xiàn)定義了需要對目標(biāo)對象進(jìn)行增強(qiáng)的切面行為,也就是Advice通知。

2)定義ProxyFactoryBean,把它作為另一個(gè)Bean來定義,它是封裝AOP功能的主要類。在配置ProxyFactoryBean時(shí),需要設(shè)定與AOP實(shí)現(xiàn)相關(guān)的重要屬性,比如proxyInterface、interceptorNames和target等。從屬性名稱可以看出,interceptorNames屬性的值往往設(shè)置為需要定義的通知器,因?yàn)檫@些通知器在ProxyFactoryBean的AOP配置下,是通過使用代理對象的攔截器機(jī)制起作用的。所以,這里依然沿用了攔截器這個(gè)名字,也算是舊瓶裝新酒吧。

3)定義target屬性,作為target屬性注入的Bean,是需要用AOP通知器中的切面應(yīng)用來增強(qiáng)的對象,也就是前面提到的base對象。

有了這些配置,就可以使用ProxyFactoryBean完成AOP的基本功能了。關(guān)于配置的例子,如代碼清單3-10所示。與前面提到的配置步驟相對應(yīng),可以看到,除定義了ProxyFactoryBean的AOP封裝外,還定義了一個(gè)Advisor,名為testAdvisor。作為ProxyFactory配置的一部分,還需要配置攔截的方法調(diào)用接口和目標(biāo)對象。這些基本的配置,是使用ProxyFactoryBean實(shí)現(xiàn)AOP功能的重要組成,其實(shí)現(xiàn)和作用機(jī)制也是后面重點(diǎn)分析的內(nèi)容。

代碼清單3-10 配置ProxyFactoryBean

        <bean id="testAdvisor" class="com.abc.TestAdvisor"/>
        <bean id="testAOP" class="org.springframework.aop.ProxyFactoryBean>
        <property name="proxyInterfaces"><value>com.test.AbcInterface"</value></property>
        <property name="target">
            <bean class="com.abc.TestTarget"/>
        </property>
        <property name="interceptorNames">
            <list><value> testAdvisor</value></list>
        </property>
        </bean>

掌握這些配置后,就可以具體看一看這些AOP是如何實(shí)現(xiàn)的,也就是說,切面應(yīng)用是怎樣通過ProxyFactoryBean對target對象起作用的,下面我們會詳細(xì)地分析這個(gè)部分。

3.3.3 ProxyFactoryBean生成AopProxy代理對象

在Spring AOP的使用中,我們已經(jīng)了解到,可以通過ProxyFactoryBean來配置目標(biāo)對象和切面行為。這個(gè)ProxyFactoryBean是一個(gè)FactoryBean,對FactoryBean這種Spring應(yīng)用中經(jīng)常出現(xiàn)的Bean的工作形式,大家一定不會感到陌生, 對于FactoryBean的工作原理,已經(jīng)在結(jié)合IoC容器的實(shí)現(xiàn)原理分析中做過闡述。在ProxyFactoryBean中,通過interceptorNames屬性來配置已經(jīng)定義好的通知器Advisor。雖然名字為interceptorNames,但實(shí)際上卻是供AOP應(yīng)用配置通知器的地方。在ProxyFactoryBean中,需要為target目標(biāo)對象生成Proxy代理對象,從而為AOP橫切面的編織做好準(zhǔn)備工作。這些具體的代理對象生成工作,在以后的實(shí)現(xiàn)原理分析中,我們可以看到是通過JDK的Proxy或CGLIB來完成的。具體的AopProxy生成過程如圖3-13所示。

圖3-13 AopProxy的生成過程

ProxyFactoryBean的AOP實(shí)現(xiàn)需要依賴JDK或者CGLIB提供的Proxy特性。從FactoryBean中獲取對象,是以getObject()方法作為入口完成的;ProxyFactoryBean實(shí)現(xiàn)中的getObject方法,是FactoryBean需要實(shí)現(xiàn)的接口。對ProxyFactoryBean來說,把需要對target目標(biāo)對象增加的增強(qiáng)處理,都通過getObject方法進(jìn)行封裝了,這些增強(qiáng)處理是為AOP功能的實(shí)現(xiàn)提供服務(wù)的。getObject的實(shí)現(xiàn)如代碼清單3-11所示。getObject方法首先對通知器鏈進(jìn)行初始化,通知器鏈封裝了一系列的攔截器,這些攔截器都要從配置中讀取,然后為代理對象的生成做好準(zhǔn)備。在生成代理對象時(shí),因?yàn)镾pring中有singleton類型和prototype類型這兩種不同的Bean,所以要對代理對象的生成做一個(gè)區(qū)分。

代碼清單3-11 ProxyFactoryBean的getObject

        public Object getObject() throws BeansException {
            //這里初始化通知器鏈
            initializeAdvisorChain();
            //這里對singletonprototype的類型進(jìn)行區(qū)分,生成對應(yīng)的proxy
            if (isSingleton()) {
                return getSingletonInstance();
            }
            else {
                if (this.targetName == null) {
                    logger.warn("Using non-singleton proxies with singleton targets is
                    often undesirable. " +"Enable prototype proxies by setting the
                    'targetName' property.");
                }
                return newPrototypeInstance();
            }
        }

為Proxy代理對象配置Advisor鏈?zhǔn)窃趇nitializeAdvisorChain方法中完成的,如代碼清單3-12所示。這個(gè)初始化過程有一個(gè)標(biāo)志位advisorChainInitialized,這個(gè)標(biāo)志用來表示通知器鏈?zhǔn)欠褚呀?jīng)初始化。如果已經(jīng)初始化,那么這里就不會再初始化,而是直接返回。也就是說,這個(gè)初始化的工作發(fā)生在應(yīng)用第一次通過ProxyFactoryBean去獲取代理對象的時(shí)候。在完成這個(gè)初始化之后,接著會讀取配置中出現(xiàn)的所有通知器,這個(gè)取得通知器的過程也比較簡單,把通知器的名字交給容器的getBean方法就可以了,這是通過對IoC容器實(shí)現(xiàn)的一個(gè)回調(diào)來完成的。然后把從IoC容器中取得的通知器加入攔截器鏈中,這個(gè)動作是由addAdvisorOnChainCreation方法來實(shí)現(xiàn)的。

代碼清單3-12 對Advisor配置鏈的初始化

        private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException {
            if (this.advisorChainInitialized) {
                return;
            }
            if (!ObjectUtils.isEmpty(this.interceptorNames)) {
                if (this.beanFactory == null) {
                    throw new IllegalStateException("No BeanFactory available anymore
                    (probably due to serialization) " +
                    "- cannot resolve interceptor names " + Arrays.asList
                    (this.interceptorNames));
                }
                    if (this.interceptorNames[this.interceptorNames.length -1].
                    endsWith(GLOBAL_SUFFIX) &&this.targetName == null &&
                    this.targetSource == EMPTY_TARGET_SOURCE) {
                    throw new AopConfigException("Target required after globals");
                }
                // 這里是添加Advisor鏈的調(diào)用,是通過interceptorNames屬性進(jìn)行配置的
                for (String name : this.interceptorNames) {
                    if (logger.isTraceEnabled()) {
                          logger.trace("Configuring advisor or advice '" + name + "'");
                    }
                    if (name.endsWith(GLOBAL_SUFFIX)) {
                          if (!(this.beanFactory instanceof ListableBeanFactory)) {
                              throw new AopConfigException(
                                      "Can only use global advisors or interceptors with a
                                      ListableBeanFactory");
                            }
                            addGlobalAdvisor((ListableBeanFactory) this.beanFactory,
                                    name.substring(0, name.length() - GLOBAL_SUFFIX.length()));
                    }
                    else {
                            /* 如果程序在這里被調(diào)用,那么需要加入命名的攔截器advice,并且需要檢查這
                              個(gè)Beansingleton還是prototype類型*/
                            Object advice;
                            //如果是singleton類型Bean
                            if (this.singleton || this.beanFactory.isSingleton(name)) {
                            //加入advice或者advisor
                                advice = this.beanFactory.getBean(name);
                            }
                            else {
                                //prototype類型Bean的處理
                                advice = new PrototypePlaceholderAdvisor(name);
                            }
                            addAdvisorOnChainCreation(advice, name);
                    }
                }
            }
            this.advisorChainInitialized = true;
        }

生成singleton的代理對象在getSingletonInstance()的代碼中完成,這個(gè)方法是ProxyFactoryBean生成AopProxy代理對象的調(diào)用入口。代理對象會封裝對target目標(biāo)對象的調(diào)用,也就是說針對target對象的方法調(diào)用行為會被這里生成的代理對象所攔截。具體的生成過程是,首先讀取ProxyFactoryBean中的配置,為生成代理對象做好必要的準(zhǔn)備,比如設(shè)置代理的方法調(diào)用接口等。Spring通過AopProxy類來具體生成代理對象。對于getSingletonInstance()方法中代理對象的生成過程,如代碼清單3-13所示。

代碼清單3-13 生成單件代理對象

        private synchronized Object getSingletonInstance() {
            if (this.singletonInstance == null) {
                this.targetSource = freshTargetSource();
                if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 &&
                !isProxyTargetClass()) {
                    //根據(jù)AOP框架來判斷需要代理的接口
                    Class targetClass = getTargetClass();
                    if (targetClass == null) {
                          throw new FactoryBeanNotInitializedException("Cannot determine
                          target class for proxy");
                    }
        // 這里設(shè)置代理對象的接口
        setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader));
                }
                super.setFrozen(this.freezeProxy);
                // 注意這里的方法會使用ProxyFactory來生成需要的Proxy
                this.singletonInstance = getProxy(createAopProxy());
            }
            return this.singletonInstance;
        }
        //通過createAopProxy返回的AopProxy來得到代理對象
        protected Object getProxy(AopProxy aopProxy) {
            return aopProxy.getProxy(this.proxyClassLoader);
        }

這里出現(xiàn)了AopProxy類型的對象,Spring利用這個(gè)AopProxy接口類把AOP代理對象的實(shí)現(xiàn)與框架的其他部分有效地分離開來。AopProxy是一個(gè)接口,它由兩個(gè)子類實(shí)現(xiàn),一個(gè)是Cglib2AopProxy,另一個(gè)是JdkDynamicProxy。顧名思義,對這兩個(gè)AopProxy接口的子類的實(shí)現(xiàn),Spring分別通過CGLIB和JDK來生成需要的Proxy代理對象。

具體的代理對象的生成,是在ProxyFactoryBean的基類AdvisedSupport的實(shí)現(xiàn)中借助AopProxyFactory完成的,這個(gè)代理對象要么從JDK中生成,要么借助CGLIB獲得。因?yàn)镻roxyFactoryBean本身就是AdvisedSupport的子類,所以在ProxyFactoryBean中獲得AopProxy是很方便的,可以在ProxyCreatorSupport中看到,具體的AopProxy是通過AopProxyFactory來生成的。至于需要生成什么樣的代理對象,所有信息都封裝在AdvisedSupport里,這個(gè)對象也是生成AopProxy的方法的輸入?yún)?shù),這里設(shè)置為this本身,因?yàn)镻roxyCreatorSupport本身就是AdvisedSupport的子類。在ProxyCreatorSupport中生成代理對象的入口實(shí)現(xiàn),如代碼清單3-14所示。

代碼清單3-14 ProxyCreatorSupport生成AopProxy對象

        protected final synchronized AopProxy createAopProxy() {
            if (!this.active) {
                activate();
            }
            //通過AopProxyFactory取得AopProxy,這個(gè)AopProxyFactory是在初始化函數(shù)中
            //定義的,使用的是DefaultAopProxyFactory
            return getAopProxyFactory().createAopProxy(this);
        }

這里使用了AopProxyFactory來創(chuàng)建AopProxy,AopProxyFactory使用的是DefaultAopProxyFactory。這個(gè)被使用的AopProxyFactory,作為AopProxy的創(chuàng)建工廠對象,是在ProxyFactoryBean的基類ProxyCreatorSupport中被創(chuàng)建的。在創(chuàng)建AopProxyFactory時(shí),它被設(shè)置為DefaultAopProxyFactory,很顯然,Spring給出了這個(gè)默認(rèn)的AopProxyFactory工廠的實(shí)現(xiàn)。有了這個(gè)AopProxyFactory對象以后,問題就轉(zhuǎn)換為在DefaultAopProxyFactory中,AopProxy是怎樣生成的了。

關(guān)于AopProxy代理對象的生成,需要考慮使用哪種生成方式,如果目標(biāo)對象是接口類,那么適合使用JDK來生成代理對象,否則Spring會使用CGLIB來生成目標(biāo)對象的代理對象。為了滿足不同的代理對象生成的要求,DefaultAopProxyFactory作為AopProxy對象的生產(chǎn)工廠,可以根據(jù)不同的需要生成這兩種AopProxy對象。對于AopProxy對象的生產(chǎn)過程,在DefaultAopProxyFactory創(chuàng)建AopProxy的過程中可以清楚地看到,但這是一個(gè)比較高層次的AopProxy代理對象的生成過程,如代碼清單3-15所示。所謂高層次,是指在DefaultAopProxyFactory創(chuàng)建AopProxy的過程中,對不同的AopProxy代理對象的生成所涉及的生成策略和場景做了相應(yīng)的設(shè)計(jì),但是對于具體的AopProxy代理對象的生成,最終并沒有由DefaultAopProxyFactory來完成,比如對JDK和CGLIB這些具體的技術(shù)的使用,對具體的實(shí)現(xiàn)層次的代理對象的生成,是由Spring封裝的JdkDynamicAopProxy和CglibProxyFactory類來完成的。

代碼清單3-15 在DefaultAopProxyFactory中創(chuàng)建AopProxy

        public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
            if (config.isOptimize() || config.isProxyTargetClass() ||hasNoUserSupplied-
                ProxyInterfaces(config)) {
                Class targetClass = config.getTargetClass();
                if (targetClass == null) {
                    throw new AopConfigException("TargetSource cannot determine target class: " +
                    "Either an interface or a target is required for proxy creation.");
                }//如果targetClass是接口類,使用JDK來生成Proxy
                if (targetClass.isInterface()) {
                    return new JdkDynamicAopProxy(config);
                }
                if (!cglibAvailable) {
                    throw new AopConfigException(
                            "Cannot proxy target class because CGLIB2 is not available. " +
                            "Add CGLIB to the class path or specify proxy interfaces.");
                } //如果不是接口類要生成Proxy,那么使用CGLIB來生成
                return CglibProxyFactory.createCglibProxy(config);
            }
            else {
                return new JdkDynamicAopProxy(config);
            }
        }

在AopProxy代理對象的生成過程中,首先要從AdvisedSupport對象中取得配置的目標(biāo)對象,這個(gè)目標(biāo)對象是實(shí)現(xiàn)AOP功能所必需的,道理很簡單,AOP完成的是切面應(yīng)用對目標(biāo)對象的增強(qiáng),皮之不存,毛將焉附,這個(gè)目標(biāo)對象可以看做是“皮”,而AOP切面增強(qiáng)就是依附于這塊皮上的“毛”。如果這里沒有配置目標(biāo)對象,會直接拋出異常,提醒AOP應(yīng)用, 需要提供正確的目標(biāo)對象的配置。在對目標(biāo)對象配置的檢查完成以后,需要根據(jù)配置的情況來決定使用什么方式來創(chuàng)建AopProxy代理對象,一般而言,默認(rèn)的方式是使用JDK來產(chǎn)生AopProxy代理對象,但是如果遇到配置的目標(biāo)對象不是接口類的實(shí)現(xiàn),會使用CGLIB來產(chǎn)生AopProxy代理對象;在使用CGLIB來產(chǎn)生AopProxy代理對象時(shí),因?yàn)镃GLIB是一個(gè)第三方的類庫,本身不在JDK的基本類庫中,所以需要在CLASSPATH路徑中進(jìn)行正確的配置,以便能夠加載和使用。在Spring中,使用JDK和CGLIB來生成AopProxy代理對象的工作,是由JdkDynamicAopProxy和CglibProxyFactory來完成的。詳細(xì)的代理對象的生成過程會在下面的小節(jié)進(jìn)行詳細(xì)的分析。

3.3.4 JDK生成AopProxy代理對象

前面介紹的ProxyFactoryBean在AopProxy代理對象和IoC容器配置之間起到了橋梁的作用,這個(gè)橋梁作用體現(xiàn)在它為代理對象的最終生成做好了準(zhǔn)備。AopProxy代理對象可以由JDK或CGLIB來生成,而JdkDynamicAopProxy和Cglib2AopProxy實(shí)現(xiàn)的都是通過AopProxy接口,它們的層次關(guān)系如圖3-14所示。從源代碼實(shí)現(xiàn)中,也可以看到相對應(yīng)的接口實(shí)現(xiàn)關(guān)系。

圖3-14 AopProxy接口的層次關(guān)系

在這里可以看到使用兩種代理對象的實(shí)現(xiàn)方式,一種是使用CGLIB,另一種使用JDK自己的Proxy。具體怎樣生成代理對象,通過這兩個(gè)類的源代碼實(shí)現(xiàn)就可以了解,在AopProxy的接口下,設(shè)計(jì)了Cglib2AopProxy和JdkDynamicAopProxy兩種Proxy代理對象的實(shí)現(xiàn),而AopProxy的接口設(shè)計(jì)也很簡單,就是獲得Proxy代理對象。獲得Proxy代理對象的方式有兩種,一種方式是需要指定ClassLoader,另一種方式則不需要指定,如圖3-15所示。

圖3-15 AopProxy接口

先看看在AopProxy接口實(shí)現(xiàn)中,JdkDynamicAopProxy是怎樣完成AopProxy代理對象生成工作的,這個(gè)代理對象的生成過程如代碼清單3-16所示。在JdkDynamicAopProxy中,使用了JDK的Proxy類來生成代理對象,在生成Proxy對象之前,首先需要從advised對象中取得代理對象的代理接口配置,然后調(diào)用Proxy的newProxyInstance方法,最終得到對應(yīng)的Proxy代理對象。在生成代理對象時(shí),需要指明三個(gè)參數(shù),一個(gè)是類裝載器,一個(gè)是代理接口,另外一個(gè)就是Proxy回調(diào)方法所在的對象,這個(gè)對象需要實(shí)現(xiàn)InvocationHandler接口。這個(gè)InvocationHandler接口定義了invoke方法,提供代理對象的回調(diào)入口。對于JdkDynamicAopProxy,它本身實(shí)現(xiàn)了InvocationHandler接口和invoke方法,這個(gè)invoke方法是Proxy代理對象的回調(diào)方法,所以可以使用this來把JdkDynamicAopProxy指派給Proxy對象,也就是說JdkDynamicAopProxy對象本身,在Proxy代理的接口方法被調(diào)用時(shí),會觸發(fā)invoke方法的回調(diào),這個(gè)回調(diào)方法完成了AOP編織實(shí)現(xiàn)的封裝。在這里先重點(diǎn)關(guān)注AopProxy代理對象的生成,Proxy代理對象的invoke實(shí)現(xiàn),將是詳細(xì)分析AOP實(shí)現(xiàn)原理的重要部分。

代碼清單3-16 JdkDynamicAopProxy生成Proxy代理對象

        public Object getProxy(ClassLoader classLoader) {
            if (logger.isDebugEnabled()) {
                logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.
                getTargetSource());
            }
            Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces
            (this.advised);
            findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
            //這是調(diào)用JDK生成Proxy的地方
            return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
        }

3.3.5 CGLIB生成AopProxy代理對象

在AopProxy接口實(shí)現(xiàn)中,可以看到使用CGLIB來生成Proxy代理對象,這個(gè)Proxy代理對象的生成可以在Cglib2AopProxy的代碼實(shí)現(xiàn)中看到,同樣是在AopProxy的接口方法getProxy的實(shí)現(xiàn)中完成的,如代碼清單3-17所示。

代碼清單3-17 Cglib2AopProxy生成AopProxy代理對象

        public Object getProxy(ClassLoader classLoader) {
            if (logger.isDebugEnabled()) {
                logger.debug("Creating CGLIB2 proxy: target source is " + this.advised.
                getTargetSource());
            }
            //advised中取得在IoC容器中配置的target對象
            try {
                Class rootClass = this.advised.getTargetClass();
                Assert.state(rootClass != null, "Target class must be available for creating a
                CGLIB proxy");
                Class proxySuperClass = rootClass;
                if (AopUtils.isCglibProxyClass(rootClass)) {
                    proxySuperClass = rootClass.getSuperclass();
                    Class[] additionalInterfaces = rootClass.getInterfaces();
                    for (Class additionalInterface : additionalInterfaces) {
                          this.advised.addInterface(additionalInterface);
                    }
                }
                //驗(yàn)證代理對象的接口設(shè)置
                // 創(chuàng)建并配置CGLIBEnhancer,這個(gè)Enhancer對象是CGLIB的主要操作類
                Enhancer enhancer = createEnhancer();
                if (classLoader != null) {
                    enhancer.setClassLoader(classLoader);
                    if (classLoader instanceof SmartClassLoader &&
                           ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
                          enhancer.setUseCache(false);
                    }
                }
                //設(shè)置Enhancer對象,包括設(shè)置代理接口,回調(diào)方法
                //來自advisedIoC配置,比如使用AOPDynamicAdvisedInterceptor攔截器
                enhancer.setSuperclass(proxySuperClass);
                enhancer.setStrategy(new UndeclaredThrowableStrategy
                (UndeclaredThrowableException.class));
                enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
                enhancer.setInterceptDuringConstruction(false);
                Callback[] callbacks = getCallbacks(rootClass);
                enhancer.setCallbacks(callbacks);
                enhancer.setCallbackFilter(new ProxyCallbackFilter(
                          this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap,
                          this.fixedInterceptorOffset));
                Class[] types = new Class[callbacks.length];
                for (int x = 0; x < types.length; x++) {
                    types[x] = callbacks[x].getClass();
                }
                enhancer.setCallbackTypes(types);
                // 通過Enhancer生成代理對象
                Object proxy;
                if (this.constructorArgs != null) {
                    proxy = enhancer.create(this.constructorArgTypes, this.constructorArgs);
                }
                else {
                    proxy = enhancer.create();
                }
                return proxy;
            }
            catch (CodeGenerationException ex) {
                throw new AopConfigException("Could not generate CGLIB subclass of class [" +
                        this.advised.getTargetClass() + "]: " +
                        "Common causes of this problem include using a final class or a
                        non-visible class",ex);
            }
            catch (IllegalArgumentException ex) {
                throw new AopConfigException("Could not generate CGLIB subclass of class [" +
                        this.advised.getTargetClass() + "]: " +
                        "Common causes of this problem include using a final class or anon-visible
                        class", ex);
            }
            catch (Exception ex) {
                throw new AopConfigException("Unexpected AOP exception", ex);
            }
        }

在代碼清單中,可以看到具體對CGLIB的使用,比如對Enhancer對象的配置,以及通過Enhancer對象生成代理對象的過程。在這個(gè)生成代理對象的過程中,需要注意的是對Enhancer對象callback回調(diào)的設(shè)置,正是這些回調(diào)封裝了Spring AOP的實(shí)現(xiàn),就像前面介紹的JDK的Proxy對象的invoke回調(diào)方法一樣。在Enhancer的callback回調(diào)設(shè)置中,實(shí)際上是通過設(shè)置DynamicAdvisedInterceptor攔截器來完成AOP功能的,如果讀者感興趣,可以在getCallbacks方法實(shí)現(xiàn)中看到回調(diào)DynamicAdvisedInterceptor的設(shè)置。

        Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);

DynamicAdvisedInterceptor中的回調(diào)實(shí)現(xiàn)會在下面詳細(xì)分析,這里先埋一個(gè)伏筆。

這樣,通過使用AopProxy對象封裝target目標(biāo)對象之后,ProxyFactoryBean的getObject方法得到的對象就不是一個(gè)普通的Java對象了,而是一個(gè)AopProxy代理對象。在ProxyFactoryBean中配置的target目標(biāo)對象,這時(shí)已經(jīng)不會讓應(yīng)用直接調(diào)用其方法實(shí)現(xiàn),而是作為AOP實(shí)現(xiàn)的一部分。對target目標(biāo)對象的方法調(diào)用會首先被AopProxy代理對象攔截,對于不同的AopProxy代理對象生成方式,會使用不同的攔截回調(diào)入口。例如,對于JDK的AopProxy代理對象,使用的是InvocationHandler的invoke回調(diào)入口;而對于CGLIB的AopProxy代理對象,使用的是設(shè)置好的callback回調(diào),這是由對CGLIB的使用來決定的。在這些callback回調(diào)中,對于AOP實(shí)現(xiàn),是通過DynamicAdvisedInterceptor來完成的,而DynamicAdvisedInterceptor的回調(diào)入口是intercept方法。通過這一系列的準(zhǔn)備,已經(jīng)為實(shí)現(xiàn)AOP的橫切機(jī)制奠定了基礎(chǔ),在這個(gè)基礎(chǔ)上,AOP的Advisor已經(jīng)可以通過AopProxy代理對象的攔截機(jī)制,對需要它進(jìn)行增強(qiáng)的target目標(biāo)對象發(fā)揮切面的強(qiáng)大威力了。

可以把AOP的實(shí)現(xiàn)部分看成由基礎(chǔ)設(shè)施準(zhǔn)備和AOP運(yùn)行輔助這兩個(gè)部分組成,這里的AopProxy代理對象的生成,可以看成是一個(gè)靜態(tài)的AOP基礎(chǔ)設(shè)施的建立過程。通過這個(gè)準(zhǔn)備過程,把代理對象、攔截器這些待調(diào)用的部分都準(zhǔn)備好,等待著AOP運(yùn)行過程中對這些基礎(chǔ)設(shè)施的使用。對于應(yīng)用觸發(fā)的AOP應(yīng)用,會涉及AOP框架的運(yùn)行和對AOP基礎(chǔ)設(shè)施的使用。這些動態(tài)的運(yùn)行部分,是從前面提到的攔截器回調(diào)入口開始的,這些攔截器調(diào)用的實(shí)現(xiàn)原理,和AopProxy代理對象生成一樣,也是AOP實(shí)現(xiàn)的重要組成部分,同時(shí)也是下面要重點(diǎn)分析的內(nèi)容,讓我們繼續(xù)深入AopProxy代理對象的回調(diào)實(shí)現(xiàn)中去,慢慢地揭開Spring AOP實(shí)現(xiàn)的另一層神秘的面紗。

主站蜘蛛池模板: 天长市| 黔东| 黄梅县| 河源市| 宁津县| 建德市| 彰武县| 银川市| 兴国县| 镇远县| 游戏| 句容市| 仁化县| 芒康县| 高碑店市| 吉隆县| 名山县| 炎陵县| 满洲里市| 江西省| 龙泉市| 文安县| 龙胜| 石河子市| 新竹市| 株洲县| 榆树市| 右玉县| 错那县| 大兴区| 禄丰县| 东莞市| 突泉县| 鹤山市| 黔南| 沁阳市| 德钦县| 增城市| 德令哈市| 平果县| 车致|