在spring中獲取代理對象代理的目標對象工具類

 

昨天晚上一哥們需要獲取代理對象的目標對象,查找了文檔發現沒有相應的工具類,因此自己寫了一個分享給大家。能獲取JDK動態代理/CGLIB代理對象代理的目標對象。

 

 

問題描述::

 

我現在遇到個棘手的問題,要通過spring託管的service類保存對象,這個類是通過反射拿到的,經過實驗發現這個類只能反射取得sservice實現了接口的方法,而extends類的方法一律不出現,debug後發現這個servie實例被spring替換成jdkdynmicproxy類,而不是原始對象了,,它裏面只有service繼承的接口方法,而沒有extends 過的super class方法,怎麼調用原生對象的方法!!!!!

 

用託管的spring service類調用getClass().getName()方法,發現輸出都是$proxy43這類東西!!

 

 

通過此種方式獲取目標對象是不可靠的,或者說任何獲取目標對象的方式都是不可靠的,因爲TargetSource,TargetSource中存放了目標對象,但TargetSource有很多種實現,默認我們使用的是SingletonTargetSource ,但還有其他的比如ThreadLocalTargetSourceCommonsPoolTargetSource 等等。

 

這也是爲什麼spring沒有提供獲取目標對象的API。

 

 

Java代碼  收藏代碼
  1. import java.lang.reflect.Field;  
  2.   
  3. import org.springframework.aop.framework.AdvisedSupport;  
  4. import org.springframework.aop.framework.AopProxy;  
  5. import org.springframework.aop.support.AopUtils;  
  6.   
  7. public class AopTargetUtils {  
  8.   
  9.       
  10.     /** 
  11.      * 獲取 目標對象 
  12.      * @param proxy 代理對象 
  13.      * @return  
  14.      * @throws Exception 
  15.      */  
  16.     public static Object getTarget(Object proxy) throws Exception {  
  17.           
  18.         if(!AopUtils.isAopProxy(proxy)) {  
  19.             return proxy;//不是代理對象  
  20.         }  
  21.           
  22.         if(AopUtils.isJdkDynamicProxy(proxy)) {  
  23.             return getJdkDynamicProxyTargetObject(proxy);  
  24.         } else { //cglib  
  25.             return getCglibProxyTargetObject(proxy);  
  26.         }  
  27.           
  28.           
  29.           
  30.     }  
  31.   
  32.   
  33.     private static Object getCglibProxyTargetObject(Object proxy) throws Exception {  
  34.         Field h = proxy.getClass().getDeclaredField("CGLIB$CALLBACK_0");  
  35.         h.setAccessible(true);  
  36.         Object dynamicAdvisedInterceptor = h.get(proxy);  
  37.           
  38.         Field advised = dynamicAdvisedInterceptor.getClass().getDeclaredField("advised");  
  39.         advised.setAccessible(true);  
  40.           
  41.         Object target = ((AdvisedSupport)advised.get(dynamicAdvisedInterceptor)).getTargetSource().getTarget();  
  42.           
  43.         return target;  
  44.     }  
  45.   
  46.   
  47.     private static Object getJdkDynamicProxyTargetObject(Object proxy) throws Exception {  
  48.         Field h = proxy.getClass().getSuperclass().getDeclaredField("h");  
  49.         h.setAccessible(true);  
  50.         AopProxy aopProxy = (AopProxy) h.get(proxy);  
  51.           
  52.         Field advised = aopProxy.getClass().getDeclaredField("advised");  
  53.         advised.setAccessible(true);  
  54.           
  55.         Object target = ((AdvisedSupport)advised.get(aopProxy)).getTargetSource().getTarget();  
  56.           
  57.         return target;  
  58.     }  
  59.       

發佈了27 篇原創文章 · 獲贊 8 · 訪問量 48萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章