前面学习了JDK的动态代理代理模式-JDK与cglib的动态代理(一),知道了被代理对象必须要实现一个接口,因为JDK动态生成的代理类需要继承Proxy用来获取InvocationHandler(Caigou)也就是代理对象,因为我们还需要执行它的invoke来实现代理方法的前置与后置操作,又因为java是单一继承关系那就只能用接口与被代理对象建立联系。
那现在就来看看cglib又是如何来实现动态代理的
cglib动态代理
这次我们不需要接口,直接上小伙伴
public class Friend {
private String name = "小伙伴";
private String adress = "火星";
private String material = "火腿肠";
public void shop(String arg) {
System.out.println("我叫" + this.name + ",我住在" + this.adress + ",我要买" + this.material);
}
}
我们的采购也就是代理必须要实现MethodInterceptor
public class Caigou implements MethodInterceptor{
//没有直接持有被代理对象的引用
public Object getInstance(Class<?> clazz) {
Enhancer eh = new Enhancer();
//指定动态生成的子类的父类
eh.setSuperclass(clazz);
//回调 相当于在jdk动态代理中newProxyInstance方法第三个参数作用
eh.setCallback(this);
return eh.create();
}
/**
* obj 动态生成的子类对象
* method 被代理对象的方法
* args 此次调用的输入参数列表
* proxy 方法的拦截
*/
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("我是采购");
proxy.invokeSuper(obj, args);
System.out.println("开始采购");
System.out.println("采购完成");
System.out.println(obj.getClass());
Class<?> class1 = obj.getClass().getSuperclass();
System.out.println("父类"+class1);
List<Class<?>> interfaces = Arrays.asList(obj.getClass().getInterfaces());
System.out.println("实现接口"+interfaces);
System.out.println(method);
System.out.println(args[0].toString());
System.out.println(proxy);
return null;
}
}
public class TestShop {
public static void main(String[] args) {
try {
Friend friend = (Friend)new Caigou().getInstance(Friend.class);
friend.shop("测试参数");
} catch (Exception e) {
e.printStackTrace();
}
}
}
我是采购
我叫小伙伴,我住在火星,我要买火腿肠
开始采购
采购完成
class com.*.proxy.cglib.Friend$$EnhancerByCGLIB$$72d00513
父类class com.*.proxy.cglib.Friend
实现接口[interface net.sf.cglib.proxy.Factory]
public void com.*.proxy.cglib.Friend.shop(java.lang.String)
测试参数
net.sf.cglib.proxy.MethodProxy@1b68ddbd
看到cglib虽然没有直接持有被代理对象的引用,但是cglib动态生成的类是继承于我们的被代理对象的,恭喜小伙伴喜当爹,也就是相当于间接持有了被代理对象的引用。这也满足了我们代理模式引用场景的三个条件了。
JDK与cglib动态代理实现区别:
-
jdk被代理对象实现顶层接口,生成类也实现顶层接口并继承Proxy
-
cglib被代理对象等着喜当爹,生成类继承被代理类并实现 Factory