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;
@Component
@Slf4j
public class FilterContext implements ApplicationContextAware {
private ApplicationContext applicationContext;
private Map<String, Command> commandMap;
private volatile Map<String, List<Command>> commandFilters;
private HashMap<String, ArrayList<String>> commandFilterConfig;
private void listener(ConfigUpdateEvent configEvent) {
log.info("FilterContext 配置变更, key: {}, oldValue: {}, newValue: {}",
configEvent.getKey(), configEvent.getOldValue(), configEvent.getNewValue());
loadCommandFilters();
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
commandMap = applicationContext.getBeansOfType(Command.class);
log.info("FilterContext commandMap 初始化完成, {}", commandMap);
}
public Command getCommand(String beanName) {
if (commandMap != null) {
return commandMap.get(beanName);
}
return null;
}
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 {
popNew = !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);
}
}
|