Spring Boot进阶:原理、实战与面试题分析
上QQ阅读APP看书,第一时间看更新

3.2.2 CGLIB动态代理

CGLIB是一个Java字节码生成库,提供了易用的API对Java字节码进行创建和修改。我们现在尝试用CGLIB来代理前面的RealAccount类,如代码清单3-9所示。

代码清单3-9 AccountCglibProxy类代码

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

    public Object getProxy(Class<?> clazz) {
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(this);
        return enhancer.create();
    }

    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("before");
        Object object = proxy.invokeSuper(obj, args);
        System.out.println("after");
        return object;
    }
}

上述代码中的Enhancer类是CGLIB中最常用的一个类,类似于前面介绍的JDK动态代理中的Proxy类。和Proxy只能代理接口不同,Enhancer既能够代理接口,也能够代理普通类,但不能拦截final类和方法。在这里,我们实现了MethodInterceptor中的intercept()方法以提供代理逻辑。

AccountCglibProxy类的使用方法也比较简单,如代码清单3-10所示。

代码清单3-10 AccountCglibProxy类使用方法代码

AccountCglibProxy proxy = new AccountCglibProxy();
RealAccount account = (RealAccount) proxy.getProxy(RealAccount.class);
account.open();

作为对比,我们用表3-1展示了JDK动态代理和CGLIB动态代理之间的区别。

表3-1 JDK动态代理和CGLIB动态代理对比

067-1