- Spring技術內幕:深入解析Spring架構與設計原理(第2版)
- 計文柯
- 1060字
- 2018-12-31 19:55:45
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的高級特性,有興趣的讀者可以結合自己的需要進行分析。
- Learning Single:page Web Application Development
- Spring 5.0 By Example
- 動手玩轉Scratch3.0編程:人工智能科創教育指南
- iOS開發實戰:從零基礎到App Store上架
- JavaScript+jQuery開發實戰
- Animate CC二維動畫設計與制作(微課版)
- Instant QlikView 11 Application Development
- 人人都是網站分析師:從分析師的視角理解網站和解讀數據
- PhpStorm Cookbook
- Learning FuelPHP for Effective PHP Development
- Learning OpenStack Networking(Neutron)
- Mastering Xamarin.Forms(Second Edition)
- Mobile Device Exploitation Cookbook
- 計算機應用基礎教程(Windows 7+Office 2010)
- 軟件測試綜合技術