工作实战之拦截器模式

目录

前言

一、结构中包含的角色

二、拦截器使用

1.拦截器角色

 a.自定义拦截器UserValidateInterceptor,UserUpdateInterceptor,UserEditNameInterceptor

 b.拦截器配置者UserInterceptorChainConfigure,任意组装拦截器顺序

c.拦截器管理者UserInterceptorChainManager

2.运行结果展示

a.使用代码

三、拦截器调用解说

1.项目启动,初始化bean

2.方法执行 

四、代码下载

总结


前言

拦截过滤器模式,简称拦截器模式,是责任链模式的一种衍生模式。用于对业务程序做一些预处理/后处理


一、结构中包含的角色

  1. Interceptor(抽象处理者)
  2. InterceptorChain(责任链)
  3. InterceptorChainBuilder(责任链建造者)
  4. AbstractInterceptorChainManager(链条管理者)
  5. InterceptorChainConfigure(链条配置者)

二、拦截器使用

1.拦截器角色

 a.自定义拦截器UserValidateInterceptor,UserUpdateInterceptor,UserEditNameInterceptor

/**
 * 校验用户
 * @author liangxi.zeng
 */
@Component
public class UserValidateInterceptor implements Interceptor<User> {
    /**
     * 拦截方法
     *
     * @param user
     */
    @Override
    public void interceptor(User user) {
        if(user.getAge() != 10) {
            throw new CommonException("年龄不对");
        }
        System.out.println("校验用户"+user);
    }
}

 b.拦截器配置者UserInterceptorChainConfigure,任意组装拦截器顺序

@Component
public class UserInterceptorChainConfigure
        implements InterceptorChainConfigure<User,InterceptorChainBuilder<User>> {
    /**
     * 拦截器链配置
     *
     * @param interceptorChainBuilder 拦截器链构造器
     */
    @Override
    public void configure(InterceptorChainBuilder<User> interceptorChainBuilder) {
        interceptorChainBuilder
                .pre()
                .addInterceptor(UserValidateInterceptor.class)
                .post()
                .addInterceptor(UserUpdateInterceptor.class)
                .addInterceptor(UserEditNameInterceptor.class);
    }
}

c.拦截器管理者UserInterceptorChainManager

/**
 * @author liangxi.zeng
 * 拦截器链管理类
 */
@Component
public class UserInterceptorChainManager 
extends AbstractInterceptorChainManager<User> {
    public UserInterceptorChainManager(List<Interceptor<User>> interceptorList,
                                       List<InterceptorChainConfigure<User, InterceptorChainBuilder<User>>> configureList) {
        super(interceptorList, configureList);
    }
}

2.运行结果展示

a.使用代码

/**
 * @author liangxi.zeng
 */
@RestController
@RequestMapping("/demo")
public class DemoController {

    @Autowired
    private UserInterceptorChainManager userInterceptorChainManager;

    @Autowired
    private UserService userService;

    @RequestMapping("/user")
    public String user() {
        User user = new User();
        user.setId("111");
        user.setName("liangxi");
        user.setAge(10);
        userInterceptorChainManager.doInterceptor(user,(u) -> {
            // 内部创建用户
            userService.save(user);
        });
        return "success";
    }
  
}

三、拦截器调用解说

1.项目启动,初始化bean

a.初始化责任链管理者UserInterceptorChainManager,调用父类AbstractInterceptorChainManager方法initInterceptorChain,通过责任链建造者初始化责任链

 public AbstractInterceptorChainManager(List<Interceptor<T>> interceptorList,
                                           List<InterceptorChainConfigure<T, InterceptorChainBuilder<T>>> configureList) {
        interceptorChain = initInterceptorChain(interceptorList, configureList);
        LOGGER.info("Register {} InterceptorChain, names are [{}]",interceptorList);
    }

    private InterceptorChain<T> initInterceptorChain(List<Interceptor<T>> interceptorList,
                                                                   List<InterceptorChainConfigure<T, InterceptorChainBuilder<T>>> configureList) {
        if (CollectionUtils.isEmpty(interceptorList)) {
            throw new IllegalArgumentException("Interceptors is empty.");
        }

        if (CollectionUtils.isEmpty(configureList)) {
            throw new IllegalArgumentException("Interceptor configurers is empty.");
        }

        InterceptorChainBuilder<T> builder = new InterceptorChainBuilder<>(interceptorList);

        configureList.sort(AnnotationAwareOrderComparator.INSTANCE);

        configureList.forEach(configurer -> {
            configurer.configure(builder);
        });

        return builder.performBuild();
    }

 b.责任链建造者,完成对业务方法前后逻辑的织入

public InterceptorChain performBuild() {
            List<Interceptor<T>> preInterceptors = filterInterceptor(preInterceptorList);
            List<Interceptor<T>> postInterceptors = filterInterceptor(postInterceptorList);

            if (preInterceptors.isEmpty() && postInterceptors.isEmpty()) {
                throw new IllegalStateException("Registered Pre-Interceptors and Post-Interceptors is empty.");
            }

            Consumer<T> preConsumer = (T t) -> {
            };
            Consumer<T> postConsumer = (T t) -> {
            };

            if (!preInterceptors.isEmpty()) {
                preConsumer = (T obj) -> {
                    for (Interceptor<T> item : preInterceptors) {
                        item.interceptor(obj);
                    }
                };
            }

            if (!postInterceptors.isEmpty()) {
                postConsumer = (T obj) -> {
                    for (Interceptor<T> item : postInterceptors) {
                        item.interceptor(obj);
                    }
                };
            }
            return new InterceptorChain(preConsumer,postConsumer);
    }

2.方法执行 

a.从userInterceptorChainManager.doInterceptor 到 interceptorChain.doExecute(target, operation);下面代码,完成代码逻辑

  /**
     * 拦截器调用入口,将核心操作封装成 Consumer 对象传入。
     *
     * @param target    The target to handle.
     * @param operation The core operation to intercept.
     */
    public final void doExecute(T target, Operation<T> operation) {
        preConsumer.accept(target);

        if (operation != null) {
            operation.execute(target);
        }

        postConsumer.accept(target);
    }

四、代码下载

设计模式可运行代码https://gitee.com/zenglx/design-pattern.git


总结

前后端请求,可以用现成的filter和spring的Interceptor解决,业务自己的拦截器链模式,可以解决繁琐业务重复代码的问题

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值