最近开始学习《Java互联网轻量级框架整合开发》第二章学习一些简单高频的设计模式,有助于后面学习SSM,其实SSM从去年就陆陆续续学过,现在也在用,但是没有完整的学习过,这次准备用两个月时间,深入研究下,这本是17年出的,存在的问题发现几个,无关大碍,看完《编程思想》在看这种书,轻松的不得了。
说到职责链先要谈拦截器:我们在使用动态代理时,会在代理方法内(JDK是invoke();CGLIB是intercept())调用目标对象的方法用反射技术。在调目标方法前后都能写一些方法,spring中叫通知。我们可以写方法,也可以专门做一个拦截器接口,在外部传入具体的拦截器,然后在目标方法的前后进行应用,这里面可以做很多事,比如 可以根据前置通知的返回值来决定是否调用目标方法。
职责链:多个拦截器进行工作,书中给 的例子是,好比请假条是一个对象,首先由项目经理批,然后送到部门经理批,最后到人事批。过程略抽象。
举例
//被代理类接口 public interface HelloWorld { void sayHello(); } //被代理类 public class HelloWorldImpl implements HelloWorld { @Override public void sayHello() { // TODO Auto-generated method stub System.out.println("Hello World"); } } //拦截器接口 public interface Interceptor { //前置通知 boolean before(Object proxy,Object target,Method method,Object[] args); //环绕通知 void around(Object proxy,Object target,Method method,Object[] args); //z后置通知 void after(Object proxy,Object target,Method method,Object[] args); } //拦截器实现1 public class Interceptor1 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) { System.out.println(""); } @Override public void after(Object proxy, Object target, Method method, Object[] args) { System.out.println("[拦截器1]的after方法"); } } //拦截器实现2 public class Interceptor2 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) { System.out.println(""); } @Override public void after(Object proxy, Object target, Method method, Object[] args) { System.out.println("[拦截器2]的after方法"); } } //拦截器实现3 public class Interceptor3 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) { System.out.println(""); } @Override public void after(Object proxy, Object target, Method method, Object[] args) { System.out.println("[拦截器3]的after方法"); } } //动态代理实现类,在平常的JDK代理上,组合了拦截器对象 public class InterceptorJdkProxy implements InvocationHandler { private Object target;//真实对象 private Interceptor interceptor;//拦截器对象 public InterceptorJdkProxy(Object target, Interceptor interceptor) { this.target = target; this.interceptor = interceptor; } public static Object bind(Object target,Interceptor interceptor) { return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InterceptorJdkProxy(target, interceptor)); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object object = null; // TODO Auto-generated method stub if (interceptor.before(proxy, target, method, args) == true) { object = method.invoke(target, args); }else { interceptor.around(proxy, target, method, args); } interceptor.after(proxy, target, method, args); return object; } } //最后 测试类 public class Test { public static void main(String[] args) { HelloWorld proxy1 = (HelloWorld) InterceptorJdkProxy.bind(new HelloWorldImpl(), new Interceptor1()); HelloWorld proxy2 = (HelloWorld) InterceptorJdkProxy.bind(proxy1, new Interceptor2()); HelloWorld proxy3 = (HelloWorld) InterceptorJdkProxy.bind(proxy2, new Interceptor3()); proxy3.sayHello(); } }
运行结果
[拦截器3]的before方法
[拦截器2]的before方法
[拦截器1]的before方法
Hello World
[拦截器1]的after方法
[拦截器2]的after方法
[拦截器3]的after方法
每个拦截器的before方法返回值,决定了是否通过本次拦截,如果被拦截住,那就不再往下传递。就好比项目经理都不批准,就不给部门经理和人事看了。