apache common-chain 是对责任链模式的简单实现

责任链模式是一种对象的行为模式。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。

项目结构:

拦截器需要实现Command接口

基于 Spring 实现拦截器动态变更

import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.apache.commons.chain.Command;import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;/*** @author N3verL4nd* @date 2022/3/1*/
@Component
@Slf4j
public class FilterContext implements ApplicationContextAware {private ApplicationContext applicationContext;/*** beanName<->Command 映射*/private Map<String, Command> commandMap;private volatile Map<String, List<Command>> commandFilters;/*** 用户身份校验拦截器*/private HashMap<String, ArrayList<String>> commandFilterConfig;/*** 配置变更回调* 此处可基于 Apollo Disconf 实现*/private void listener(ConfigUpdateEvent configEvent) {log.info("FilterContext 配置变更, key: {}, oldValue: {}, newValue: {}",configEvent.getKey(), configEvent.getOldValue(), configEvent.getNewValue());loadCommandFilters();}@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext = applicationContext;commandMap = applicationContext.getBeansOfType(Command.class);log.info("FilterContext commandMap 初始化完成, {}", commandMap);}/*** 根据 spring beanName 获取相应的 Command* @param beanName* @return*/public Command getCommand(String beanName) {if (commandMap != null) {return commandMap.get(beanName);}return null;}/*** 根据 spring beanName 获取相应的 Command* @param beanNames* @return*/public List<Command> getCommand(String... beanNames) {List<Command> result = new ArrayList<>();if (beanNames != null) {for (String beanName : beanNames) {Command command = commandMap.get(beanName);if (command != null) {result.add(command);}}}return result;}private void loadCommandFilters() {commandFilters = Maps.newConcurrentMap();for (Map.Entry<String, ArrayList<String>> entry : commandFilterConfig.entrySet()) {List<Command> commands = new ArrayList<>();ArrayList<String> beanNames = entry.getValue();if (CollectionUtils.isNotEmpty(beanNames)) {for (String beanName : beanNames) {Command command = commandMap.get(beanName);if (command != null) {commands.add(command);}}}commandFilters.put(entry.getKey(), commands);}}public List<Command> getCommands(String key) {if (commandFilters == null) {log.info("FilterContext commandFilters 首次初始化: {}", commandFilters);loadCommandFilters();}return commandFilters.get(key);}
}

