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

    最近开始学习《Java互联网轻量级框架整合开发》第二章学习一些简单高频的设计模式,有助于后面学习SSM,其实SSM从去年就陆陆续续学过,现在也在用,但是没有完整的学习过,这次准备用两个月时间,深入研究下,这本是17年出的,存在的问题发现几个,无关大碍,看完《编程思想》在看这种书,轻松的不得了。

    说到职责链先要谈拦截器:我们在使用动态代理时,会在代理方法内(JDK是invoke();CGLIB是intercept())调用目标对象的方法用反射技术。在调目标方法前后都能写一些方法,spring中叫通知。我们可以写方法,也可以专门做一个拦截器接口,在外部传入具体的拦截器,然后在目标方法的前后进行应用,这里面可以做很多事,比如 可以根据前置通知的返回值来决定是否调用目标方法。
    职责链:多个拦截器进行工作,书中给 的例子是,好比请假条是一个对象,首先由项目经理批,然后送到部门经理批,最后到人事批。过程略抽象。

    举例

    //被代理类接口
    public interface HelloWorld {
        void sayHello();
    }
    //被代理类
    public class HelloWorldImpl implements HelloWorld {
    
        @Override
        public void sayHello() {
            // TODO Auto-generated method stub
            System.out.println("Hello World");
        }
    
    }
    //拦截器接口
    public interface Interceptor {
        //前置通知
        boolean before(Object proxy,Object target,Method method,Object[] args);
        //环绕通知
         void around(Object proxy,Object target,Method method,Object[] args);
        //z后置通知
        void after(Object proxy,Object target,Method method,Object[] args);
    }
    //拦截器实现1
    public class Interceptor1 implements Interceptor{
    
        @Override
        public boolean before(Object proxy, Object target, Method method, Object[] args) {
            System.out.println("[拦截器1]的before方法");
            return true;
        }
    
        @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("[拦截器1]的after方法");
        }
    
    }
    //拦截器实现2
    public class Interceptor2 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("");
        }
    
        @Override
        public void after(Object proxy, Object target, Method method, Object[] args) {
            System.out.println("[拦截器2]的after方法");
        }
    
    }
    //拦截器实现3
    public class Interceptor3 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("");
        }
    
        @Override
        public void after(Object proxy, Object target, Method method, Object[] args) {
            System.out.println("[拦截器3]的after方法");
        }
    
    }
    //动态代理实现类,在平常的JDK代理上,组合了拦截器对象
    public class InterceptorJdkProxy implements InvocationHandler {
        
        private Object target;//真实对象
        private Interceptor interceptor;//拦截器对象
        
        
        public InterceptorJdkProxy(Object target, Interceptor interceptor) {
            this.target = target;
            this.interceptor = interceptor;
        }
        
        public static Object bind(Object target,Interceptor interceptor) {
            return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InterceptorJdkProxy(target, interceptor));
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            Object object = null;
            // TODO Auto-generated method stub
            if (interceptor.before(proxy, target, method, args) == true) {
                object = method.invoke(target, args);
            }else {
                interceptor.around(proxy, target, method, args);
            }
            interceptor.after(proxy, target, method, args);
            return object;
        }
    
    }
    //最后 测试类
    public class Test {
        public static void main(String[] args) {
            HelloWorld proxy1 = (HelloWorld) InterceptorJdkProxy.bind(new HelloWorldImpl(), new Interceptor1());
            HelloWorld proxy2 = (HelloWorld) InterceptorJdkProxy.bind(proxy1, new Interceptor2());
            HelloWorld proxy3 = (HelloWorld) InterceptorJdkProxy.bind(proxy2, new Interceptor3());
            proxy3.sayHello();
        }
    }

    运行结果

    [拦截器3]的before方法
    [拦截器2]的before方法
    [拦截器1]的before方法
    Hello World
    [拦截器1]的after方法
    [拦截器2]的after方法
    [拦截器3]的after方法

    每个拦截器的before方法返回值,决定了是否通过本次拦截,如果被拦截住,那就不再往下传递。就好比项目经理都不批准,就不给部门经理和人事看了。

  • 相关阅读:
    rkhunter和chkrootkit
    Chkrootkit安装配置教程 – Linux后门入侵检测
    安装asterisk以及asterisk-gui
    职场最让人鄙视哪种招聘面试老板
    谷歌为何大举收购机器人公司?
    evercookie
    美科学家发现量子纠缠幽灵与宇宙虫洞有关
    Storm-YARN
    Twitter开源Summingbird:近原生编码下整合批处理与流处理
    基于keepalived的redis通信链接数测试
  • 原文地址:https://www.cnblogs.com/houj/p/11723290.html
Copyright © 2011-2022 走看看