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

3.5 Spring AOP的高級特性

了解了Spring AOP的基本實現,下面通過一個使用Spring AOP高級特性的例子,來了解它的實現原理。在使用Spring AOP時,對目標對象的增強是通過攔截器來完成的。對于一些應用場合,需要對目標對象本身進行一些處理,比如,如何從一個對象池或對象工廠中獲得目標對象等。對于這種情況,需要使用Spring的TargetSource接口特性,在這里,把這類AOP特性當成高級特性的一種,通過對這些AOP特性的實現原理的了解,可以實現對AOP基本特性的靈活運用。

Spring提供了許多現成的TargetSource實現,比如HotSwappableTargetSource,HotSwappableTargetSource使用戶可以以線程安全的方式切換目標對象,提供所謂的熱交換功能。這個特性是很有用的,盡管它的開啟需要AOP應用進行顯式的配置,但配置并不復雜,在使用時,只需要把HotSwappableTargetSource配置到ProxyFactoryBean的target屬性就可以了,在需要更換真正的目標對象時,調用HotSwappableTargetSource的swap方法就可以完成。由此可見,對HotSwappableTargetSource的熱交換功能的使用,是需要觸發swap方法調用的。這個swap方法的實現很簡單,它完成target對象的替換,也就是說,它使用新的target對象來替換原有的target對象。為了保證線程安全,需要把這個替換方法設為synchronized方法,如代碼清單3-34所示。

代碼清單3-34 HotSwappableTargetSource的swap方法

        public synchronized Object swap(Object newTarget) throws IllegalArgumentException {
            Assert.notNull(newTarget, "Target object must not be null");
            Object old = this.target;
            this.target = newTarget;
            return old;
            }
            public synchronized Object getTarget() {
                return this.target;
        }

這個target是怎樣在AOP中起作用的呢?了解一下對getTarget的調用就很清楚了,HotSwappableTargetSource只是對真正的target做了一個簡單的封裝,以提供熱交換的能力,并沒有其他特別之處。對getTarget的方法調用關系,如圖3-21所示。

圖3-21 AOP對getTarget的調用

以JdkDynamicAopProxy的實現為例,可以看到在AOP對Proxy代理對象進行invoke方法調用的時候,會通過getTarget調用取得真正的目標對象,如果已經調用過swap方法完成目標對象的熱交換,那么交給AOP的已經是交換后的目標對象了,如代碼清單3-35所示。具體來說,在invoke方法中,代理對象是在AopProxy代理對象的攔截器起作用之前,通過targetSource.getTarget()的調用來取得的,而這個代理對象是否被更換過,是由對swap方法的調用來負責的。因此,在invoke方法中,使用了什么樣的代理對象,都不會對攔截器的行為做任何的改變。

代碼清單3-35 invoke獲取目標對象

        target = targetSource.getTarget();
        if (target != null) {
            targetClass = target.getClass();
        }
                    // 這里獲得定義好的攔截器鏈
        List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice
        (method, targetClass);
        // 如果沒有設定攔截器,那么就直接調用target的對應方法
        if (chain.isEmpty()) {
            retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);
        }
        else {
            // 如果有攔截器的設定,那么需要調用攔截器之后才調用目標對象的相應方法
            //通過構造一個ReflectiveMethodInvocation來實現
            invocation = new ReflectiveMethodInvocation(proxy, target, method, args,
            targetClass, chain);
            //沿著攔截器鏈,對Joinpoint連接器進行調用
            retVal = invocation.proceed();
        }
                    if (retVal != null && retVal == target && method.getReturnType().
                    isInstance(proxy) &&
                    !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
            retVal = proxy;
        }
        return retVal;

通過getTarget方法,完成了HotSwappableTargetSource與AOP的集成。這個熱交換功能為AOP的使用提供了更多便利,對構建應用的基礎服務是非常有幫助的,比如可以在運行時支持需要改變的對象進行重新配置。對于其他AOP的高級特性,有興趣的讀者可以結合自己的需要進行分析。

主站蜘蛛池模板: 绍兴市| 云龙县| 柞水县| 新河县| 东莞市| 柳林县| 资源县| 石景山区| 土默特左旗| 当雄县| 博野县| 镇江市| 武鸣县| 泽普县| 临漳县| 娱乐| 酉阳| 蛟河市| 苏尼特左旗| 慈溪市| 东城区| 新闻| 吉木萨尔县| 长子县| 东丰县| 博客| 双峰县| 常熟市| 五大连池市| 泰州市| 白河县| 吉首市| 囊谦县| 武夷山市| 客服| 如皋市| 张掖市| 上饶市| 玛曲县| 麦盖提县| 哈尔滨市|