设计模式之——拦截器模式

拦截器模式应用非常广泛,适用场景一般在框架代码中的固定业务逻辑,这部分逻辑通常不会变化,比如:服务调用的拦截处理,拦截服务的参数,参数国际化处理,拦截服务的异常,记录服务的调用结果等等。

之所以要讲这个,是因为后面讲SpringAOP的时候会参考到!

拦截器模式有三个重要的元素:调度器,拦截器,业务逻辑,只要充分理解这三个元素,拦截器模式就很简单了。

设计模式之——拦截器模式_第1张图片

  • 调度器

一个业务逻辑可以有N个拦截器,这些拦截器是怎么运行的,自然是需要有一个调度器从中调度。

  • 拦截器

拦截器就只是负责拦截业务代码,在业务代码前后做一些操作,至于拦截器和业务代码的关系,拦截器不会直接调用业务代码,因为会耦合,拦截器在处理完自己的逻辑,会通知调度器,由调度器负责后续的操作,是继续拦截,还是调用业务逻辑。

  • 业务逻辑

业务代码这一块没啥好说的。

 

举个代码最少的例子,业务场景:服务调用,拦截服务调用记录日志,以及做异常处理。

既然有两个拦截器,自然要有一个拦截器接口。

1、拦截器接口

public interface Interceptor {
    void before(Invocation invocation);

    String intercept(Invocation invocation);

    void after(Invocation invocation);
}

2、日志拦截器

public class LogInterceptor implements Interceptor {

    @Override
    public void before(Invocation invocation) {
        System.out.println("LogInterceptor before...");
    }

    @Override
    public String intercept(Invocation invocation) {
        this.before(invocation);
        invocation.invoke();
        this.after(invocation);
        return null;
    }

    @Override
    public void after(Invocation invocation) {
        System.out.println("LogInterceptor after...");
    }
}

3,异常拦截器

public class ExceptionInterceptor implements Interceptor {

    @Override
    public void before(Invocation invocation) {
        System.out.println("ExceptionInterceptor before...");
    }

    @Override
    public String intercept(Invocation invocation) {
        this.before(invocation);
        // 实际代码应该是try catch,在catch中做事情
        invocation.invoke();
        this.after(invocation);
        return null;
    }

    @Override
    public void after(Invocation invocation) {
        System.out.println("ExceptionInterceptor after...");
    }
}

4、调度器代码

public class Invocation {
    int index = 0;
    // 调度器管理业务
    private BusinessService bs;
    // 调度器管理拦截器List
    private List interceptions = new ArrayList();
    
    public Invocation() {
        interceptions.add(new LogInterceptor());
        interceptions.add(new ExceptionInterceptor());
    }
    
    public void invoke() {
        if (index == interceptions.size()) {
            bs.perform();
        }
        else {
            Interceptor interceptor = interceptions.get(index);
            index++;
            interceptor.intercept(this); // 传this(调度器)用于回调
        }
    }
    
    public void setBusinessService(BusinessService bs) {
        this.bs = bs;
    }
}

5、业务代码

public class BusinessService {

    public void perform() {
        System.out.println("服务调用。。。");
    }
}

6,测试方法

    public static void main(String[] args) {
        Invocation invocation = new Invocation(); // 直接在构造里面就把两个拦截器加上
        invocation.setBusinessService(new BusinessService()); // 加上业务逻辑

        invocation.invoke();
    }

输出结果:

LogInterceptor before...
ExceptionInterceptor before...
服务调用。。。
ExceptionInterceptor after...
LogInterceptor after...

 

你可能感兴趣的:(设计模式,设计模式,拦截器,java)