Library for building Chain of Responsibility in Spring applications without manual wiring of dependencies.
Automatically links beans into a chain using @Order and @ChainNext.
sequenceDiagram
participant Client
participant ChainA
participant ChainB
participant ChainC
Client->>ChainA: execute()
ChainA->>ChainB: next.handle()
ChainB->>ChainC: next.handle()
- Automatic chain building via Spring context
- Supports
@Orderfor execution order - No manual wiring of chain dependencies
- Fully compatible with Spring AOP (proxies supported)
- Last class of chain contains Proxy implementation on chain interface when the class has field with
@ChainNext
- All beans implementing the chain interface are collected from the Spring context
- Beans are sorted using
@Order - The next element is injected via
@ChainNext
<dependency>
<groupId>io.github.evmetatron</groupId>
<artifactId>spring-chain-of-responsibility</artifactId>
<version>0.1.0</version>
</dependency>dependencies {
implementation("io.github.evmetatron:spring-chain-of-responsibility:0.1.0")
}import io.github.evmetatron.spring.cor.ChainFactory;
import org.springframework.context.annotation.Bean;
@Bean
public ChainInterface chain(@Autowired ChainFactory chainFactory) {
return chainFactory.createChain(ChainInterface.class);
}Injects the next element in the chain.
The order is defined using @Order.
- Do not forget
@Componentor@Service @Orderdefines execution order
import io.github.evmetatron.spring.cor.ChainNext;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
public interface ChainInterface {
void handle();
}
@Component // or @Service
@Order(1)
public class ChainA implements ChainInterface {
@ChainNext
private ChainInterface next;
@Override
public void handle() {
/* Some code */
System.out.println("Chain A");
if (shouldContinue()) {
next.handle();
}
}
}
@Component
@Order(2)
public class ChainB implements ChainInterface {
@ChainNext
private ChainInterface next;
@Override
public void handle() {
/* Some code */
System.out.println("Chain B");
if (shouldContinue()) {
next.handle();
}
}
}import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class ExampleClass {
@Autowired
private ChainInterface chain;
public void execute() {
chain.handle(); // call all chains
// Result:
// Chain A
// Chain B
}
}