CGLIB动态代理

关键词:动态代理    CGLIB    Callback

 


关于JDK动态代理,请看《JDK动态代理》。

CGLIB动态代理的核心类是:net.sf.cglib.proxy.Enhancer,Enhancer主要完成代理对象创建的过程。


█ 相关概念

  • Callback: 声明式接口,主要利用其子接口自定义实现类完成代理对象的逻辑增强,作用相当于JDK动态代理中的InvocationHandler。
package net.sf.cglib.proxy;

public interface Callback {
}

Callback接口没有定义方法,它有如下几种子接口,在子接口中分别对应了不同的方法,以此能够使得代理对象的功能更加丰富,逻辑的增强功能更加强大。可以叫它增强器。

可以通过Enhancer提供的方法setCallback(Callback callback)或setCallbacks(Callback[] callbacks)分别指定一个或多个Callback对象。

需要注意的是一个代理对象的方法被执行时,只会有一个Callback实现逻辑会被调用。所以在使用setCallbacks(Callback[] callbacks)设置多个Callback时,还需要配合使用setCallbackFilter(CallbackFilter filter)方法来指定方法使用的是具体的哪个Callback。如果设置了多个Callback,但没有设置CallbackFilter的话,会报Multiple callback types possible but no filter specified异常。但你会说了,既然每次方法调用只能增强一个Callback逻辑,那设置多个有什么用呢?用处就在于,配合CallbackFilter来使用后,能够让不同的方法被不同的Callback来增强。比如方法1被Callback1增强,方法2被Callback2增强。

  • CallbackFilter: 当配置了多个Callback时,用于过滤出需要的某个Callback
package net.sf.cglib.proxy;

import java.lang.reflect.Method;

public interface CallbackFilter {
    int accept(Method var1);

    boolean equals(Object var1);
}

比如定义这样的实现类:

public class CallbackFilterImpl implements CallbackFilter {

    @Override
    public int accept(Method method) {
        if ("equals".equals(method.getName())) {
            return 0;
        } else if ("hashcode".equals(method.getName())){
            return 1;
        } else {
            return 2;
        }
    }

}

定义3个Callback实现类,并调用set方法设置,同时也设置CallbackFilter

Callback[] callbacks = new Callback[]{new CallBack01(), new CallBack02(), new CallBack02()};
enhancer.setCallbacks(callbacks);
enhancer.setCallbackFilter(new CallbackFilterImpl());

实现的功能:若调用代理对象的equals方法,就会使用callback数组中下标为0的Callback实现对象增强逻辑,即CallBack01。同理调用hashcode方法,就会使用数组下标为1的Callback实现类增强逻辑,即Callback02。

需要注意的是,在accept中,返回的结果是Callback数组的下标,若是不合法的数组下标就会抛出异常。比如-1。再比如上面的例子,数组中只有3个元素,若返回大于等于3以上的数字,也会抛出异常,毕竟数组中没有那么多元素。其实使用的过程中,只要数组不越界,返回的整数都是合理的。


█ 使用

Callback的子接口很多,但原理大致相同,这里以MethodInterceptor为例。

①创建接口

此步骤非必须,因为CGLIB可以直接对类生成代理。

public interface Worker {

    void work();

    String workWithResult();

    void workWithParam(int param1, String param2);

}

②创建接口实现类

public class CarWork implements Worker{

    @Override
    public void work() {
        System.out.println("CarWork work ......");
    }

    @Override
    public String workWithResult() {
        return null;
    }

    @Override
    public void workWithParam(int param1, String param2) {

    }
    
    /**
     * CarWork自定义的方法,不是继承自接口
     */
    public void custom() {
        System.out.println("CarWork method");
    }
}

③创建Callback实现类,这里使用的是Callback的一个子接口:MethodInterceptor

public class WorkerCallBack implements MethodInterceptor {
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值