责任链模式
责任链模式
当一个对象在一条链上被多个拦截器拦截处理时,我们把这样的设计模式称为责任链模式,它用于一个对象在多个角色中传递的场景。
举一个生活中的例子来说明:一个程序员需要请一周假,如果把请假申请单看做一个对象,那么它需要经过项目经理、部门经理、人事等多个角色的审批,每个角色都有机会拦截这个申请单进行审批或者修改。这个时候就要考虑提供项目经理、部门经理和人事的处理逻辑,所以需要提供三个拦截器,而传递的则是请假申请单。
目标接口
package com.hlbdx.interceptor;
public interface IHelloWord {
//目标方法
public String sayHello(String message);
}
目标类
package com.hlbdx.interceptor;
public class HelloWordImpl implements IHelloWord {
//目标方法实现
public String sayHello(String message) {
if (message.equals("Hello")) {
return "Hello";
}
return "你好";
}
}
拦截器接口
package com.hlbdx.interceptor;
import java.lang.reflect.Method;
public interface Interceptor {
//目标方法执行前执行
public boolean before(Object proxy,Object target,Method method,Object[] args);
// beror方法返回false执行
public void around(Object proxy,Object target,Method method,Object[] args);
//目标方法执行后执行
public void after(Object proxy,Object target,Method method,Object[] args);
}
拦截器1
package com.hlbdx.interceptor;
import java.lang.reflect.Method;
public class Interceptor1 implements Interceptor {
public boolean before(Object proxy, Object target, Method method,
Object[] args) {
System.out.println("Interceptor1.before()");
return true;
}
public void around(Object proxy, Object target, Method method, Object[] args) {
System.out.println("Interceptor1.around()");
}
public void after(Object proxy, Object target, Method method, Object[] args) {
System.out.println("Interceptor1.after()");
}
}
拦截器2
package com.hlbdx.interceptor;
import java.lang.reflect.Method;
public class Interceptor2 implements Interceptor {
public boolean before(Object proxy, Object target, Method method,
Object[] args) {
System.out.println("Interceptor2.before()");
return true;
}
public void around(Object proxy, Object target, Method method, Object[] args) {
System.out.println("Interceptor2.around()");
}
public void after(Object proxy, Object target, Method method, Object[] args) {
System.out.println("Interceptor2.after()");
}
}
拦截器3
package com.hlbdx.interceptor;
import java.lang.reflect.Method;
public class Interceptor3 implements Interceptor {
public boolean before(Object proxy, Object target, Method method,
Object[] args) {
System.out.println("Interceptor3.before()");
return true;
}
public void around(Object proxy, Object target, Method method, Object[] args) {
System.out.println("Interceptor3.around()");
}
public void after(Object proxy, Object target, Method method, Object[] args) {
System.out.println("Interceptor3.after()");
}
}
动态代理类
package com.hlbdx.interceptor;
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 = null;
public InterceptorJDKProxy(Object target, String interceptorClass) {
this.target = target;
this.interceptorClass = interceptorClass;
}
public static Object bind(Object target, String interceptorClass) {
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), new InterceptorJDKProxy(
target, interceptorClass));
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// 没有设置拦截器则直接返回原有方法
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 {
// 返回false执行around方法
interceptor.around(proxy, target, method, args);
}
// 执行后置方法
interceptor.after(proxy, target, method, args);
return result;
}
}
测试类
package com.hlbdx.interceptor;
public class TestInterceptor {
public static void main(String[] args) {
String interceptorClass1 = "com.hlbdx.interceptor.Interceptor1";
String interceptorClass2 = "com.hlbdx.interceptor.Interceptor2";
String interceptorClass3 = "com.hlbdx.interceptor.Interceptor3";
//目标对象 new HelloWordImpl()
IHelloWord proxy1 = (IHelloWord) InterceptorJDKProxy.bind(
new HelloWordImpl(), interceptorClass1);
//目标对象 proxy1
IHelloWord proxy2 = (IHelloWord) InterceptorJDKProxy.bind(
proxy1, interceptorClass2);
//目标对象 proxy2
IHelloWord proxy3 = (IHelloWord) InterceptorJDKProxy.bind(
proxy2, interceptorClass3);
String result = proxy3.sayHello("Hello");
System.out.println(result);
}
}