一. Cglib代理的原理
Cglib 的动态代理,就是子类继承父类。即:通过生成一个被代理对象的子类,然后重写父类的方法,所以目标类和方法不能声明为 final 类型,可以强制转化为被代理类(也就是自己写的类),即父类引用指向子类对象;
二. 样例代码
1. 引入依赖
需要单独引入 cglib 的第三方依赖;
<dependency>ss
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.12</version>
</dependency>
2. Cat
public class Cat {
public void eat() {
System.out.println("cat eat---");
}
public void run() {
System.out.println("cat run---");
}
}
3. MethodInterceptor
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CglibMethodInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("代理前置开始");
// 有个疑问:代理是需要获取到被代理对象的引用,但是 Cglib 好像并没有获取被代理对象的引用
// 那怎么还能用代理呢?
// 其实这里这个 object 的引用,就是由 Cglib 帮我们创建的代理对象
// object 代理对象是被代理对象的子类(继承了我们自己写的那个被代理类)
Object result = methodProxy.invokeSuper(object, args);
System.out.println("代理后置开始");
return result;
}
}
4. Test02
import net.sf.cglib.core.DebuggingClassWriter;
import net.sf.cglib.proxy.Enhancer;
public class Test02 {
public static void main(String[] args) {
// 用于生成 CGlib 代理类的字节码
// System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "d:\\IDEA\\workspace\\myMaven\\tmp");
// 1. 生成 cglib 代理类对象
// Enhancer 用于生成代理类对象
// 参数一:把父类设置为谁?这一步告诉 cglib 生成的子类需要继承哪个类
// 参数二:设置回调,使生成的代理类对象在每调用被代理类方法时,
// 都会调用 MethodInterceptor 的 intercept() 方法
Cat cat = (Cat) Enhancer.create(Cat.class, new CglibMethodInterceptor());
// 2. 执行代理类对象方法
cat.eat();
}
}
执行结果如下:
代理前置开始
cat eat---
代理后置开始