spring在ioc容器中获取aop的受理对象

硅谷探秘者 算法基础 548 0 0

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

猜你喜欢
工具 2999 一个工具类即可packagecom.dzqc.yx.util;importorg.springframework.beans.BeansException;importorg.springframework.context.ApplicationContext;importorg.springframework.context.ApplicationContextAware;importorg.s
spring/springmvc 1259 WebApplicationContextwebApplicationContext=ContextLoader.getCurrentWebApplicationContext();ServletContextcontext=webApplicationContext.getServletContext();
spring/springmvc 605 (A.class):加此注解bean会A加载之后加载 @ConditionalOnMissingBean(A.class):当ioc含有A类型时,那么ioc则会忽略@Component注解,
official 94   BeanFactory是一种“Spring”,BeanFactory翻译过来就是Bean工厂,顾名思义,它可以用来创建Bean、Bean,BeanFactory是Spring非常核心
框架 635 最近项目遇到了一个批量导入excel功能,excel导入用到是esaypoi,可以轻松将excel数据封装成,但是不知为何,突然转换过程变得很慢,一万条数据得转换一分钟。无奈只
框架 273 springboot项目所有外提供接口信息@ComponentpublicclassTestimplementsApplicationRunner
official 151   BeanPostProcessor是SpringIOC给我们提供一个扩展接口。,他作用主要是如果我们需要Spring完成Bean实例化、配置和其他初始化前后添加一些自己逻辑处
java虚拟机(jvm) 1384 这里以HotSpot为例,且所说指普通Java,不包括数组和Class等。参考资料深入解java虚拟机《周志明》1.内存布局HotSpot虚拟机内存存储布局可以
归档
2018年11月  12 2018年12月  33 2019年01月  28 2019年02月  28 2019年03月  32 2019年04月  27 2019年05月  33 2019年06月  6 2019年07月  12 2019年08月  12 2019年09月  21 2019年10月  8 2019年11月  15 2019年12月  25 2020年01月  9 2020年02月  5 2020年03月  16 2020年04月  4 2020年06月  1 2020年07月  7 2020年08月  13 2020年09月  9 2020年10月  5 2020年12月  3 2021年01月  1 2021年02月  5 2021年03月  7 2021年04月  4 2021年05月  4 2021年06月  1 2021年07月  7 2021年08月  2 2021年09月  8 2021年10月  9 2021年11月  16 2021年12月  14 2022年01月  7 2022年05月  1
标签
算法基础 linux 前端 c++ 数据结构 框架 数据库 计算机基础 储备知识 java基础 ASM 其他 深入理解java虚拟机 nginx git 消息中间件 搜索 maven redis docker dubbo vue 导入导出 软件使用 idea插件 协议 无聊的知识 jenkins springboot mqtt协议 keepalived
目录
祝愿神州十三飞行乘组平安归来