CGLIB动态代理实现也是常用的实现方式,相对于JDK的只能代理接口,CGLIB的可以直接对类进行代理,功能也更多
1. 由于实现原理,需要一个类
public class OrderService {
public String add(String orderNo) {
System.out.println("add a order[orderNo=" + orderNo + "]");
// 后续测试使用
delete(orderNo);
return "success";
}
public String delete(String orderNo) {
System.out.println("delete a order[orderNo=" + orderNo + "]");
return "success";
}
}
2. InvocationHandler
这种方式和jdk的实现类似,区别在于一个是对接口代理,一个是对类代理
public class OrderInvocationHandler implements InvocationHandler {
private Object target;
public OrderInvocationHandler(Object target) {
super();
this.target = target;
}
/**
* proxy: OrderService$$EnhancerByCGLIB$$47a95d3e
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("method call before ...");
// 这样写会造成循环调用
// Object result = method.invoke(proxy, args);
Object result = method.invoke(target, args);
System.out.println("method call after ...");
return result;
}
}
2.1 测试
public static void main(String[] args) {
// System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:/BaiduNetdiskDownload/java-sample");
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(OrderService.class);
// 自定义InvocationHandler
enhancer.setCallback(new OrderInvocationHandler(new OrderService()));
// OrderService$$EnhancerByCGLIB$$47a95d3e
OrderService orderService = (OrderService) enhancer.create();
System.out.println(orderService.add("111"));
}
输出:
method call before ...
add a order[orderNo=111]
method call after ...
success
2.2 代理类源码(部分)
public class OrderService$$EnhancerByCGLIB$$47a95d3e extends OrderService implements Factory {
private InvocationHandler CGLIB$CALLBACK_0;
private static final Method CGLIB$add$0;
static void CGLIB$STATICHOOK1() {
CGLIB$add$0 = Class.forName("com.core.proxy.cglib.OrderService").getDeclaredMethod("add",
Class.forName("java.lang.String"));
}
public final String add(String var1) {
try {
// 此处CGLIB$CALLBACK_0其实就是OrderInvocationHandler实例
InvocationHandler var10000 = this.CGLIB$CALLBACK_0;
return (String) var10000.invoke(this, CGLIB$add$0, new Object[]{var1});
} catch (Error | RuntimeException var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
static {
CGLIB$STATICHOOK1();
}
3. MethodInterceptor
这种方法可以实现和上面方法同样的功能,唯一区别在于当对代理类(obj)调用invokeSuper方法时,如果出现方法调用(add方法调用delete方法),日志会嵌套打印
public class OrderMethodInterceptor implements MethodInterceptor {
private Object target;
public OrderMethodInterceptor(Object target) {
super();
this.target = target;
}
/**
* obj com.core.proxy.cglib.OrderService$$EnhancerByCGLIB$$b4cc9f16@b7dd107
* method public java.lang.String com.core.proxy.cglib.OrderService.add(java.lang.String)
* proxy net.sf.cglib.proxy.MethodProxy@42eca56e
* createInfo
* c1 com.core.proxy.cglib.OrderService
* c2 com.core.proxy.cglib.OrderService$$EnhancerByCGLIB$$b4cc9f16
* FastClassInfo
* f1 OrderService$$FastClassByCGLIB$$9ef31016
* type=com.core.proxy.cglib.OrderService
* f2 OrderService$$EnhancerByCGLIB$$b4cc9f16$$FastClassByCGLIB$$c22a6914
* type=OrderService$$EnhancerByCGLIB$$b4cc9f16
* i1 0(add)
* i2 18(CGLIB$add$0)
*/
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("cglib method before...");
// 对于嵌套函数调用会多次输出日志信息
// Object result = proxy.invokeSuper(obj, args);
// 这样会出现死循环
// Object result = proxy.invoke(obj, args);
Object result;
if (null != target) {
// 嵌套方法不会多次输出日志信息(目前还想不到其它的应用场景)
// f1.i1()
result = proxy.invoke(target, args);
} else {
// f2.i2()
result = proxy.invokeSuper(obj, args);
}
System.out.println("cglib method after...");
return result;
}
}
3.1 测试
public static void main(String[] args) {
// System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:/BaiduNetdiskDownload/java-sample");
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(OrderService.class);
// 自定义MethodInterceptor
enhancer.setCallback(new OrderMethodInterceptor(new OrderService()));
// OrderService$$EnhancerByCGLIB$$47a95d3e
OrderService orderService = (OrderService) enhancer.create();
System.out.println(orderService.add("111"));
}
输出:
cglib method before...
add a order[orderNo=111]
cglib method after...
success
3.2 代理类源码(部分)
public class OrderService$$EnhancerByCGLIB$$b4cc9f16 extends OrderService implements Factory {
private static final Method CGLIB$add$0$Method;
private static final MethodProxy CGLIB$add$0$Proxy;
static void CGLIB$STATICHOOK1() {
Class var0 = Class.forName("com.core.proxy.cglib.OrderService$$EnhancerByCGLIB$$b4cc9f16");
var10000 = ReflectUtils.findMethods(
new String[]{"add", "(Ljava/lang/String;)Ljava/lang/String;", "delete",
"(Ljava/lang/String;)Ljava/lang/String;"},
(var1 = Class.forName("com.core.proxy.cglib.OrderService")).getDeclaredMethods());
CGLIB$add$0$Method = var10000[0];
CGLIB$add$0$Proxy = MethodProxy.create(var1, var0, "(Ljava/lang/String;)Ljava/lang/String;", "add",
"CGLIB$add$0");
}
// 调用父类方法
final String CGLIB$add$0(String var1) {
return super.add(var1);
}
// 被重写的方法
public final String add(String var1) {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
/**
* 参数说明:
* var10000: OrderMethodInterceptor实例
* CGLIB$add$0$Method: add方法
* CGLIB$add$0$Proxy: MethodProxy实例,根据上面定义可知:
* c1是OrderService类,最后转化为MethodProxy.invoke方法中的FastClassInfo.f1
* c2是OrderService$$EnhancerByCGLIB$$b4cc9f16类,最后转化为MethodProxy.invokeSuper方法中的FastClassInfo.f2
* sig1是add方法,最后转化为MethodProxy.invoke方法中的FastClassInfo.i1
* sig2是CGLIB$add$0方法,最后转化为MethodProxy.invokeSuper方法中的FastClassInfo.i2
* 根据参数也就可以明白为什么通常我们使用的都是proxy.invokeSuper(obj, args)方法,而proxy.invoke(obj, args)会出现循环调用的问题
* */
return var10000 != null
? (String) var10000.intercept(this, CGLIB$add$0$Method, new Object[]{var1}, CGLIB$add$0$Proxy)
: super.add(var1);
}
static {
CGLIB$STATICHOOK1();
}
}
4. FixedValue
这种方法用于对所有被代理方法(add或delete)都返回固定值(hello cglib),注意传入的参数会被屏蔽掉,返回值类型要相同,不然会抛类型转换错误异常,比如该例中固定返回值是String类型,调用hashCode(返回值是int)方法会抛异常
public class FixedValueInterceptor implements FixedValue {
@Override
public Object loadObject() throws Exception {
return "hello cglib";
}
}
4.1 测试
public static void main(String[] args) {
// System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:/BaiduNetdiskDownload/java-sample");
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(OrderService.class);
// 对拦截的所有方法都返回相同返回值
enhancer.setCallback(new FixedValueInterceptor());
// OrderService$$EnhancerByCGLIB$$47a95d3e
OrderService orderService = (OrderService) enhancer.create();
System.out.println(orderService.add("111"));
System.out.println(orderService.hashCode());
}
输出:
hello cglib
Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number
at com.core.proxy.cglib.OrderService$$EnhancerByCGLIB$$c555ee0d.hashCode(<generated>)
at com.core.proxy.cglib.Test.main(Test.java:41)
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8
4.2 代理类源码(部分)
public class OrderService$$EnhancerByCGLIB$$c555ee0d extends OrderService implements Factory {
// 此处CGLIB$CALLBACK_0就是FixedValueInterceptor实例
private FixedValue CGLIB$CALLBACK_0;
// 方法被重写
public final String add(String var1) {
FixedValue var10000 = this.CGLIB$CALLBACK_0;
return (String) var10000.loadObject();
}
public final int hashCode() {
FixedValue var10000 = this.CGLIB$CALLBACK_0;
Object var1 = var10000.loadObject();
// 此处有类型转换,String类型转换为int类型会抛异常
return var1 == null ? 0 : ((Number) var1).intValue();
}
}
5. CallbackHelper
这种方式可以对不同的方法使用不同的CallBack处理,例如本例中对不是Object类中且方法返回值是String类型(add或delete)的方法用FixedValueInterceptor(返回固定值)处理,其它(比如hashCode)用NoOp(不做任何处理)
@SuppressWarnings("rawtypes")
public class OrderCallbackHelper extends CallbackHelper {
public OrderCallbackHelper(Class superclass, Class[] interfaces) {
super(superclass, interfaces);
}
@Override
protected Object getCallback(Method method) {
if (method.getDeclaringClass() != Object.class && method.getReturnType() == String.class) {
return new FixedValueInterceptor();
}
return NoOp.INSTANCE;
}
}
5.1 测试
public static void main(String[] args) {
// System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:/BaiduNetdiskDownload/java-sample");
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(OrderService.class);
// 根据不用方法采取不同的处理
OrderCallbackHelper callbackHelper = new OrderCallbackHelper(OrderService.class, OrderService.class.getInterfaces());
enhancer.setCallbackFilter(callbackHelper);
enhancer.setCallbacks(callbackHelper.getCallbacks());
// OrderService$$EnhancerByCGLIB$$47a95d3e
OrderService orderService = (OrderService) enhancer.create();
System.out.println(orderService.add("111"));
System.out.println(orderService.hashCode());
}
输出:
hello cglib
1343441044
5.2 代理类源码(部分)
public class OrderService$$EnhancerByCGLIB$$b3f5ea2d extends OrderService implements Factory {
// FixedValueInterceptor实例
private FixedValue CGLIB$CALLBACK_0;
// FixedValueInterceptor实例
private FixedValue CGLIB$CALLBACK_1;
private NoOp CGLIB$CALLBACK_2;
private NoOp CGLIB$CALLBACK_3;
private NoOp CGLIB$CALLBACK_4;
private NoOp CGLIB$CALLBACK_5;
// 该方法会被FixedValueInterceptor处理
public final String add(String var1) {
FixedValue var10000 = this.CGLIB$CALLBACK_0;
return (String) var10000.loadObject();
}
// 该方法会被FixedValueInterceptor处理
public final String delete(String var1) {
FixedValue var10000 = this.CGLIB$CALLBACK_1;
return (String) var10000.loadObject();
}
// 其它方法(例如hashCode,toString)由于会被NoOp处理,又因为NoOp不会做任何处理,所有方法不会被重写
}
6. LazyLoader
这种方式用来懒加载一些比较耗资源的对象(new OrderService()),所谓懒加载有两层含义(a.用到时才创建对象,b.只加载一次),本例中,loadObject方法只有在第一次方法(比如add)调用时才调用,第二次调用时不会再调用loadObject方法,会复用上次的返回值
public class OrderLazyLoader implements LazyLoader {
@Override
public Object loadObject() throws Exception {
System.out.println("cglib load object.");
// 对于一些比较耗资源的对象实例化可以在这里使用懒加载
OrderService target = new OrderService();
return target;
}
}
6.1 测试
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(OrderService.class);
// 自定义LazyLoader
enhancer.setCallback(new OrderLazyLoader());
// OrderService$$EnhancerByCGLIB$$47a95d3e
OrderService orderService = (OrderService) enhancer.create();
System.out.println(orderService.add("111"));
}
输出:
cglib load object.
add a order[orderNo=111]
success
6.2 代理类源码(部分)
public class OrderService$$EnhancerByCGLIB$$b1fa87cb extends OrderService implements Factory {
// OrderLazyLoader实例
private LazyLoader CGLIB$CALLBACK_0;
// loadObject()方法返回的实例(OrderService)
private Object CGLIB$LAZY_LOADER_0;
public final String add(String var1) {
return ((OrderService) this.CGLIB$LOAD_PRIVATE_0()).add(var1);
}
private final synchronized Object CGLIB$LOAD_PRIVATE_0() {
Object var10000 = this.CGLIB$LAZY_LOADER_0;
// 第一次会加载,后面不会再次加载
if (this.CGLIB$LAZY_LOADER_0 == null) {
LazyLoader var10001 = this.CGLIB$CALLBACK_0;
if (this.CGLIB$CALLBACK_0 == null) {
CGLIB$BIND_CALLBACKS(this);
var10001 = this.CGLIB$CALLBACK_0;
}
// 获取OrderService实例
var10000 = this.CGLIB$LAZY_LOADER_0 = var10001.loadObject();
}
return var10000;
}
}
7. Dispatcher
这种方式和LazyLoader类似,只是每次方法调用loadObject方法都会调用一次,其实只是起到了转发的作用,表面上是调用代理类的方法(add/delete),实际上最终的实例对象是由loadObject方法返回的
public class OrderDispatcher implements Dispatcher {
@Override
public Object loadObject() throws Exception {
System.out.println("cglib dispatcher.");
OrderService target = new OrderService();
return target;
}
}
7.1 测试
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(OrderService.class);
// 自定义LazyLoader
enhancer.setCallback(new OrderDispatcher());
// OrderService$$EnhancerByCGLIB$$47a95d3e
OrderService orderService = (OrderService) enhancer.create();
System.out.println(orderService.add("111"));
System.out.println(orderService.delete("222"));
}
输出:
cglib dispatcher.
add a order[orderNo=111]
success
cglib dispatcher.
delete a order[orderNo=222]
success
7.2 代理类源码(部分)
public class OrderService$$EnhancerByCGLIB$$c961763b extends OrderService implements Factory {
// OrderDispatcher实例
private Dispatcher CGLIB$CALLBACK_0;
public final String add(String var1) {
Dispatcher var10000 = this.CGLIB$CALLBACK_0;
if (this.CGLIB$CALLBACK_0 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
}
return ((OrderService) var10000.loadObject()).add(var1);
}
public final String delete(String var1) {
Dispatcher var10000 = this.CGLIB$CALLBACK_0;
if (this.CGLIB$CALLBACK_0 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
}
return ((OrderService) var10000.loadObject()).delete(var1);
}
}
8. ProxyRefDispatcher
和Dispatcher类似,只是loadObject方法传入了OrderService代理类的实例,暂时还没遇到应用场景
public class OrderProxyRefDispatcher implements ProxyRefDispatcher {
/**
* proxy OrderService$$EnhancerByCGLIB$$9e3fb6d8
*/
@Override
public Object loadObject(Object proxy) throws Exception {
System.out.println("cglib ProxyRefDispatcher.");
OrderService target = new OrderService();
return target;
}
}
8.1 测试
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(OrderService.class);
// 自定义ProxyRefDispatcher
enhancer.setCallback(new OrderProxyRefDispatcher());
// OrderService$$EnhancerByCGLIB$$47a95d3e
OrderService orderService = (OrderService) enhancer.create();
System.out.println(orderService.add("111"));
System.out.println(orderService.delete("222"));
}
输出:
cglib ProxyRefDispatcher.
add a order[orderNo=111]
success
cglib ProxyRefDispatcher.
delete a order[orderNo=222]
success
8.2 代理类源码(部分)
public class OrderService$$EnhancerByCGLIB$$9e3fb6d8 extends OrderService implements Factory {
// OrderProxyRefDispatcher实例
private ProxyRefDispatcher CGLIB$CALLBACK_0;
public final String add(String var1) {
ProxyRefDispatcher var10000 = this.CGLIB$CALLBACK_0;
if (this.CGLIB$CALLBACK_0 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
}
return ((OrderService) var10000.loadObject(this)).add(var1);
}
public final String delete(String var1) {
ProxyRefDispatcher var10000 = this.CGLIB$CALLBACK_0;
if (this.CGLIB$CALLBACK_0 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
}
return ((OrderService) var10000.loadObject(this)).delete(var1);
}
}