Spring Boot Chain of Responsibility Pattern Example
By Ercan - 26/09/2025
The Chain of Responsibility is a behavioral design pattern that allows us to process a request through a sequence of handlers. Each handler decides whether it can process the request or pass it along to the next handler in the chain.
In this article, we will demonstrate how this pattern can be applied in a Spring Boot application to resolve which hashing algorithm was used for a given hash.
TL;DR: If you want to skip the explanation and dive straight into the code, check out the full implementation on GitHub: https://github.com/ercansormaz/chain-of-responsibility-pattern
Problem to Solve
Given a plain text string and its hashed value, we want to determine which algorithm (MD5, SHA1, SHA256, etc.) generated the hash.
The API
Our project provides a simple API:
Request:
curl --location 'http://localhost:8080/hash/resolve' \
--header 'Content-Type: application/json' \
--data '{
"text": "hello world",
"hash": "5eb63bbbe01eeed093cb22bb8f5acdc3"
}'
Response:
{
"algorithm": "MD5"
}
Applying the Chain of Responsibility
Instead of writing a complex if-else or switch-case block for each hashing algorithm, we used the Chain of Responsibility Pattern:
- Each algorithm is represented by a dedicated ChainHandler class.
- If a handler can resolve the hash, it returns the self.
- Otherwise, it forwards the request to the next step in the chain.
This structure makes the system open for extension (adding a new algorithm is easy) but closed for modification (no need to touch existing logic).
The Role of HashResolveChainOrchestrator
At the core of this implementation lies the HashResolveChainOrchestrator.
This class is responsible for managing and executing the chain:
- It builds the handler chain based on each algorithm’s hash length during the application’s startup
- It defines the entry point for the chain execution.
- It invokes the first step and ensures the request flows through the chain.
By isolating the chain handling logic in one place, the code becomes clean, reusable, and easy to test.
@Component
@RequiredArgsConstructor
public class HashResolveChainOrchestrator {
private final List<HashResolveChainHandler> hashResolveChainImplementations;
private HashResolveChainHandler resolveChain;
@PostConstruct
public void prepareResolveChain() {
HashResolveChainHandler current = null;
List<HashResolveChainHandler> sortedList = hashResolveChainImplementations.stream()
.sorted(Comparator.comparingInt(o -> o.getHashType().getHexStringLength()))
.toList();
for (HashResolveChainHandler chainStep : sortedList) {
if (Objects.isNull(resolveChain)) {
resolveChain = chainStep;
}
if (Objects.nonNull(current)) {
current.setNext(chainStep);
}
current = chainStep;
}
}
public HashType resolve(String text, String hash) {
return resolveChain.matches(text, hash).getHashType();
}
}
Benefits of This Approach
- Scalability – Adding a new algorithm requires only a new chain step class.
- Separation of Concerns – Each step handles only its own algorithm.
- Maintainability – The
HashResolveChainOrchestratorcentralizes chain execution, avoiding duplication.
Conclusion
The Chain of Responsibility pattern provides a clean and extensible way to handle multiple possible operations without cluttering code with conditionals.
In this Spring Boot project, we applied it to build a Hash Algorithm Resolver, which can easily be extended with new hashing algorithms.
The result is a flexible, testable, and production-ready structure that demonstrates the power of design patterns in modern applications.
👉 You can explore the full source code on GitHub:
https://github.com/ercansormaz/chain-of-responsibility-pattern
Tags: spring boot, design pattern, chain of responsibility pattern, java
