Mastering Apache Commons Chain in Spring Boot 3: Real‑World Examples

This article introduces a Spring Boot 3 case collection and then provides a comprehensive tutorial on using Apache Commons Chain, covering its core interfaces, basic and advanced usage, resource release, catalog management, exception handling, and integration with Spring Boot.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Mastering Apache Commons Chain in Spring Boot 3: Real‑World Examples

Introduction Apache Commons Chain is a subproject of Apache Commons that implements the Chain of Responsibility pattern. It provides a flexible way to organize and execute a series of commands, with support for Context, Command, Chain, Filter, and Catalog interfaces.

Core Interfaces

Context : a marker interface extending java.util.Map, representing the application state.

Command : a unit of work with a single method public boolean execute(Context context). It returns true to stop further execution.

Chain : implements Command, can contain other Commands or Chains, allowing nesting.

Filter : a special Command with a postprocess(Context, Exception) method for resource cleanup, executed in reverse order.

Catalog : a logical collection of named Commands, enabling lookup by name.

Basic Example

public class Command1 implements Command {
  public boolean execute(Context context) throws Exception {
    System.err.println("command1...");
    context.put("c1", "我是C1计算结果");
    return false;
  }
}
public class Command2 implements Command {
  public boolean execute(Context context) throws Exception {
    System.err.println("command2...");
    System.out.println(context.get("c1"));
    context.put("c2", "我是C2计算结果");
    return false;
  }
}
public class Command3 implements Command {
  public boolean execute(Context context) throws Exception {
    System.err.println("command3...");
    System.out.println(context.get("c2"));
    return false;
  }
}

Running the chain:

Context context = new ContextBase();
List<Command> commands = List.of(new Command1(), new Command2(), new Command3());
Chain chain = new ChainBase(commands);
chain.execute(context);

Output:

command1...
command2...
我是C1计算结果
command3...
我是C2计算结果

Resource Release

Commands that need cleanup can implement Filter. The postprocess method is called after execution in reverse order.

public class Command1 implements Command, Filter {
  public boolean postprocess(Context context, Exception exception) {
    System.err.println("C1释放资源");
    return exception == null;
  }
}
// similarly for Command2 and Command3

Result shows resources released in reverse order.

Catalog Management

CatalogBase catalog = new CatalogBase();
catalog.addCommand("c1", new Command1());
catalog.addCommand("c2", new Command2());
catalog.addCommand("c3", new Command3());

Map<String, Object> data = new HashMap<>();
Context context = new ContextBase(data);
Iterator<String> names = catalog.getNames();
while (names.hasNext()) {
  catalog.getCommand(names.next()).execute(context);
}

Exception Handling

If a Command throws an exception, execution stops, but Filters still run. The exception can be caught after chain.execute.

try {
  chain.execute(context);
} catch (Exception e) {
  System.err.printf("发生错误: %s%n", e.getMessage());
}

Spring Boot Integration Example

Define three Commands as Spring beans with @Component and @Order to control execution order, then inject them into a component that builds a Chain and runs it.

@Component
@Order(1)
public class ValidatorCommand implements Command { /* ... */ }

@Component
@Order(2)
public class HtmlCheckCommand implements Command { /* ... */ }

@Component
@Order(3)
public class SensitiveWordCommand implements Command { /* ... */ }

@Component
public class CharCheckComponent {
  private final List<Command> commands;
  private final Catalog catalog;
  // constructor injection and check method that builds ChainBase(commands) and executes
}

Running the Spring Boot application prints the execution flow of the three commands.

Note : The commons-chain project is no longer actively maintained and its servlet‑context implementation does not support Jakarta EE.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

backend-developmentSpring BootApache Commons ChainCommand Pattern
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.