这是一种带限制的动态代理,因为bind方法的传入参数,不仅有真实对象,还多了第二参数拦截器名字符串。
动态代理类的invoke方法中,加入拦截器的逻辑,代理类的invoke逻辑图如下:其中第二参数的拦截器中的before函数的返回值,就是下图中的true或false
这里原来的方法,指的就是JDK动态代理invoke原本执行的真实对象类的方法;
注意,代理类的invoke方法,书这里有一个返回值result,更加标准的使用反射。(因为方法总可能有返回值的,虽然这里真实方法sayHelloWorld是void的)
————————————————————————————————————————————————————————————————————
下面是书的截图:
多拦截器嵌套代理(责任链模式):
what is 责任链模式?
我前面的文章介绍过动态代理模式,该模式设计者只需要向开发者暴露拦截器即可。当有多个拦截器时,就衍生出了责任链。
什么是责任链?比如请假流程:请假单看成对象,你要请假需要经过开发经理、部门经理、人事部门负责人等多个环节,每个环节的人都可以拦截你的请假申请单进行修改或审批,这里把每个环节都看成拦截器的话,总共有三个拦截器。
一个对象在一条链上被多个拦截器处理的模式就是责任链模式,主要用于一个对象在多个角色中传递的场景。
责任链模式一般通过层层代理来实现,也就是说它建立在代理模式的基础上。层代理是什么意思?比如上面的请假流程,开发经理是动态代理1,部门经理是在开发经理动态代理1的基础上生成的动态代理2,人事部门则是在动态代理2基础上生成的动态代理3。
二、拦截器的实现
拦截器1:
public class Iterceptor1 implements Interceptor{
@Override
public boolean before(Object proxy, Object target, Method method, Object[] args) {
System.out.println("拦截器 1 的before()方法");
return true;
}
@Override
public void around(Object proxy, Object target, Method method, Object[] args) {
}
@Override
public void after(Object proxy, Object target, Method method, Object[] args) {
System.out.println("拦截器 1 的after()方法");
}
}
拦截器2:
public class Iterceptor2 implements Interceptor{
@Override
public boolean before(Object proxy, Object target, Method method, Object[] args) {
System.out.println("拦截器 2 的before()方法");
return true;
}
@Override
public void around(Object proxy, Object target, Method method, Object[] args) {
}
@Override
public void after(Object proxy, Object target, Method method, Object[] args) {
System.out.println("拦截器 2 的after()方法");
}
}
拦截器3:
public class Iterceptor3 implements Interceptor{
@Override
public boolean before(Object proxy, Object target, Method method, Object[] args) {
System.out.println("拦截器 3 的before()方法");
return true;
}
@Override
public void around(Object proxy, Object target, Method method, Object[] args) {
}
@Override
public void after(Object proxy, Object target, Method method, Object[] args) {
System.out.println("拦截器 3 的after()方法");
}
}
测试类:这里的getProxy方法,就和书中的bind方法一样。注意,是嵌套传入的参数,对象只有new出的一个
FuGuiWang类,是接口BuyHouse的一个实现类,其中有真实目标方法pay();
public class DemoTest {
public static void main(String[] args) {
BuyHouse proxy1 = (BuyHouse) JDKProxy.getProxy(new FuGuiWang(), "com.wo.domain.proxy.interceptor.Iterceptor1");
BuyHouse proxy2 = (BuyHouse) JDKProxy.getProxy(proxy1, "com.wo.domain.proxy.interceptor.Iterceptor2");
BuyHouse proxy3 = (BuyHouse) JDKProxy.getProxy(proxy2, "com.wo.domain.proxy.interceptor.Iterceptor3");
proxy3.pay(); //到这里才真的开始执行proxy3对应的代理对象中的invoke,像是递归。
}
}
注意执行顺序,before是最后到最前,after是最前到最后。
责任链模式的好处是我们可以在传递链上加上新的拦截器,增加拦截逻辑,很方便实现额外功能,当然缺点也很明,就是或增加反射和代理影响效率。