CGLIB 动态代理使用

举报
小毕超 发表于 2022/09/25 00:40:42 2022/09/25
【摘要】 一、CGLIB Cglib是一个强大的,高性能,高质量的代码生成类库。它可以在运行期扩展JAVA类与实现JAVA接口。其底层实现是通过ASM字节码处理框架来转换字节码并生成新的类。大部分功能实际上是AS...

一、CGLIB

Cglib是一个强大的,高性能,高质量的代码生成类库。它可以在运行期扩展JAVA类与实现JAVA接口。其底层实现是通过ASM字节码处理框架来转换字节码并生成新的类。大部分功能实际上是ASM所提供的,Cglib只是封装了ASM,简化了ASM操作,实现了运行期生成新的class。

运行时动态的生成一个被代理类的子类(通过ASM字节码处理框架实现),子类重写了被代理类中所有非 final 的方法。在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势植入横切逻辑。

Cglib优缺点:

优点:JDK动态代理要求被代理的类必须实现接口,当需要代理的类没有实现接口时Cglib代理是一个很好的选择。实现扩展功能,对我们方法实现增强、安全性、冗余性提高代码复用机制。

缺点:对于被代理类中的final方法,无法进行代理,因为子类中无法重写final函数

注意:jdk7 开始 jdk 动态代理效率比 cglib 要高。

二、CGLIB代理实现

实现 MethodInterceptor 接口的 intercept 方法后,所有生成的代理方法都调用这个方法。
intercept方法的具体参数有

  1. obj 目标类的实例
  2. method 目标方法实例(通过反射获取的目标方法实例)
  3. args 目标方法的参数
  4. proxy 代理类的实例
    该方法的返回值就是目标方法的返回值。
@Slf4j
public class CglibMethodInterceptor implements MethodInterceptor {
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        log.info("<目标方法之前开始执行....>");
        Object result = proxy.invokeSuper(obj, args);
        log.info("<目标方法之后开始执行....>");
        return result;
    }
}

创建目标代理对象:

@Slf4j
public class TargetObject {
    
    public String exec(String param) {
        log.info("<param:{}>", param);
        return "ok";
    }
}

使用 CGLIB 代理目标方法:

public class Test {
    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(TargetObject.class);
        enhancer.setCallback(new CglibMethodInterceptor());
        TargetObject targetObject = (TargetObject) enhancer.create();
        String result = targetObject.exec("ABC");
        System.out.println(result);
    }
}

在这里插入图片描述

文章来源: blog.csdn.net,作者:小毕超,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/qq_43692950/article/details/126690354

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。