使用 CGLIB 生成动态代理,首先需要生成 Enhancer 类实例,并指定用于处理代理业务的回调类。
在 Enhancer.create() 方法中,会使用 DefaultGeneratorStrategy.Generate() 方法生成动态代理类的字节码,
并保存在 byte 数组中。接着使用 ReflectUtils.defineClass() 方法,通过反射,调用 ClassLoader.defineClass() 方法,
将字节码装载到 ClassLoader 中,完成类的加载。最后使用 ReflectUtils.newInstance() 方法,通过反射,生成动态类的实例,
并返回该实例。基本流程是根据指定的回调类生成 Class 字节码—通过 defineClass() 将字节码定义为类—使用反射机制生成该类的实例。
真实主题:
public class Cglib { void todo(){ System.out.println("todo someThing...."); } }
代理类:
package com.infinitePossibilities.aop_proxy.cglibProxy; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; import java.lang.reflect.Method; public class CglibProxy implements MethodInterceptor { Object getCglibProxyInstance(){ Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(Cglib.class); enhancer.setCallback(this); return enhancer.create(); } @Override public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { System.out.println("Before....."); methodProxy.invokeSuper(object,args); System.out.println("After....."); return null; } }
测试:
package com.infinitePossibilities.aop_proxy.cglibProxy; public class Test { /** * 优点: * * CGLIB通过继承的方式进行代理、无论目标对象没有没实现接口都可以代理,弥补了JDK动态代理的缺陷。 * * 缺点: * * CGLib创建的动态代理对象性能比JDK创建的动态代理对象的性能高不少,但是CGLib在创建代理对象时 * * 所花费的时间却比JDK多得多,所以对于单例的对象,因为无需频繁创建对象,用CGLib合适, * * 反之,使用JDK方式要更为合适一些。 * * 由于CGLib由于是采用动态创建子类的方法,对于final方法,无法进行代理。 * */ public static void main(String[] args) { CglibProxy cglibProxy = new CglibProxy(); Cglib cglib = (Cglib) cglibProxy.getCglibProxyInstance(); cglib.todo(); } }