TargetSource(目標源)是被代理的target(目標對象)實例的來源。TargetSource被用於獲取當前MethodInvocation(方法調用)所須要的target(目標對象),這個target經過反射的方式被調用(如:method.invode(target,args))。換句話說,proxy(代理對象)代理的不是target,而是TargetSource,這點很是重要!!!java
那麼問題來了:爲何SpringAOP代理不直接代理target,而須要經過代理TargetSource(target的來源,其內部持有target),間接代理target呢?spring
一般狀況下,一個proxy(代理對象)只能代理一個target,每次方法調用的目標也是惟一固定的target。可是,若是讓proxy代理TargetSource,可使得每次方法調用的target實例都不一樣(固然也能夠相同,這取決於TargetSource實現)。這種機制使得方法調用變得靈活,能夠擴展出不少高級功能,如:target pool(目標對象池)、hot swap(運行時目標對象熱替換),等等。app
接下來要說的另一點,可能會顛覆你的既有認知:TargetSource組件自己與SpringIoC容器無關,換句話說,target的生命週期不必定是受spring容器管理的,咱們以往的XML中的AOP配置,只是對受容器管理的bean而言的,咱們固然能夠手動建立一個target,同時使用Spring的AOP框架(而不使用IoC容器)。Demo以下:框架
// 首先定義一個被代理的目標類 public class TargetBean { // 此方法演示使用 public void show() { System.out.println("show"); } } // 接下來是建立代理對象的過程 public class AOPDemo { public static void main(String[] args) { TargetBean target = new TargetBean(); TargetSource targetSource = new SingletonTargetSource(target); // 使用SpringAOP框架的代理工廠直接建立代理對象 TargetBean proxy = (TargetBean) ProxyFactory.getProxy(targetSource); // 這裏會在控制檯打印:com.lixin.aopdemo.TargetBean$$EnhancerBySpringCGLIB$$767606b3 System.out.println(proxy.getClass().getName()); } }
這個demo只是建立target的代理對象,並無添加任何加強邏輯。,從輸出能夠看到該目標類已經被CGLIB加強。整個代理過程十分簡單,沒有使用任何BeanFactory或ApplicationContext同樣能夠完成代理。ide
TargetSource功能定義以下:post
public interface TargetSource extends TargetClassAware { /** * 返回當前目標源的目標類型。 * 能夠返回null值,如:EmptyTargetSource(未知類會使用這個目標源) */ @Override Class<?> getTargetClass(); /** * 當前目標源是不是靜態的。 * 若是爲false,則每次方法調用結束後會調用releaseTarget()釋放目標對象. * 若是爲true,則目標對象不可變,也就不必釋放了。 * @return */ boolean isStatic(); /** * 獲取一個目標對象。 * 在每次MethodInvocation方法調用執行以前獲取。 * @return * @throws Exception */ Object getTarget() throws Exception; /** * 釋放指定的目標對象。 * @param target * @throws Exception */ void releaseTarget(Object target) throws Exception; }
TargetSource組件體系圖以下:spa
TargetSource包含4個簡單實現和3大類實現。prototype
四個簡單實現包括:線程
三大類實現包括:代理
總結一下,本文詳解了什麼是TargetSource,它的做用是什麼,以及該接口的各類實現。最後提醒一下:SpringAOP的自動代理(*AutoProxyCreator),只會爲受SpringIoC容器管理的bean建立SingletonTargetSource。其餘實現類均在手動代理時按需使用。