前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring的cglib代理类无法取到被代理类的成员属性

Spring的cglib代理类无法取到被代理类的成员属性

原创
作者头像
code-x
修改2023-04-19 22:32:44
1.7K0
修改2023-04-19 22:32:44
举报
文章被收录于专栏:code-x

cglib的原理是生成一个被代理类的子类进行增强, 那么为什么子类访问不到父类的属性呢

代码语言:javascript
复制
@Service
public class AopTestService {

    public String value = "hello world";

    @Transactional
    public void imTest() {
        Object obj = SpringUtil.getBean(this.getClass());
        boolean bool1 = AopUtils.isAopProxy(obj);
        boolean bool2 = AopUtils.isAopProxy(this);
        System.err.println(StrUtil.format("bool1:{}, bool2:{}, value:{}", bool1, bool2, this.value));
    }

    @Transactional
    public final void noImTest() {
        Object obj = SpringUtil.getBean(this.getClass());
        boolean bool1 = AopUtils.isAopProxy(obj);
        boolean bool2 = AopUtils.isAopProxy(this);
        System.err.println(StrUtil.format("bool1:{}, bool2:{}, value:{}", bool1, bool2, this.value));
        System.err.println(this.getValue());
    }

    public String getValue() {
        return value;
    }
}
代码语言:java
复制
@Autowired
AopTestService aopTestService;

@PostConstruct
public void test() {
    aopTestService.imTest();
    aopTestService.noImTest();
    System.err.println("test: " + aopTestService.value);
}

输出

代码语言:javascript
复制
bool1:true, bool2:false, value:hello world
bool1:true, bool2:true, value:null
hello world
test: null
  1. 第一行: bool1肯定为true, 因为这是从容器中取到的对象. 根据aop代理规则, imTest方法可以被代理, 下面就是cglib生成的子类方法, 通过var10000.intercept代理拦截器, 最终使用源类AopTestService的对象去调用imTest方法
代码语言:java
复制
public final void imTest() {       
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;       
    if (var10000 == null) {            
        CGLIB$BIND_CALLBACKS(this);            
        var10000 = this.CGLIB$CALLBACK_0;       
    }        
    if (var10000 != null) {            
        var10000.intercept(this, CGLIB$imTest$2$Method, CGLIB$emptyArgs, CGLIB$imTest$2$Proxy);
    } else {            
        super.imTest();       
    }  
}

所以, bool2为false, this.value正常输出

2. 第二行: bool2true, 因为noImTest方法被final修饰, 无法被代理增强, 所以最终是通过cglib生成的子类去调用父类AopTestServicenoImTest方法. 但是this.value输出null, 这是因为cglib生成的子类对象, 是通过objenesis这个库实例化的, objenesis这个库的作用是绕过构造方法实例化对象. 所以对象没有正常的初始化, 父类的value属性也就没有了

3. 第三行, this.getValue输出了. 这个方法也是被子类重写了, 最终也是通过源类AopTestService的对象去调用对应方法, 所以能够输出

代码语言:java
复制
public final String getValue() {       
    MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;       
    if (var10000 == null) {            
        CGLIB$BIND_CALLBACKS(this);            
        var10000 = this.CGLIB$CALLBACK_0;       
    }       
    return var10000 != null ? 
    (String)var10000.intercept(this, CGLIB$getValue$0$Method, CGLIB$emptyArgs, CGLIB$getValue$0$Proxy) 
    : super.getValue();  
}

4. 第四行: 原因同第二行

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档