利用ASM开源包,将真实对象类的class文件加载进来,通过修改字节码生成其子类,覆盖父类相应的方法。
备注:ASM是直接操作字节码的框架。
<dependency> <groupId>cglib</groupId> <artifactId>cglib-nodep</artifactId> <version>3.3.0</version> <scope>compile</scope> </dependency> 复制代码
package com.java24k.example.target; /** * @Description: 真实主题即被代理对象 * @Author zhoufeng * @Date 2020/7/13 2:34 * @version: V1.0 */ public class TargetClass { public void targetInfo(){ System.out.println("打印目标类信息"); } } 复制代码
package com.java24k.example.interceptor; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; /** * @Description: 代理拦截处理器 * @Author zhoufeng * @Date 2020/7/13 2:30 * @version: V1.0 */ public class MyInterceptor implements MethodInterceptor { @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("------插入前置通知代码-------------"); // 此处一定要使用proxy的invokeSuper方法来调用目标类的方法 methodProxy.invokeSuper(o, objects); System.out.println("------插入后置处理代码-------------"); return null; } } 复制代码
package com.java24k.example.test; import com.java24k.example.interceptor.MyInterceptor; import com.java24k.example.target.TargetClass; import net.sf.cglib.proxy.Enhancer; /** * @Description: 生成cglib代理测试类 * @Author zhoufeng * @Date 2020/7/13 2:41 * @version: V1.0 */ public class CglibProxyTest { public static void main(String[] args) { Enhancer enhancer = new Enhancer(); // 设置目标类 enhancer.setSuperclass(TargetClass.class); // 设置拦截器对象 enhancer.setCallback(new MyInterceptor()); // 创建子类 即代理 TargetClass targetClassProxy = (TargetClass) enhancer.create(); targetClassProxy.targetInfo(); } } 复制代码
------插入前置通知代码------------- 打印目标类信息 ------插入后置处理代码------------- Process finished with exit code 0 复制代码
在JDK动态代理中,调用目标对象的方法使用的是反射,而在CGLIB动态代理中使用的是FastClass机制。
第二节和第三节我们将剖析CGLIB生成动态代理源码和FastClass源码。