一,拦截器
程序设计者经常设计一个拦截器接口供开发者使用,开发者只要知道拦截器接口的方法,含义和作用即可,无需知道动态代理的具体实现。
接口和真实对象:
public interface DaoInterface {
public void say();
}
public class RealObject implements DaoInterface {
@Override
public void say() {
System.out.println("我是真实对象!!!!!!!");
}
}
拦截器:
before方法,在真实对象之前调用。当返回是true时,则反射真实对象的方法;当返回为false时,则调用around。
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);
public void after(Object proxy,Object target,Method method,Object[] args);
}
public class MyInterceptor implements Interceptor{
@Override
public boolean before(Object proxy, Object target, Method method, Object[] args) {
System.out.println("反射方法前的逻辑");
return false;
}
@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("反射方法后的逻辑");
}
}
JDK动态代理:
public class InterceptorJdkProxy implements InvocationHandler {
private Object target;//真实对象
private String interceptorClass = null;//拦截器全限定类名
public InterceptorJdkProxy(Object target, String interceptorClass) {
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));
}
/**
*
* @param proxy
* @param method
* @param args
* @return
* @throws Throwable
*/
@Override
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;
}
}
TestMain类:
public class TestMain {
public static void main(String[] args) {
DaoInterface realObject = (DaoInterface) InterceptorJdkProxy.bind(new RealObject(),
"Interceptor.MyInterceptor");
realObject.say();
}
}
执行流程:
二,职责链模式
1、职责链模式定义
职责链模式定义:避免请求发送者与接收者耦合在一起,让多个对象都可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。
——————《设计模式》清华大学出版社
2,模式角色
(1),Hander抽象处理者
定义一个处理请求的接口,在其中定义抽象请求处理方法。
(2),ConcreteHandler具体处理者
是抽象处理者的子类,实现了处理请求的方法。在处理前需要判断是否有处理的权限,如果有就处理,否则传给后面的处理者。
(3),Client客户类
发起请求,只关心请求返回的结果,不关心中间几个处理者处理,如何处理。
代码:(在上面的链接器上增加了几个拦截器)
public class MyInterceptor2 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("拦截器2取代了代理的方法");
}
@Override
public void after(Object proxy, Object target, Method method, Object[] args) {
System.out.println("拦截器2的after方法");
}
}
public class MyInterceptor3 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("拦截器3取代了代理的方法");
}
@Override
public void after(Object proxy, Object target, Method method, Object[] args) {
System.out.println("拦截器3的after方法");
}
}
public class TestMain {
public static void main(String[] args) {
DaoInterface proxy1 = (DaoInterface) InterceptorJdkProxy.bind(new RealObject(),
"Interceptor.MyInterceptor");
DaoInterface proxy2 = (DaoInterface)InterceptorJdkProxy.bind(proxy1,
"Interceptor.MyInterceptor2"
);
DaoInterface proxy3 = (DaoInterface)InterceptorJdkProxy.bind(proxy2,
"Interceptor.MyInterceptor3"
);
proxy3.say();
}
}
当三个拦截器的before方法都返回为true时:
就会经过一个个的拦截器到带代理所代理的真实对象的方法。
当拦截器2的before返回为false时
在拦截器2中将请求拒绝,所以就不能传递到后面去了。在职责链中将其阻断了。
3,优缺点
- 降低耦合度
- 简化对象的相互连接
- 增强给对象指派职责的灵活性
- 增加新的请求处理很方便
- 不能保证请求一定被接收到
- 对于比较长的职责链,请求涉及多个处理对象,系统性能将受到一定影响,而且在进行代码调试时不太方便。