责任链模式

1.定义

一个对象在一条链上被多个拦截器拦截处理(当然,可能只会拦截,不会处理)的设计模式称为责任链模式。该模式是一个对象在多个角色中传递的过程。

类似于流程审批,申请单被级级审核。

2.构成

对象+拦截器

3.例子

由于责任链模式由多个拦截器组成,所以现在先让我们来撸3个拦截器:

 

/**

 * 一号拦截器

 */

public class ResponsibilityInterceptor1 implements Interceptor {

    /**

     * 作用于真实对象之前的方法

     * @param proxy 代理对象

     * @param target 真实对象(被代理对象)

     * @param method 方法对象

     * @param args 方法参数

     * @return 是否反射真实方法(true反射)

     */

    @Override

    public boolean before(Object proxy, Object target, Method method, Object[] args) {

        System.out.print("我是一号拦截器的before");

        return true;

    }

    /**

     * 用于代理真实对象的方法(before返回false时触发)

     * @param proxy 代理对象

     * @param target 真实对象(被代理对象)

     * @param method 方法对象

     * @param args 方法参数

     */

    @Override

    public void around(Object proxy, Object target, Method method, Object[] args) {

        System.out.print("我是一号拦截器的around");

    }

    /**

     * 作用于真实对象方法之后的方法

     * @param proxy 代理对象

     * @param target 真实对象(被代理对象)

     * @param method 方法对象

     * @param args 方法参数

     */

    @Override

    public void after(Object proxy, Object target, Method method, Object[] args) {

        System.out.print("我是一号拦截器的after");

    }

}

 

/**

 * 二号拦截器

 */

public class ResponsibilityInterceptor2 implements Interceptor {

    /**

     * 作用于真实对象之前的方法

     * @param proxy 代理对象

     * @param target 真实对象(被代理对象)

     * @param method 方法对象

     * @param args 方法参数

     * @return 是否反射真实方法(true反射)

     */

    @Override

    public boolean before(Object proxy, Object target, Method method, Object[] args) {

        System.out.print("我是二号拦截器的before");

        return true;

    }

    /**

     * 用于代理真实对象的方法(before返回false时触发)

     * @param proxy 代理对象

     * @param target 真实对象(被代理对象)

     * @param method 方法对象

     * @param args 方法参数

     */

    @Override

    public void around(Object proxy, Object target, Method method, Object[] args) {

        System.out.print("我是二号拦截器的around");

    }

    /**

     * 作用于真实对象方法之后的方法

     * @param proxy 代理对象

     * @param target 真实对象(被代理对象)

     * @param method 方法对象

     * @param args 方法参数

     */

    @Override

    public void after(Object proxy, Object target, Method method, Object[] args) {

        System.out.print("我是二号拦截器的after");

    }

}

 

 

/**

 * 三号拦截器

 */

public class ResponsibilityInterceptor3 implements Interceptor {

    /**

     * 作用于真实对象之前的方法

     * @param proxy 代理对象

     * @param target 真实对象(被代理对象)

     * @param method 方法对象

     * @param args 方法参数

     * @return 是否反射真实方法(true反射)

     */

    @Override

    public boolean before(Object proxy, Object target, Method method, Object[] args) {

        System.out.print("我是三号拦截器的before");

        return false;

    }

    /**

     * 用于代理真实对象的方法(before返回false时触发)

     * @param proxy 代理对象

     * @param target 真实对象(被代理对象)

     * @param method 方法对象

     * @param args 方法参数

     */

    @Override

    public void around(Object proxy, Object target, Method method, Object[] args) {

        System.out.print("我是三号拦截器的around");

    }

    /**

     * 作用于真实对象方法之后的方法

     * @param proxy 代理对象

     * @param target 真实对象(被代理对象)

     * @param method 方法对象

     * @param args 方法参数

     */

    @Override

    public void after(Object proxy, Object target, Method method, Object[] args) {

        System.out.print("我是三号拦截器的after");

    }

}

 

然后借助jdk动态代理类进行代理,详情见动态代理文章。

 

最后,撸一个测试类:

@RunWith(SpringRunner.class)

@SpringBootTest

public class ResponsibilityTest {

    /**

     * 利用之前撸好的代理类进行多个拦截器的代理

     */

    @Test

    public void responsibilityTest(){

        IProxyTest interceptor1 = (IProxyTest)InterceptorJdkProxy.bind(new ProxyTest(),"com.example.springredis.responsibility.ResponsibilityInterceptor1");

        IProxyTest interceptor2 = (IProxyTest)InterceptorJdkProxy.bind(interceptor1,"com.example.springredis.responsibility.ResponsibilityInterceptor2");

        IProxyTest interceptor3 = (IProxyTest)InterceptorJdkProxy.bind(interceptor2,"com.example.springredis.responsibility.ResponsibilityInterceptor3");

        interceptor3.sayHello();

    }

}

 

注:最初被代理的类为ProxyTest :

 

public class ProxyTest implements IProxyTest {

    @Override

    public void sayHello() {

        System.out.print("说你好!");

    }

}

 

测试类的运行结果为:

我是三号拦截器的before我是二号拦截器的before我是一号拦截器的before说你好!我是一号拦截器的after我是二号拦截器的after我是三号拦截器的after

 

由结果可以看出,每个拦截器的方法都被触发了,在拦截器的before方法被触发完了之后,触发了真实对象的方法,接着顺序触发了after方法。

 

interceptor3 为interceptor2 的代理对象,interceptor2 为interceptor1的代理对象,interceptor1为ProxyTest的代理对象。在interceptor3执行sayHello方法时,首先会进入jdk动态代理类的invoke方法:

 

/**

 * 代理类实现逻辑,在代理类执行方法时,首先会进入该方法

 * @param proxy 代理类对象

 * @param method 方法对象

 * @param args 方法传承

 * @return 方法返回对象

 * @throws Throwable

 */

@Override

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

    Object result = null;//返回结果对象

    //没有设置拦截器时,就直接反射方法

    if(interceptorClass==null){

        result = method.invoke(target,args);//通过反射调用真实对象方法

    }

    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;

}

这个方法中会因为before方法放回true而反射被代理对象的sayHello方法,这个时候,就会换成interceptor2去调用sayHello方法,所以又会进入代理类,触发代理类的invoke方法,以此类推,知道调用ProxyTest(第一个代理类)的sayHello,接着顺序调用after。这就是责任链的整个流程。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值