cglib proxy

文章目录


动态代理常用有三: JDK代理, cglib代理, javaassistant代理. 这里demo一下 cglib代理…

cglib 是 jdk代理的补充, 最大的区别在于能够针对一个无接口的类实现代理.
本质是针对被代理类生成一个功能增强的子类. 因此, private 方法, final类,都是不能被代理的.

来看demo:

public class CglibProxy implements MethodInterceptor {
    private Enhancer enhancer = new Enhancer();

    /**
     * All generated proxied methods call this method instead of the original method.
     * The original method may either be invoked by normal reflection using the Method object,
     * or by using the MethodProxy (faster).
     *
     * @param obj    "this", the enhanced object
     * @param method intercepted Method
     * @param args   argument array; primitive types are wrapped
     * @param proxy  used to invoke super (non-intercepted method); may be called
     *               as many times as needed
     **/
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("I am before method invocation" + this.getClass().getName());
        Object result = proxy.invokeSuper(obj, args);
        System.out.println("I am after method invocation" + this.getClass().getName());
        return result;
    }

    public Object getProxy(Class clazz) {
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(this);// 设置cb对象, 就是这个 MethodInterceptor
        return enhancer.create();// 通过bytecode技术动态创建子类实例
    }
}

class CglibProxyTest {
    public static void main(String[] args) {
        CglibProxy cglibProxy = new CglibProxy();
        CglibProxyTest proxy = (CglibProxyTest) cglibProxy.getProxy(CglibProxyTest.class);
        String method = proxy.method("1024");
        System.out.println(method);
    }

    public String method(String str) {
        System.out.println(str);
        return "CglibProxyTest.method : " + str;
    }
}

使用cglib代理, 关键需要理解这里的 MethodInterceptor.intercept方法的各个参数. MethodInterceptor是对被代理类的方法的增强.

Enhancer就是代理类的生成器,它的java doc有这么一段话:

The original and most general callback type is the MethodInterceptor, which in AOP terms enables “around advice”–that is, you can invoke custom code both before and after the invocation of the “super” method. In addition you can modify the arguments before calling the super method, or not call it at all.
Although MethodInterceptor is generic enough to meet any interception need, it is often overkill. For simplicity and performance, additional specialized callback types, such as LazyLoader are also available. Often a single callback will be used per enhanced class, but you can control which callback is used on a per-method basis with a CallbackFilter.
The most common uses of this class are embodied in the static helper methods. For advanced needs, such as customizing the ClassLoader to use, you should create a new instance of Enhancer. Other classes within CGLIB follow a similar pattern.

这段话指出了三点:

  1. MethodInterceptor 就是方法拦截器, 类似AOP中的around advice
  2. MethodInterceptor用起来不爽的话,还有 LazyLoader这些Enhancer的子类可以使用; 同时还有 CallbackFilter来控制什么 方法需要代理,什么不需要.这个特性很有用, 当我们去代理一个类,未必希望所有方法都被拦截.
  3. Enhancer在静态工具方法中用得多. 但不同Classloader,应该有自己的 Enhancer.
    另外:
    上面的demo ,在 getProxy()方法中,我们直接 给 Enhancer 设置了多个属性,但多线程的情况下,未必能正常跑.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值