CGLIB动态代理的使用

CGLIB动态代理

jdk动态代理是根据实现接口来进行代理,只适合有接口的被代理类。而CGLIB动态代理是通过继承被代理类来实现代理的,适用于没有接口的被代理类。

代码实现

下面通过销售汽车的例子来实现代码。

pom文件引入依赖:

(如果不是maven工程,需要引入cglib和asm两个依赖,因为cglib需要靠asm解析)


<dependencies>
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>3.3.0</version>
        </dependency>
    </dependencies>
/**
 * 真实主体类(目标对象)
 */
public class CarFactory{

    public void sell() {
        System.out.println("进行汽车售卖");
    }

    public void check() {
        System.out.println("进行汽车检测");
    }
}

/**
 * 代理工厂对象(创造代理类)
 */
public class ProxyFactory implements MethodInterceptor {
    //真实主题类
    private  CarFactory carFactory=new CarFactory();

    public CarFactory getProxyObject(){
        //创建Enhance对象,类似jadk中的Proxy类
        Enhancer enhancer = new Enhancer();
        //设置父类的字节码对象
        enhancer.setSuperclass(CarFactory.class);
        //设置回调函数
        enhancer.setCallback(this);
        //创建代理对象
        CarFactory carFactory=(CarFactory)enhancer.create();
        return carFactory;
    }

    /**
     *
     * @param o 代理类对象
     * @param method 代理的方法
     * @param objects 代理方法参数
     * @param methodProxy 代理方法
     * @return 代理方法的返回值
     * @throws Throwable
     */
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("执行其他操作");
        method.invoke(carFactory,objects);
        return null;
    }
}

测试

public class Client {
    public static void main(String[] args) {
        ProxyFactory proxyFactory = new ProxyFactory();
        CarFactory proxyObject = proxyFactory.getProxyObject();
        System.out.println("父类是"+proxyObject.getClass().getSuperclass());
        proxyObject.sell();
        System.out.println("--------");
        proxyObject.check();
    }
}

分析

ProxyFactory类不是代理类,是代理类工厂,用来创建代理类的。

通过CGLIB实现动态代理需要创建Enhancer对象,其就相当于Proxy类。因为CGLIB代理是通过继承被代理类来实现代理的,所以要设置其父类字节码对象,也就是被代理类。此外,还需要设置一个回调函数,参数是一个函数式接口,要重写intercept()方法,就相当于JDK代理中InvocationHandler接口。这个方法有四个参数:

 @param o 代理类对象
* @param method 代理的方法
* @param objects 代理方法参数
* @param methodProxy 代理方法

在此方法中进行方法增强,当通过代理类调用代理方法时就会调用此方法。

method.invoke()方法就是执行被代理类中的方法(原方法)。

注:method.invoke()方法的第一个参数不能写成o,否则会进入死循环。

总结

CGLIB动态代理是通过继承被代理类来实现代理的,所以被代理类不用实现接口。但是需要注意的是CGLIB不能代理加了final关键字的类,因为加了final关键字的类不能被继承。

使用动态代理能够把代理的方法都集成在一个方法invoke中,即使新增方法,也不用修改代理类,扩展性好。

在很多地方都用到了代理,比如spring的aop就是通过代理实现的。鉴权也是通过代理。

关于CJLib的具体解释可查看这篇文章

CGLIB动态代理之intercept函数刨析_cglib intercept_一个默默努力的人的博客-CSDN博客

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值