"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方法传入代理对象,即可获得受理对象。