序言
责任链模式的核心是职责清晰,好处有两点:第一,单个节点处理逻辑清晰,节点间关系可搭积木式组合,但需要注意链条长度不可过长,否则效率降低;第二,简化客户端使用,链条对于客户端是黑盒,可能会带来一定调试的困扰。
- 场景介绍
- demo演示
一、场景介绍
1、女人在古代的依从关系就是包含三个结点的责任链:未嫁从父,既嫁从夫,夫死从子。
2、在NIO中,Netty的channelHandler实现就是一个责任链,请求经过层层传递,最终到需要处理的结点,进行逻辑处理
3、在交易前的校验判断逻辑中,先校验租户状态、再校验任务、最后校验交易,类似这种有先后顺序、可组合的的交易群也可组成责任链
二、demo演示
- 抽象类handler
- 业务处理类
- 服务端组合类
- 客户端调用类
- POM 的引入
抽象类handler
public abstract class ValidateHandler {
ValidateHandler nextHandler;
/**
* 客户端指定装配
* @param nextHandler
*/
public void setNextHandler(ValidateHandler nextHandler) {
this.nextHandler = nextHandler;
}
// 客户端调用处理
public Response handle(Request request) {
// 默认每个子结点都进入
this.validate();
if (nextHandler == null) {
return null;
}
nextHandler.handle(request);
return new Response(200);
}
// 具体需要结点实现的业务逻辑
public abstract void validate();
}
结点处理(三个结点)
// 结点1:校验主叫号码
@Service
public class ValidateCaller extends ValidateHandler {
@Override
public void validate(){
System.out.println("caller validate");
}
}
// 结点2:校验任务状态
@Service
public class ValidateTask extends ValidateHandler {
@Override
public void validate(){
System.out.println("task validate");
}
}
// 结点3:校验租户状态
@Service
public class ValidateTenant extends ValidateHandler {
@Override
public void validate(){
System.out.println("tenant validate");
}
}
服务端组合
@Service
@Slf4j
public class TransActionValidate {
@Autowired
private ValidateCaller validateCaller;
@Autowired
private ValidateTask validateTask;
@Autowired
private ValidateTenant validateTenant;
@PostConstruct
public void init() {
validateTenant.setNextHandler(validateTask);
validateTask.setNextHandler(validateCaller);
}
// 整个链条的入口
public void validate(Request request) {
log.info("TransActionValidate start:{}", request);
Response response = validateTenant.handle(request);
log.info("TransActionValidate end:{}", response);
}
}
客户端调用
// requsest
@Data
public class Request {
private String tenantId;
public Request(String tenantId) {
this.tenantId = tenantId;
}
}
// response
@Data
public class Response {
private int status;
public Response(int status) {
this.status = status;
}
}
// client
@RunWith(SpringJUnit4ClassRunner.class)// SpringJUnit支持,由此引入Spring-Test框架支持!
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class Client {
@Autowired
private TransActionValidate transActionValidate;
@Test
public void request() {
transActionValidate.validate(new Request("huang"));
}
}
POM的引入
<properties>
<!--test-->
<junit.version>4.12</junit.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
</parent>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
结果展示