拦截器和职责链模式

一,拦截器

程序设计者经常设计一个拦截器接口供开发者使用,开发者只要知道拦截器接口的方法,含义和作用即可,无需知道动态代理的具体实现。
接口和真实对象:

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,优缺点

  • 降低耦合度
  • 简化对象的相互连接
  • 增强给对象指派职责的灵活性
  • 增加新的请求处理很方便
  • 不能保证请求一定被接收到
  • 对于比较长的职责链,请求涉及多个处理对象,系统性能将受到一定影响,而且在进行代码调试时不太方便。
发布了28 篇原创文章 · 获赞 9 · 访问量 3070

猜你喜欢

转载自blog.csdn.net/H1517043456/article/details/103317519
今日推荐