Java CGLIB动态代理
Jakcy
Java
2021-10-28
9
原理
CGLIB代理通过Enhancer来指定要代理的目标对象、实际处理代理逻辑的对象,最终通过调用create()方法得到代理对象,对这个对象 所有非final方法 的调用都会转发给MethodInterceptor.intercept()方法,在intercept()方法里我们可以加入任何逻辑,比如修改方法参数,加入日志功能、安全检查功能等; 通过调用MethodProxy.invokeSuper()方法,将调用转发给原始对象,具体到本例,就是Hello的具体方法。CGLIG中MethodInterceptor的作用跟JDK代理中的InvocationHandler很类似,都是方法调用的中转站。
代码
package com.yixing.demo;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class Demo2 {
static class Hello {
public void say() {
System.out.println("Hello");
}
}
static class DemoProxy implements MethodInterceptor {
/**
* 根据类获取代理对象
*/
public static Hello createObject(Class<Hello> helloClass) {
Enhancer enhancer = new Enhancer();
// 设置被代理的类
enhancer.setSuperclass(helloClass);
// 设置代理类
enhancer.setCallback(new DemoProxy());
// 创建代理对象
return (Hello) enhancer.create();
}
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
try {
System.out.println(obj.getClass());
System.out.println(obj.getClass().getSuperclass());
Arrays.stream(obj.getClass().getInterfaces()).forEach(System.out::println);
System.out.println("begin method " + method.getName());
return proxy.invokeSuper(obj, args);
} finally {
System.out.println("end");
}
}
}
public static void main(String[] args) {
Hello hello = new Hello();
hello.say();
Hello hello2 = DemoProxy.createObject(Hello.class);
hello2.say();
}
}
Hello
class com.yixing.demo.Demo2$Hello$$EnhancerByCGLIB$$4454f6d7
class com.yixing.demo.Demo2$Hello
interface net.sf.cglib.proxy.Factory
begin method say
Hello
end
生成的代理类
public class Demo2$Hello$$EnhancerByCGLIB$$e3734e52
extends Demo2$Hello
implements Factory
{
...
private MethodInterceptor CGLIB$CALLBACK_0; // ~~
...
public final String say()
{
...
MethodInterceptor tmp17_14 = CGLIB$CALLBACK_0;
if (tmp17_14 != null) {
// 将请求转发给MethodInterceptor.intercept()方法。
return (String)tmp17_14.intercept(this,
CGLIB$say$0$Method,
new Object[] {},
CGLIB$say$0$Proxy);
}
return super.sayHello(paramString);
}
...
}