zoukankan      html  css  js  c++  java
  • 责任链模式

    什么是责任链模式?

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

    责任链模式步骤

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

    相当于层层代理。

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

  • 相关阅读:
    centos7下安装docker(2镜像)
    Centos7下安装docker(1)
    分享一个连接,升级内核
    zabbix图形乱码问题解决办法
    六十四:JavaScript之JavaScript的Math对象常用的方法
    六十三:JavaScript之JavaScript的String对象常用的方法
    六十二:JavaScript之JavaScript数组对象和常用的方法
    六十一:JavaScript之JavaScript函数
    六十:JavaScript之JavaScript流程控制语句
    五十九:JavaScript之JavaScript操作符
  • 原文地址:https://www.cnblogs.com/xc-xinxue/p/12373054.html
Copyright © 2011-2022 走看看