标题是什么意思呢?
比如现在有一个service类,通过@Service注解加入到ioc容器中,那么此时在程序运行中去ioc容器中获取这个service对象,获取的就是原滋原味的service。但是如果对这个service通过aop代理后(比如用到了事物等),再次在程序运行过程中获取这个service,那么获取的就是代理后的service,这时再去通过反射获取service的属性,方法等获取到的就是代理后的对象的属性或方法,就无法获取我们想要的数据。但是spring提供了一下接口,可以通过代理对象获取到被代理的对象。
import org.springframework.aop.framework.AdvisedSupport;
import org.springframework.aop.framework.AopProxy;
import org.springframework.aop.support.AopUtils;
import java.lang.reflect.Field;
/**
* @ClassName SpringAopTargetUtil
* @Description 在 spring aop 对容器中的对象代理以后 通过spring的接口获取的对象都是代理后的对象
* 该工具类能获取到被代理的对象
* @Author Jiajiajia
* @Date 2020/12/20 14:42
**/
public class SpringAopTargetUtil {
/**
* 获取被代理类的Object
*/
public static Object getTarget(Object proxy) throws Exception {
if(!AopUtils.isAopProxy(proxy)) {
/**
* 不是代理对象
*/
return proxy;
}
if(AopUtils.isJdkDynamicProxy(proxy)) {
/**
* jdk代理
*/
return getJdkDynamicProxyTargetObject(proxy);
} else {
/**
* cglib 代理
*/
return getCglibProxyTargetObject(proxy);
}
}
/**
* @MethodName: getCglibProxyTargetObject
* @Description: CGLIB方式被代理类的获取
* @Author: Jiajiajia
* @Params: * @param proxy
* @Return {@link Object}
* @date 2020/12/20
*/
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;
}
/**
* @MethodName: getJdkDynamicProxyTargetObject
* @Description: JDK动态代理方式被代理类的获取
* @Author: Jiajiajia
* @Params: * @param proxy
* @Return {@link Object}
* @date 2020/12/20
*/
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;
}
}