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方法返回值,决定了是否通过本次拦截,如果被拦截住,那就不再往下传递。就好比项目经理都不批准,就不给部门经理和人事看了。

  • 相关阅读:
    软件测试工程师linux十大场景命令使用
    用yum安装软件显示错误:cannot find a valid baseurl for repo: base
    Redis安装、启动与多端口配置
    Linux vi编辑器
    cookie 和session、三种保持登陆会话的方式
    服务器内存溢出问题
    selenium多窗口切换
    Turtle库的学习积累
    高频ES6
    事件冒泡和捕获的执行顺序
  • 原文地址:https://www.cnblogs.com/houj/p/11723290.html
Copyright © 2011-2022 走看看