在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物件
- spring aop獲取目標物件的方法物件(包括方法上的註解)Spring物件
- javascript如何獲取事件目標物件JavaScript事件物件
- 建立獲取Springbean物件工具類SpringBean物件
- [譯]ES6中的代理物件物件
- JDK動態代理物件與被代理物件地址值問題JDK物件
- 死磕Spring之AOP篇 - Spring AOP自動代理(三)建立代理物件Spring物件
- 代理模式-訪問物件的代理而非其本身模式物件
- 物件獲取原型物件物件原型
- Java獲取Spring的各種物件JavaSpring物件
- JavaScript獲取head標籤物件JavaScript物件
- 在SpringMVC中獲取request物件的幾種方式SpringMVC物件
- JavaScript代理模式,怎麼實現物件的動態代理?JavaScript模式物件
- Spring AOP 中被代理的物件一定是單例嗎?Spring物件單例
- Spring中獲得dataSurce物件的方法Spring物件
- 在SPRING自動代理事務中.怎樣讓指定的攔截器對應指定的目標BEAN?SpringBean
- 通過反射獲取私有內部類物件反射物件
- Java反射獲取類和物件資訊全解析Java反射物件
- 獲取Object物件的lengthObject物件
- Java中獲取Class物件的三種方式Java物件
- js 是否能根據物件的id直接從物件陣列中獲取該物件JS物件陣列
- java 獲取物件大小Java物件
- QTP中如何快速獲取Page中的物件個數QT物件
- struts之Action中獲取request、response物件的方法物件
- 死磕Spring之AOP篇 - Spring AOP兩種代理物件的攔截處理Spring物件
- Spring boot 獲取yml檔案工具類Spring Boot
- Unity通過子物件獲取父物件例子Unity物件
- Hyperf 獲取 Swoole\Server 的物件以及函式類的封裝Server物件函式封裝
- ORACLE不使用工具的情況下獲取物件DDLOracle物件
- Java 獲取Word中的標題大綱(目錄)Java
- 全面梳理JS物件的訪問控制及代理反射JS物件反射
- 【OpenFeign】@FeignClient 代理物件的建立原始碼分析client物件原始碼
- 認識 JavaAgent --獲取目標程式已載入的所有類Java
- 類和物件(中)物件
- Oracle獲取資料庫中的物件建立語句Oracle資料庫物件
- JavaScript獲取滑鼠在元素中的座標JavaScript
- 如何使用jQuery獲取物件的尺寸jQuery物件
- 獲取物件DDL語句的方法物件