CGLIB 动态代理使用

Posted 小毕超

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CGLIB 动态代理使用相关的知识,希望对你有一定的参考价值。

一、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);
    

以上是关于CGLIB 动态代理使用的主要内容,如果未能解决你的问题,请参考以下文章

JDK动态代理与CGLIB动态代理

写cglib动态代理需要哪些jar包

DK动态代理与CGLib动态代理的区别

jdk动态代理和cglib动态代理的区别

AOP动态代理之CGLIB代理

Spring中的cglib动态代理