1. 程式人生 > >SpringAOP中的joinpoint物件 target和this方法的區別

SpringAOP中的joinpoint物件 target和this方法的區別

情景如下:

建立一個持久層的類gooddaoimpl

用切面類 goodaspect進行功能增強

----------------------------------------------------------------------------------------------------------------------------------

SpringAOP中的JoinPoint物件主要有這麼幾個方法:

1:JoinPoint.getSignature(): 該方法主要獲取被代理物件的屬性名稱集合:

System.out.println("這是
joinpoint.getSignature().getName所指向的物件" + joinPoint.getSignature());
這句程式碼的輸出結果為:
這是joinpoint.getSignature().getName()所指向的物件void aoptest.dao.GoodDao.delete()

可以看到其中有被代理物件的包名類名,被代理方法名等 可以通過

joinpoint.getSignature().getName
等一系列joinpoint.getSignature().xxx方法獲取,再此不再贅述。

2:joinPoint.getTarget():

	System.out.println("這是joinpoint.gettarget所指向的物件" + joinPoint.getTarget());

此條語句的輸出結果是:

這是joinpoint.gettarget所指向的物件[email protected]

這同樣是被代理類的物件。

	System.out.println("這是joinpoint.gettarget所指向的物件" + joinPoint.getTarget().getClass().getName());

此處是獲得了被代理類的物件。

執行這條語句 結果如下:

這是joinpoint.gettarget所指向的物件aoptest.daoimpl.GoodDaoImpl

可以看出也獲得了被代理類的類名。

3:joinpoint.getthis:

System.out.println("這是joinpoint.getthis所指向的物件" + joinPoint.getThis()其

其輸出結果為:

這是joinpoint.getthis所指向的物件[email protected]

此時我們發現joinpoint.getthis和joinPoint.getTarget(),兩者獲取的是同一個物件(見類名後的地址)。那麼兩個方法的區別是什麼呢?

System.out.println("這是joinpoint.gettarget所指向的物件" + joinPoint.getTarget().getClass().getName());
System.out.println("這是joinpoint.getthis所指向的物件" + joinPoint.getThis().getClass().getName());

分別獲取兩個方法返回物件的類名

輸出結果如下:

這是joinpoint.gettarget所指向的物件aoptest.daoimpl.GoodDaoImpl
這是joinpoint.getthis所指向的物件com.sun.proxy.$Proxy18
我們眉頭一皺,發現事情並不簡單,gettarget獲取的類名是被代理類的類名,換而言之  在編譯完成之後,gettarget返回的物件是以被代理類的位元組碼檔案存在著的,而getthis的類名則是
com.sun.proxy.$Proxy18

即是代理類的型別,在編譯完成後,getthis返回的物件是以代理類位元組碼檔案存在著的。

為什麼是這種情況呢。

聯絡到AOP底層的原理——動態代理,個人做出如下猜想, 對於動態代理的過程,jvm底層也是把獲取被代理的物件從而直接生成代理類的位元組碼檔案(com.sun.proxy.$proxy),再通過Proxy內部的類載入器,生成(類似反編譯)代理類物件。

故二個方法的返回值在以java物件存在時,是同一個物件,在編譯時,getthis方法會經由Spring的JDK動態代理進行上述的底層操作,導致gethis的返回物件是以代理類的class物件存在著的。