"spring在ioc容器中获取aop的受理对象",这句话是什么意思呢?有时候我们会在spring项目中对一下类进行代理,比如我们会用spring的aop和自定义注解对一些接口访问添加日志,再比如对service层添加事物。这些操作spring都会自动帮我们生成代理对象。当我们需要在spring容器启动后获取ioc容器中的对象时,这个时候获取的确实代理对象了。已经不是我们的原生对象了。这时再去获取对象的类型,以及该类型的属性,方法等获取的都是代理对象的属性和方法。那么如何获取受理(不是代理)对象呢?使用下面的一个工具类即可。
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;
}
}
调用getTarget
方法传入代理对象,即可获得受理对象。