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<T extends ContractRequest> implements Processor<T, ContractResponse> {
@Resource(name = "contractSignCompactInitImpl")
private Interceptor<T, ContractResponse> contractCompactInitImpl;
// other interceptors injected
@Override
public ContractResponse process(T paramter) {
List<Interceptor<T, ContractResponse>> 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<T extends ContractRequest> implements Chain<T, ContractResponse> {
private final Integer index;
private final T request;
private final List<Interceptor<T, ContractResponse>> interceptors;
@Override
public ContractResponse proceed(T request) {
if (index >= interceptors.size()) {
throw new IllegalArgumentException("index越界");
}
Chain<T, ContractResponse> nextChain = new ContractChain<>(index + 1, request, interceptors);
Interceptor<T, ContractResponse> 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.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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.
