Optimizing Contract Signing with Strategy, Chain of Responsibility, and Composite Patterns in Java
This article explains how to improve a Java Spring Boot contract signing workflow by combining the Strategy pattern, Chain of Responsibility, and Composite patterns, detailing the process steps, project structure, code implementations, custom annotations, and dynamic bean injection to achieve a flexible and maintainable solution.
The article demonstrates how to optimize a contract signing workflow in a Java Spring Boot project by applying the Strategy pattern together with the Chain of Responsibility and Composite patterns.
It first outlines the prerequisite knowledge such as mastering the Strategy pattern, Chain of Responsibility, class inheritance, interface implementation, and parameter handling.
The signing process consists of several steps (initializing contract text, generating contract, checking shield, sending MQ, updating flow, uploading files, selecting channel, and invoking the channel) and is implemented as a recursive chain where each node depends on the previous node's output.
Project structure and class diagram are provided, followed by concrete code implementations of request/response POJOs, the processor, the chain, and individual interceptors. Example code snippets are shown within /** * @author xbhog * @describe: Request POJO */ @Data @NoArgsConstructor @AllArgsConstructor @Builder public class ContractRequest { private String name; private String age; private String status; } /** * @author xbhog * @describe: Response POJO */ @Data @NoArgsConstructor @AllArgsConstructor @Builder public class ContractResponse { private String status; private String mas; } and @Slf4j @Component public class ContractSignProcessor implements Processor { @Resource(name = "contractSignCompactInitImpl") private Interceptor contractCompactInitImpl; // other interceptors injected @Override public ContractResponse process(T paramter) { List > interceptorList = new ArrayList<>(); interceptorList.add(contractCompactInitImpl); // add other interceptors log.info("签章开始"); return new ContractCall(paramter, interceptorList).exectue(); } } as well as the chain implementation public class ContractChain implements Chain { private final Integer index; private final T request; private final List > interceptors; @Override public ContractResponse proceed(T request) { if (index >= interceptors.size()) { throw new IllegalArgumentException("index越界"); } Chain nextChain = new ContractChain<>(index + 1, request, interceptors); Interceptor interceptor = interceptors.get(index); log.info("当前节点:{}", interceptor.getClass().getSimpleName()); ContractResponse response = interceptor.process(nextChain); if (Objects.isNull(response)) { throw new NullPointerException("intercetor" + interceptor + "return null"); } return response; } } .
To simplify bean injection, a custom @ContractSign annotation and an enum defining sign channels are introduced: public @interface ContractSign { ContractSignEnum.SignChannel SIGN_CHANNEL(); } and public class ContractSignEnum { public enum SignChannel { SIGN_INIT(1, "合同文本初始化"), SIGN_GENERATE(2, "合同文本生成"), // ... other channels ; private Integer code; private String info; SignChannel(Integer code, String info) { this.code = code; this.info = info; } } } . A SignConfig class scans annotated interceptors via AnnotationUtils.findAnnotation and stores them in a map, enabling the processor to build an ordered interceptor list by iterating over the map’s sorted keys.
Finally, the article discusses how the order of the chain is guaranteed by iterating over the sorted map keys, and provides test logs demonstrating the execution flow of each interceptor in the contract signing process.
Selected Java Interview Questions
A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.