责任链模式

什么是责任链模式?

当一个对象在一条链上被多个拦截器拦截处理(拦截器也可与选择不拦截处理它)时,我们把这样的设计模式称为责任链模式。

责任链模式步骤

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反射方法后逻辑

相当于层层代理。

责任链模式的优点在于我们可以在传递链上加入新的拦截器,增加拦截逻辑,缺点是会增加代理和反射,而代理和反射的性能不高。

原文地址:https://www.cnblogs.com/xc-xinxue/p/12373054.html