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物件存在著的。