cglib 动态代理

本文深入探讨了CGLIB动态代理的工作原理,通过实例展示了如何使用CGLIB创建代理类并重写方法。重点讲解了CGLIB与JDK动态代理的对比,以及何时选择CGLIB。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Cglib动态代理

CGLIB是一个功能强大,高性能的代码生成包。它为没有实现接口的类提供代理,为JDK的动态代理提供了很好的补充

通常可以使用Java的动态代理创建代理,但当要代理的类没有实现接口或者为了更好的性能,CGLIB 是一个好的选择。



前言

CGLIB 动态代理

 JDK的动态代理机制只能代理实现了接口的类。而不能实现接口的类就不能使
 用JDK的动态代理,CGLIB是针对类来实现代理的,它的原理是对指定目标类生
 成一个子类,并覆盖其中的方法实现增强,但因为采用的是继承,所以不能对
 final修饰的类进行代理。

一、原理

实现原理:继承思想:

代理类继承目标类,重写目标类中的方法, CGLIB像是一个拦截器,在调用我们的代理类方法时,代理类(子类)会去找到目标类(父类),此时它会被一个方法拦截器所拦截,在拦截器中才会去实现方法的调用。并且还会对方法进行行为增强。

二、简单实现Cglib

1.导入依赖

 <dependency>
	   <groupId>cglib</groupId>
	   <artifactId>cglib</artifactId>
	   <version>3.1</version>
 </dependency>

2.新建目标代理类

public class userviceImpl{
   public void add() {
        System.out.println("我是目标代理类");
    }
}

3.创建代理类Cglib

创建代理类,里面主要有2个方法,一个为获取代理的实例方法,另一个为需要重写的方法,此类需要实现MethodInterceptor接口,该接口很简单,此包含一个方法intercept:

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class Cglib implements MethodInterceptor {

  /** 指定cglib代理模式的代理类 */
  private Object target;

/*在创建实例前,我们需要使用一个叫Enhancer的对象,此对象用来创建代理对象,
    设置目标类为超类后的同时需要回调当前类 */
  public Object bind(Object target) {
    this.target = target;
    Enhancer enhancer = new Enhancer();
    // 设置超类方法
    enhancer.setSuperclass(this.target.getClass());
    // 设置一个回调方法,用来设置哪个类为代理类,this表示当前类为代理类
    enhancer.setCallback(this);
    // 创建代理对象
    return enhancer.create();
  }

  @Override
  public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy)
      throws Throwable {
    System.out.println("CGLIB代理前");
    //invokerSuper 或许可以理解为 调用目标对象方法
    Object object = proxy.invokeSuper(obj, args);
    System.out.println("CGLIB代理后");
    return object;
  }
}
/*intercept方法的几个参数说明:
obj:表示目标对象

method:表示当前调度的方法,这里指的是HelloWorld类里面的sayHello()方法

args:表示执行方法的参数列表

MethodProxy: 表示执行目标方法的代理对象
*/

4创建测试:

 @Test
    public void cglib01(){

        Cglib cglib = new Cglib();

        userviceImpl userServiceImpl = (userviceImpl) cglib.bind(new userviceImpl());

        userServiceImpl.add();
    }

结果截图:
在这里插入图片描述


总结

在这里插入图片描述

目前主流还是使用Cglib 动态代理比较多 ,所以建议Cglib 要学会,JDK 动态代理也最好掌握
Cglib和jdk动态代理的区别?


1、Jdk动态代理:利用拦截器(必须实现InvocationHandler)加上反射机制
生成一个代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理
2、 Cglib动态代理:利用ASM框架,对代理对象类生成的class文件加载进来,
通过修改其字节码生成子类来处理

什么时候用cglib什么时候用jdk动态代理?

1、目标对象生成了接口 默认用JDK动态代理
2、如果目标对象使用了接口,可以强制使用cglib
3、如果目标对象没有实现接口,必须采用cglib库,Spring会自动在JDK动态代理
和cglib之间转换

JDK动态代理和cglib字节码生成的区别?

1、JDK动态代理只能对实现了接口的类生成代理,而不能针对类
2、Cglib是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法,并覆盖其中方法的增强,但是因为采用的是继承,所以该类或方法最好不要生成final,对于final类或方法,是无法继承的
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

huangshaohui00

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值