职责链模式

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

posted @ 2019-10-22 23:03  侯上进  阅读(171)  评论(0编辑  收藏  举报