使用

            ChainBase base = new ChainBase();List<Command> commands = filterContext.getCommands(NewUserFilterTypeEnum.ACTIVITY_DETAIL_LOGIN.getType());if (CollectionUtils.isNotEmpty(commands)) {for (Command command : commands) {base.addCommand(command);}}if (CollectionUtils.isNotEmpty(commands)) {ContextBase contextBase = new ContextBase();contextBase.put("userId", userId);contextBase.put("openId", request.getOpenId());try {// 所有 Command 都满足,即需要新客弹窗 execute 接口返回 falsepopNew = !base.execute(contextBase);} catch (BizException e) {throw e;} catch (Exception e) {log.error("NewUserService getNewcomerPop 执行登录用户拦截器失败, userId: {}, error: {}", userId, e);throw new BizException(ServerCode.SYSTEM_ERROR);}}

apache common-chain 简单使用相关推荐

  1. 面试官问:对象池技术了解吗?apache common pool2呢?

    欢迎关注方志朋的博客,回复"666"获面试宝典 对象池顾名思义就是存放对象的池,与我们常听到的线程池.数据库连接池.http连接池等一样,都是典型的池化设计思想. 对象池的优点就是 ...

  2. Docker安装Apache与运行简单的web服务——httpd helloworld

    Docker运行简单的web服务--httpd helloworld目录[阅读时间:约5分钟] 一.Docker简介 二.Docker的安装与配置[CentOS环境] 三.Docker运行简单的web ...

  3. 《Apache Common CLI官方文档

    本篇文章是并发编程网组织的一次Apache Common组件翻译的一部分,因为无意中看到了Apache Common CLI感觉很好奇,因为这个工具很少在网上看到,当然或许我没有关注过.因为我之前也写 ...

  4. Apache Common常用jar包

    我们在日常开发中,不需要重复造轮子,Apache Common已经帮我们做了好多实用的jar包,直接拿来用就可以.也可以多研究下这些代码是怎么实现的. commons-logging.jar ---- ...

  5. WEB文件上传之apache common upload使用(一)

    文件上传一个经常用到的功能,它有许多中实现的方案. 页面表单 + RFC1897规范 + http协议上传 页面控件(flash/html5/activeX/applet) + RFC1897规范 + ...

  6. org.apache.struts.chain.commands.InvalidPathException: No action config found for the specified url.

    No action config found for the specified url url路径下找不到action,原因是stuts-config.xml文件配置错误. demo的项目文件如下: ...

  7. 使用Apache Common Daemon实现Windows服务

    本文介绍使用Apcahe Common Daemon组件将java程序注册为Windows服务的方法,同样使用这个库来实现服务的有著名的Tomcat,甚至我认为这个项目就是从Tomcat里剥出来的,理 ...

  8. Apache htaccess的简单总结,以及参数的使用

    一.防盗链功能 只这四行就实现了防盗链是不是很神奇^_^,编写起来是不是又觉得复杂. RewriteEngine On RewriteCond %{HTTP_REFERER} !^http://(.+ ...

  9. apache common JCS的使用

    前言 对于JCS的研究还是要回到从前使用redis的场景.主要是redis作为分布式缓存,可以集中在内存中缓存大量数据.但是,进程与redis的通信终归是进程间的通信,所有的数据都需要序列化与反序列化 ...

  10. 服务器架设笔记——使用Apache插件解析简单请求

    一般来说,对于一个请求,服务器都会对其进行解析,以确定请求的合法性以及行进的路径.于是本节将讲解如何获取请求的数据.(转载请指明出于breaksoftware的csdn博客) 我们使用<服务器架 ...

最新文章

  1. python image stiching_Python自然语言处理,词云图生成
  2. 用Servlet获取表单数据
  3. python输出print到txt-pycharm实现print输出保存到txt文件
  4. oracle 拼接sql 日期,动态SQL对日期处理注意事项
  5. react把表格渲染好ui_《RSUITE》React企业级UI框架实战评测
  6. 【传智播客】Javaweb程序设计任务教程 黑马程序员 第二章 课后答案
  7. MyBatis 分页插件 PageHelper
  8. JVM学习-字节码指令
  9. 【Paddle】实践作业——建立模型并测试100张图片
  10. 团队作业个人博客07
  11. Mybatis学习笔记(九) —— Mybatis逆向工程
  12. thinkphp5 一周学习总结 10月12日
  13. 凸优化第五章对偶 5.9 广义不等式
  14. python字典筛选
  15. 设计adm和CPU计算机组装方案,成熟的解决方案:CPU风扇(AMD和INTEL)的详细拆卸和安装方法(图形教程)...
  16. java支付宝app支付代码
  17. 正则校验整数,校验小数位,校验2-4位小数位,正整数长度可控制
  18. 2021-2027全球与中国美容淋浴器市场现状及未来发展趋势
  19. 微信小程序聊天室 前后端源码附效果图和数据库结构图
  20. Java、javascript、JS和JScript区别

热门文章

  1. 软路由安装openwrt系统
  2. 详解电脑机械硬盘装什么系统好
  3. 大疆2018网申之机器学习算法工程师笔试题B卷
  4. 年薪30~60万,机器学习算法工程师必备能力项
  5. 短视频剪辑如何入门?短视频剪辑常用的配音软件
  6. CCS 报警告 #10247-D
  7. 中芯国际进军PRAM存储,蚕食三星40nm产能
  8. ros系列—解决文件改名导致节点无法启动问题及ros::NodeHandle nh与nh(“~“)的理解
  9. 人工智能如何被用于造福人类?
  10. 权重衰减(weight decay)与学习率衰减(learning rate decay)