首先我们来谈谈联众代理模式的不同之处:
《1》代理类不同点:
(1)Proxy的代理类的创建是通过工具类或者工厂类自动创建的,
我们只需要调用Proxy.newProxyInstance(Loader,interfaces,h);正确的传入相应的参数,就可以得到饿哦们想要的目标类的代理类,这里对这三个参数做一下简单的介绍:Loader是目标类的类加载器,Interfaces是目标类实现的所有接口,h,是委托类对象。代码如下:
//动态生成代理对象
ISomeService someServiceImpl = (ISomeService) Proxy.newProxyInstance(
//目标类的类加载器 、
target.getClass().getClassLoader(),
//目标类实现的所有接口
target.getClass().getInterfaces(),
//代理类的委托对象
new ServiceProxyEntrust(target));
(1)Cglib的代理模式中,并没有提供现成的工具或者工厂 类让我们直接得到代理类,需要我们程序员手工定义类和方法来创建我们所需要的代理类,一般我个人喜欢把代理类的名字定义成“cglibProxy”,方法签名定义成“newProxyInstance“,
CglibProxy.newProxyInstance(target.getClass(),mi);
target是我们的目标类,mi是我们的委托类对象。我们手工定义的工厂类的需要实现这个newProxyInstance()方法,并且在这个方法的内部,我们需要借助增强器Enhancer来为我们的代理类指定目标类,并且让委托类和目标类发生联系,具体的代码实现如下:
import net.sf.cglib.proxy.MethodInterceptor;
public class CglibProxy {
//创建代理对象的过程中,我们需要借助一个类
//target:是我们的目标类
//mi:是我们的委托类对象
public static Object newProxyInstance(Class<?> target, MethodInterceptor mi) {
//增强器
Enhancer enhancer = new Enhancer();
//指定父类,即指定目标类
enhancer.setSuperclass(target);
//指定回调对象,即指定代理类
//把目标类和委托类联系在了一起
enhancer.setCallback(mi);
//创建并且返回代理对象
return enhancer.create();
}
通过这种方法,Cglib也可以一般性的创建代理类,但是我们之前说过,我们需要个性化的增强目标类,所以我们还应该让这个目标类变得不一般,这就涉及到我们要说的第二点的不同,
《2》委托类的不同
(2)Proxy 的委托类需要实现InvocationHandler接口,该接口只有一个方法,我们需要重写这个方法,
publci Object invoke(Object proxy,Method method,Object[] args);该方法的功能就是通过植入交叉逻辑代码。来达到个性化增强目标类的目的。(proxy是代理对象,method,是目标方法,args是目标方法的参数)代码如下:
/**
* proxy:代理对象
* method:目标方法
* args:目标方法的参数
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//植入交叉逻辑
SystemUtil.doTx();
//通过反射执行目标方法
Object result = method.invoke(target, args);
//植入交叉逻辑
SystemUtil.doLog();
return result;
}
(2)Cglib的委托类需要实现的接口是MethodInterceptor,然后需要重写该接口中的intercept() 方法,代码如下:
/**
* obj:代理对象
* method:目标方法
* args:目标方法的参数
* proxy:目标方法的代理对象
*/
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
//植入交叉逻辑
SystemUtil.doTx();
//通过反射执行目标方法
Object result = method.invoke(target, args);
//植入交叉逻辑
SystemUtil.doLog();
return result;
==================================================
小结:二者的不同之处在于
(1)Proxy的代理类是有工具类或者工厂类动态的生成(我们只需要调用相应的方法,然后正确的传入参数即可,具体的生成过程可以通过debug模式查看)
Cglib是没有提供相应的工具类,需要程序员手工编写,
(2)二者的委托类实现的接口不同,所以重写的的接口也不同
(3)Proxy 动态代理要求目标类必须是要实现接口的类,而Cglib的目标类可以不用实现接口(当然了实现了接口的目标类也同样可以适用,用法和没有实现接口的类似),但是Cglib的目标类是不能被final所修饰的,且必须提供无参的构造器(因为Cglib的代理类其实是目标类的子类)
============================
相同点:
(1)二者都可以在不修改目标类的源码的情况下,达到个性化增强目标类的业务逻辑功能的目的。
(2)二者的委托类虽然实现的接口和方法不同,但是这两个重写的方法的功能相同,都是通过在目标方法的前后执行交叉代码逻辑(或者是系统及服务)来达到增加目标方法的作用。