基于MAVEN项目的CGLib动态代理原理及实现
前言
在学习spring框架时,我们会学习AOP。实现AOP的底层原理中有JDK动态代理和CGLib代理。今天我们来学习一下CGLib。
一、什么是CGLib
CGLib是一个强大的、高性能的代码生成库,它可以在运行期扩展Java类与实现Java接口。Hibernate支持它来实现PO(Persistent Object 持久化对象)字节码的动态生成。
其被广泛应用于AOP框架(Spring、dynaop)中,用以提供方法拦截操作。例如Spring AOP为他们提供方法的interception(拦截)。
CGLib采用底层的字节码技术ASM, 可以为一个类创建子类, 在子类中采用方法拦截的技术拦截所有父类方法的调用, 并织入横切逻辑。
二、实现过程
2.1导包
在pom.xml中导入cglib包
<dependencies>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
</dependencies>
2.2创建cglib代理类
代理类需要实现MethodInterceptor接口并重写intercept方法
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class MyProxy implements MethodInterceptor {
/**
*
* @param o cglib生成的代理对象
* @param method 被代理对象的方法
* @param objects 传入方法的参数
* @param methodProxy 代理的方法
* @return
* @throws Throwable
*/
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("这里可以插入执行关键代码之前的逻辑");
Object o1 = methodProxy.invokeSuper(o, objects);//关键代码:
System.out.println("这里可以插入执行关键代码之后的逻辑");
return o1;
}
}
2.3创建目标类
public class User {
public String say(String msg){
System.out.println("早上好"+msg);
return msg;
}
}
2.4编写测试类
import net.sf.cglib.core.DebuggingClassWriter;
import net.sf.cglib.proxy.Enhancer;
public class Demo {
public static void main(String[] args) {
// 代理类class文件存入本地磁盘方便我们反编译查看源码
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:\\code");
Enhancer enhancer = new Enhancer(); // 通过CGLIB动态代理获取代理对象的过程
enhancer.setSuperclass(User.class); // 设置enhancer对象的父类
enhancer.setCallback(new MyProxy()); // 设置enhancer的回调对象
User user = (User) enhancer.create(); // 创建代理对象
String world = user.say("world"); // 通过代理对象调用目标方法
System.out.println(world);
}
}
2.5运行结果
2.6创建的代理类
class文件存入本地磁盘
三、实现原理
CGLib采用底层的字节码技术ASM, 可以为一个类创建子类, 在子类中采用方法拦截的技术拦截所有父类方法的调用, 并织入横切逻辑。