代理模式和动态代理,都是来解决增强的
代理模式
1.4个元素,被代理的接口,被代理的实现类,被代理的实现类的对象,代理类
2.代理类 实现了 被代理的 接口
3.向代理类中,传被代理的实现类
4.代理类 重写 接口的所有方法,在这些方法中,调用实现的方法,然后可以在这个
方法前后做增强
5.例子:
interface IHello{
void sayHello();
void sayGoodBye()
}
class IHelloImplement implements IHello{
void sayHello(){
sout("say hello!!!");
}
void sayGoodBye(){
sout("say goodBye!!!");
}
}
这时如果要做增强,但是不能改源代码,那么我想只能重新写一个类去实现接口
然后,将之前的实现类传过来,这样在保持之前实现类不变的情况下,可以做增强
class Proxy implements IHello{
private IHello iHello;
public void setIHello(IHello iHello){
this.iHello = iHello;
}
void sayHello(){
sout("增强");
iHello.sayHello();
}
void sayGoodBye(){
sout("增强");
iHello.sayGoodBye();
}
}
这样,我们有了这个代理类,就可以做到增强
动态代理
1.五个元素,被代理接口,被代理接口实现类,InvocationHandler实现类,Proxy类(动态创建,代理对象的)
被代理实现类的对象(传给InvocationHandler)
2.Proxy和InvocationHandler的区别
1.Proxy可以动态创建 需要被代理的实现类的对象
这个需要被代理的实现类的对象执行方法时,会调用 InvocationHandler实现类的 invoke()方法
执行的不是被代理接口实现类的方法,执行的是invoke增强的方法
3.代理模式的代理对象,就是自己创建的代理类的对象
而动态代理的代理对象,仅是,之前未被增强的 实现类的 对象
只是,这个对象在执行方法的时候,会调用Invocationhandler的invoke方法
在invoke的方法里面,我们做了增强
4.代理模式和动态代理增强的位置不同
1.代理模式:自己写的代理类,实现接口的方法的时候,做了增强
2.动态代理:InvocationHanler
接口实现类的 invoke方法做了增强
5.Invocation的实现类,可以看做代理对象,Proxy创建出来的可以看做需要被代理的实现类对象
5.动态代理的具体步骤:
1.创建InvocationHandler实例
1.创建一个需要被代理的实现类对象,传给InvocationHandler
2.这样InvocationHander属性中就有了,一个实现类对象
3.必须传,因为最后 invoke(Object object, Method method, Object[] args)
中的, method.invoke(subject, args);,subject就是来自这个对象的
2.Proxy创建 具体的动态代理对象
newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
loader: 一个ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载
一般是,传被代理实现类的 classLoader
作用:生成代理对象
interfaces: 一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,
如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),
这样我就能调用这组接口中的方法了
传之前与InvocayionHandler绑定的需要被代理的实现类对象的interfaces
作用:生成代理对象可以执行哪些方法
h: 一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上
传之前创建的handler
作用:当代理对象执行方法后,会关联InvocationHandler对象,去执行真正的invoke方法
3.可以理解需要将 handler和需要被代理的实现类对象要做一次绑定
1.而Proxy做绑定的时候,重点就是Class<?>[] interfaces, InvocationHandler h,这两个参数
interface必须传,需要被代理的实现类对象的interface
h必须传 有这个实现类对象作为属性的 invocationhandler实例
这样 Proxy返回的 才是 之前那个创建好的,需要被代理的实现类对象
执行的时候,因为绑定了,也能找到具体的 invocationHandler,执行invoke
invoke也能执行,这个需要被代理的实现类对象的方法,因为之前我的InvocationHandler里面传了它
2.这样就能理解,为什么InvocationHandler里面要有一个 需要被代理的实现类对象属性
一个InvocationHandler的 invoke方法如何增强 一个 proxy的 多个 method?
在 invoke方法里面做一个判断即可,判断method类型,多个if就可以解决
容易被忽视的,就是Proxy中的 接口方法,生成的proxy代理对象,只有在调用被代理的 接口方法的时候,才会调用invocationHandler的 invoke方法,例如拦截器的拦截规定(signature修饰的 那个对象的那个方法),生成代理对象后,只有在执行这个方法的时候,才会调用invocationHandler的 invoke方法
invocationHandler和invocation的区别
1.invocationhandler是执行具体invoke的地方
2.invocation可以保存 代理对象和方法和args,这样在invoke方法如果不在此处执行
例如interceptor中是最后传这个invocation给interceptor的intercept方法去执行
3.invocation可以保存proxy中的需要被代理的对象,以及他的 method,agrs,invoke调用其他方法后
还是可以通过invocation获得代理对象的信息,对象,方法,参数,继续执行代理对象的方法