什么是责任链模式?
当一个对象在一条链上被多个拦截器拦截处理(拦截器也可与选择不拦截处理它)时,我们把这样的设计模式称为责任链模式。
责任链模式步骤
1.定义拦截器接口功能
package test1; import java.lang.reflect.Method; public interface Interceptor { //代理对象 真实对象 方法 方法参数 //在真实对象前调用,返回true则反射真实对象方法;false则调用around方法 public boolean before(Object proxy,Object target,Method method,Object[] args); public void around(Object proxy,Object target,Method method,Object[] args); //反射真实对象方法或者调用around方法后调用after方法 public void after(Object proxy,Object target,Method method,Object[] args); }
2.实现多个拦截器
public class Interceptor1 implements Interceptor{ @Override public boolean before(Object proxy, Object target, Method method, Object[] args) { // TODO Auto-generated method stub System.out.println("拦截器1反射方法前逻辑"); return true; } @Override public void around(Object proxy, Object target, Method method, Object[] args) { // TODO Auto-generated method stub System.out.println("拦截器1取代了被代理对象的方法"); } @Override public void after(Object proxy, Object target, Method method, Object[] args) { // TODO Auto-generated method stub System.out.println("拦截器1反射方法后逻辑"); } } public class Interceptor2 implements Interceptor{ @Override public boolean before(Object proxy, Object target, Method method, Object[] args) { // TODO Auto-generated method stub System.out.println("拦截器2反射方法前逻辑"); return true; } @Override public void around(Object proxy, Object target, Method method, Object[] args) { // TODO Auto-generated method stub System.out.println("拦截器2取代了被代理对象的方法"); } @Override public void after(Object proxy, Object target, Method method, Object[] args) { // TODO Auto-generated method stub System.out.println("拦截器2反射方法后逻辑"); } } public class Interceptor3 implements Interceptor{ @Override public boolean before(Object proxy, Object target, Method method, Object[] args) { // TODO Auto-generated method stub System.out.println("拦截器3反射方法前逻辑"); return true; } @Override public void around(Object proxy, Object target, Method method, Object[] args) { // TODO Auto-generated method stub System.out.println("拦截器3取代了被代理对象的方法"); } @Override public void after(Object proxy, Object target, Method method, Object[] args) { // TODO Auto-generated method stub System.out.println("拦截器3反射方法后逻辑"); } }
3.使用拦截器
package test1; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class InterceptorJdkProxy implements InvocationHandler{ private Object target;//真实对象 private String interceptorClass;//拦截器全限定名 public InterceptorJdkProxy(Object target, String interceptorClass) { // TODO Auto-generated constructor stub this.target=target; this.interceptorClass=interceptorClass; } /** * 绑定委托对象并返回一个 代理占位 * @param target * @param interceptorClass * @return 代理对象占位 */ public static Object bind(Object target,String interceptorClass) { //取得代理对象 return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InterceptorJdkProxy(target,interceptorClass)); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // TODO Auto-generated method stub if(interceptorClass==null) { //没有设置拦截器则直接反射原有方法 return method.invoke(target, args); } Object result=null; //通过反射生成拦截器 Interceptor interceptor=(Interceptor)Class.forName(interceptorClass).newInstance(); //调用前值方法 if(interceptor.before(proxy,target,method,args)) { //反射原有对象方法 result=method.invoke(target, args); }else { interceptor.around(proxy,target,method,args); } //调用后置方法 interceptor.after(proxy,target,method,args); return result; } }
4.测试
public class testMultiInterceptor { public static void main(String[] args) { // TODO Auto-generated method stub HelloWorld proxy1=(HelloWorld)InterceptorJdkProxy.bind(new HelloWorldImpl(), "test2.Interceptor1"); HelloWorld proxy2=(HelloWorld)InterceptorJdkProxy.bind(proxy1, "test2.Interceptor2"); HelloWorld proxy3=(HelloWorld)InterceptorJdkProxy.bind(proxy2, "test2.Interceptor3"); proxy3.sayHelloWorld(); } }
结果:
拦截器3反射方法前逻辑
拦截器2反射方法前逻辑
拦截器1反射方法前逻辑
Hello World
拦截器1反射方法后逻辑
拦截器2反射方法后逻辑
拦截器3反射方法后逻辑
相当于层层代理。
责任链模式的优点在于我们可以在传递链上加入新的拦截器,增加拦截逻辑,缺点是会增加代理和反射,而代理和反射的性能不高。