Arthas 可视化被 CGLIB 动态代理后的新类

7 篇文章 0 订阅

欢迎访问陈同学博客原文

有小伙伴问:“Spring 中被 CGLIB 动态代理后的新类究竟是什么样子?能不能反编译出来看看?”。

确实,亲眼看看被动态代理后的新类有助于理解知识。

本篇就借助于阿里 Arthas 反编译内存中 class 来做个简单演示。

Demo

下面是写在 Spring Boot 应用中的一个 Controller,beans 接口返回所有bean,hello() 方法被 @Transactional 注解标记后,类会自动被动态代理以进行声明式事务的处理。

package com.example;

@RestController
public class HelloController implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    @GetMapping("beans")
    public Object getBeans() {
        return applicationContext.getBean("");
    }

    @Transactional
    public void hello() {
        System.out.println("hello");
    }
}

启动应用后,访问 beans 拿到 helloController

{
    "bean": "helloController",
    "aliases": [],
    "scope": "singleton",
    "type": "com.example.HelloController$$EnhancerBySpringCGLIB$$2d4c54bd",
    "resource": "file [.../target/classes/com/example/HelloController.class]",
    "dependencies": []
}

bean 的类型是被代理后的新类:com.example.HelloController$$EnhancerBySpringCGLIB$$2d4c54bd,从名字中的 EnhancerBySpringCGLIB 可以看出由 SpringCGLIB 进行增强。

从内存反编译class

下载 arthas-boot.jar 后,本地直接运行jar包:**java -jar arthas-boot.jar **。

然后利用其 jad 即java decompile 命令直接反编译内存中的class。

jad com.example.HelloController$$EnhancerBySpringCGLIB$$2d4c54bd

下面是部分截图,可以直接拷贝到IDEA中查看更多信息。

[外链图片转存失败(img-ki0KHlJO-1564881619722)(https://imgcdn.chenyongjun.vip/2019/07/27/1.png)]

新类继承自HelloController,实现了 SpringProxy、Advised。再看看 HelloController 中 hello() 方法处理情况。

public class HelloController$$EnhancerBySpringCGLIB$$2d4c54bd
extends HelloController
implements SpringProxy,
Advised,
Factory {
    
    final void CGLIB$hello$1() {
        super.hello();
    }
    
    public final void hello() {
        try {
            MethodInterceptor methodInterceptor = this.CGLIB$CALLBACK_0;
            ...
            if (methodInterceptor != null) {
                Object object = methodInterceptor.intercept(...);
                return;
            }
            // 最终调用父类方法
            super.hello();
            return;
        }
        catch ...
    }
}

子类 override 了 hello() 方法,且在其中嵌入了方法拦截。

DynamicAdvisedInterceptor 实现了 MethodInterceptor,它会执行一个拦截器链,而 Spring 的 TransactionInterceptor 是拦截器中一员,负责加入事务处理机制。

附:CGLIB底层基于ASM来操作字节码,从而实现上述的动态创建新类,达到动态代理的效果。


欢迎关注公众号 [陈一乐],一起学习,一起成长

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值