在spring中獲取代理物件代理的目標物件工具類
問題描述
我現在遇到個棘手的問題,要通過spring託管的service類儲存物件,這個類是通過反射拿到的,經過實驗發現這個類只能反射取得sservice實現了介面的方法,而extends類的方法一律不出現,debug後發現這個servie例項被spring替換成jdkdynmicproxy類,而不是原始物件了,,它裡面只有service繼承的介面方法,而沒有extends 過的super class方法,怎麼呼叫原生物件的方法!!!!!
用託管的spring service類呼叫getClass().getName()方法,發現輸出都是$proxy43這類東西!!
通過此種方式獲取目標物件是不可靠的,或者說任何獲取目標物件的方式都是不可靠的,因為TargetSource,TargetSource中存放了目標物件,但TargetSource有很多種實現,預設我們使用的是SingletonTargetSource ,但還有其他的比如ThreadLocalTargetSource、CommonsPoolTargetSource 等等。
這也是為什麼spring沒有提供獲取目標物件的API。
解決方法
import java.lang.reflect.Field;
import org.springframework.aop.framework.AdvisedSupport;
import org.springframework.aop.framework.AopProxy;
import org.springframework.aop.support.AopUtils;
public class AopTargetUtils {
/**
* 獲取 目標物件
* @param proxy 代理物件
* @return
* @throws Exception
*/
public static Object getTarget(Object proxy) throws Exception {
if(!AopUtils.isAopProxy(proxy)) {
return proxy;//不是代理物件
}
if(AopUtils.isJdkDynamicProxy(proxy)) {
return getJdkDynamicProxyTargetObject(proxy);
} else { //cglib
return getCglibProxyTargetObject(proxy);
}
}
private static Object getCglibProxyTargetObject(Object proxy) throws Exception {
Field h = proxy.getClass().getDeclaredField("CGLIB$CALLBACK_0");
h.setAccessible(true);
Object dynamicAdvisedInterceptor = h.get(proxy);
Field advised = dynamicAdvisedInterceptor.getClass().getDeclaredField("advised");
advised.setAccessible(true);
Object target = ((AdvisedSupport)advised.get(dynamicAdvisedInterceptor)).getTargetSource().getTarget();
return target;
}
private static Object getJdkDynamicProxyTargetObject(Object proxy) throws Exception {
Field h = proxy.getClass().getSuperclass().getDeclaredField("h");
h.setAccessible(true);
AopProxy aopProxy = (AopProxy) h.get(proxy);
Field advised = aopProxy.getClass().getDeclaredField("advised");
advised.setAccessible(true);
Object target = ((AdvisedSupport)advised.get(aopProxy)).getTargetSource().getTarget();
return target;
}
}
相關文章
- 反射獲取注入到spring中的類物件的工具類反射Spring物件
- 建立獲取Springbean物件工具類SpringBean物件
- 死磕Spring之AOP篇 - Spring AOP自動代理(三)建立代理物件Spring物件
- Java獲取Spring的各種物件JavaSpring物件
- Spring事務管理與AOP代理的原理,預設的單例物件和代理物件銷燬的時機Spring單例物件
- JDK動態代理物件與被代理物件地址值問題JDK物件
- 代理模式-訪問物件的代理而非其本身模式物件
- 物件獲取原型物件物件原型
- Spring AOP 中被代理的物件一定是單例嗎?Spring物件單例
- JavaScript代理模式,怎麼實現物件的動態代理?JavaScript模式物件
- 通過反射獲取私有內部類物件反射物件
- 死磕Spring之AOP篇 - Spring AOP兩種代理物件的攔截處理Spring物件
- 【OpenFeign】@FeignClient 代理物件的建立原始碼分析client物件原始碼
- 經過代理如何獲取真實IP 及 laravel 中配置可信代理的原理Laravel
- Java中獲取Class物件的三種方式Java物件
- Spring boot 獲取yml檔案工具類Spring Boot
- Unity通過子物件獲取父物件例子Unity物件
- 【Spring AOP】AOP 底層實現原理 —— 動態代理類的建立(JDK、CGlib)、工廠如何加工原始物件SpringJDKCGLib物件
- Hyperf 獲取 Swoole\Server 的物件以及函式類的封裝Server物件函式封裝
- 使用selenium定位獲取標籤物件並提取資料物件
- 獲取 Class 物件的 3 種方法物件
- Java獲取Class物件的方式和例項化物件的方式Java物件
- 03 #### `__dict__` , 用於獲取物件中的成員物件
- Oracle獲取資料庫中的物件建立語句Oracle資料庫物件
- 認識 JavaAgent --獲取目標程式已載入的所有類Java
- 類和物件(中)物件
- Java 獲取Word中的標題大綱(目錄)Java
- 反射--Class物件功能--獲取Method反射物件
- Python中的類與物件Python物件
- java中的類與物件Java物件
- cpp中的類和物件物件
- three.js獲取物件的材質JS物件
- JavaScript獲取滑鼠在元素中的座標JavaScript
- mybatis原始碼學習:從SqlSessionFactory到代理物件的生成MyBatis原始碼SQLSession物件
- 物體物件在螢幕中的座標及滑鼠座標物件
- 獲取Spring容器中Bean例項的工具類(Java泛型方法實現)SpringBeanJava泛型
- Java 中建立子類物件會建立父類物件麼?Java物件
- 15 ##### 適合繫結方法的場景:在物件中封裝值,在方法中讀取物件的值物件封裝