在职责链模式中,多个处理器依次处理同一个请求。一个请求先经过 A 处理器处理,然后再把请求传递给 B 处理器,B 处理器处理完后再传递给 C 处理器,以此类推,形成一个链条。链条上的每个处理器各自承担各自的处理职责,所以叫作职责链模式。
在 GoF 的定义中,一旦某个处理器能处理这个请求,就不会继续将请求传递给后续的处理器了。当然,在实际的开发中,也存在对这个模式的变体,那就是请求不会中途终止传递,而是会被所有的处理器都处理一遍。
public abstract class AbstractHandler {
private AbstractHandler nextHandler;
public void setNextHandler(AbstractHandler nextHandler) {
this.nextHandler = nextHandler;
}
public void handle() {
boolean handled = doHandle();
if (!handled && nextHandler != null) {
nextHandler.handle();
}
}
protected abstract boolean doHandle();
}
public class HandlerA extends AbstractHandler {
@Override
protected boolean doHandle() {
boolean result = false;
System.out.println("HandlerA");
return result;
}
}
public class HandlerB extends AbstractHandler {
@Override
protected boolean doHandle() {
boolean result = false;
System.out.println("HandlerB");
return result;
}
}
public class HandlerChain {
private AbstractHandler head;
private AbstractHandler tail;
public HandlerChain addHandler(AbstractHandler handler) {
if (head == null) {
head = handler;
tail = handler;
} else {
tail.setNextHandler(handler);
tail = handler;
}
return this;
}
public void handle() {
if (head != null) {
head.handle();
}
}
}
public class Application {
public static void main(String[] args) {
final HandlerChain chain = new HandlerChain();
chain.addHandler(new HandlerA())
.addHandler(new HandlerB())
.handle();
}
}
public interface IHandler {
void handle();
}
public class HandlerA implements IHandler {
@Override
public void handle() {
System.out.println("HandlerA");
}
}
public class HandlerB implements IHandler {
@Override
public void handle() {
System.out.println("HandlerB");
}
}
public class HandlerChain {
private List<IHandler> chain = Lists.newArrayList();
public HandlerChain addHandler(IHandler handler) {
chain.add(handler);
return this;
}
public void handle() {
chain.forEach(IHandler::handle);
}
}
public class Application {
public static void main(String[] args) {
final HandlerChain chain = new HandlerChain();
chain.addHandler(new HandlerA())
.addHandler(new HandlerB())
.handle();
}
}
该模式能将多个处理者连接成一条链。 接收到请求后, 它会 “询问” 每个处理者是否能够对其进行处理。 这样所有处理者都有机会来处理请求。
无论你以何种顺序将处理者连接成一条链, 所有请求都会严格按照顺序通过链上的处理者。
如果在处理者类中有对引用成员变量的设定方法, 你将能动态地插入和移除处理者, 或者改变其顺序。
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface ChainNode {
/**
* 所属链名称
*/
String chain();
/**
* 节点名称
*/
String name() default StrUtil.EMPTY;
/**
* 在链中的位置(-1表示末尾)
*/
int index() default -1;
}
支持多个定义,只有要与之对应的执行器就行
public interface Validate<T> {
/**
* 执行校验
*
* @param context
* @author yuyouyang
* @date 2021/6/3 21:38
* @version 1.0
*/
void doValidate(T context);
}
@Component
@ChainNode(chain = ChainConstant.DESIGN_VALIDATE_CHAIN, name = ChainConstant.COLUMN_VALIDATE, index = 1)
public class ColumnValidate implements Validate<Map<String, Object>> {
@Override
public void doValidate(Map<String, Object> context) {...}
}
@Component
@ChainNode(chain = ChainConstant.DESIGN_VALIDATE_CHAIN, name = ChainConstant.HAS_EXECUTED_VALIDATE, index = -1)
public class HasExecutedValidate implements Validate<Map<String, Object>> {
@Override
public void doValidate(Map<String, Object> context) {...}
}
public class ValidateChainExecutor{
private Map<String, List<Validate>> chains = Maps.newHashMap();
private Map<String, Object> validations;
public ValidateChainExecutor(Map<String, Object> validations) {
this.validations = validations;
init();
}
/**
* 初始化责任链
*
* @author yuyouyang
* @date 2021/6/3 21:36
* @version 1.0
*/
private void init() {
final Class<ChainNode> validateAnnoClass = ChainNode.class;
validations.values()
.forEach(validation -> {
final ChainNode anno = validation.getClass()
.getAnnotation(validateAnnoClass);
chains.computeIfAbsent(anno.chain(), v -> new ArrayList<>())
.add((Validate) validation);
});
// 排序
chains.values()
.forEach(chain -> chain.sort(Comparator.comparingInt(c -> c.getClass()
.getAnnotation(validateAnnoClass)
.index())));
}
@SuppressWarnings("unchecked")
public <T> void execute(String chain, T context) {
chains.get(chain)
.forEach(validation -> validation.doValidate(context));
}
}
@Configuration
public class ChainConfig {
@Autowired
private ApplicationContext applicationContext;
@Bean
@ConditionalOnMissingBean
public ValidateChainExecutor getChainExecutor() {
return new ValidateChainExecutor(applicationContext.getBeansWithAnnotation(ChainNode.class));
}
}