Expand Authors Top

If you have a few years of experience in the Java ecosystem and you’d like to share that with the community, have a look at our Contribution Guidelines.

Expanded Audience – Frontegg – Security (partner)
announcement - icon User management is very complex, when implemented properly. No surprise here.

Not having to roll all of that out manually, but instead integrating a mature, fully-fledged solution - yeah, that makes a lot of sense.
That's basically what Frontegg is - User Management for your application. It's focused on making your app scalable, secure and enjoyable for your users.
From signup to authentication, it supports simple scenarios all the way to complex and custom application logic.

Have a look:

>> Elegant User Management, Tailor-made for B2B SaaS

November Discount Launch 2022 – Top
We’re finally running a Black Friday launch. All Courses are 30% off until the end of this week:


November Discount Launch 2022 – TEMP TOP (NPI)
We’re finally running a Black Friday launch. All Courses are 30% off until the end of this week:


1. Introduction

Apache Commons Chain is a library that uses the Chain of Responsibility pattern – generally used for organizing complex processing flows in which multiple receivers can process a request.

In this quick article, we'll go through an example representing a withdrawal from an ATM.

2. Maven Dependency

To start, we'll import the latest version of this library using Maven:


To check for the most recent version of this library – go here.

3. Example Chain

The ATM takes a number as an input and passes it down to handlers responsible for performing different actions. Those involve calculating numbers of bank notes to be dispensed, and sending a notification to the bank and customer about the transaction.

4. Chain Context

The context represents the current state of an application, storing information about the transaction.

For our ATM withdrawal request, the information we need is:

  • Total amount to be withdrawn
  • Number of 100 denomination notes
  • Number of 50 denomination notes
  • Number of 10 denomination notes
  • Amount left to be withdrawn

This state is defined in a class:

public class AtmRequestContext extends ContextBase {
    int totalAmountToBeWithdrawn;
    int noOfHundredsDispensed;
    int noOfFiftiesDispensed;
    int noOfTensDispensed;
    int amountLeftToBeWithdrawn;

    // standard setters & getters

5. Command

The Command takes the Context as an input and processes it.

We'll implement each of the steps mentioned above as a Command:

public class HundredDenominationDispenser implements Command {

    public boolean execute(Context context) throws Exception {
        intamountLeftToBeWithdrawn = (int) context.get("amountLeftToBeWithdrawn);
        if (amountLeftToBeWithdrawn >= 100) {
            context.put("noOfHundredsDispensed", amountLeftToBeWithdrawn / 100);
            context.put("amountLeftToBeWithdrawn", amountLeftToBeWithdrawn % 100);
        return false;

The Commands for FiftyDenominationDispenser & TenDenominationDispenser are similar.

6. Chain

A Chain is a collection of commands to be executed in a specified order. Our Chain will consist of the above Commands and also an AuditFilter at the end:

public class AtmWithdrawalChain extends ChainBase {

    public AtmWithdrawalChain() {
        addCommand(new HundredDenominationDispenser());
        addCommand(new FiftyDenominationDispenser());
        addCommand(new TenDenominationDispenser());
        addCommand(new AuditFilter());

When any Command in the Chain returns true, it forces the Chain to end.

7. Filter

A filter is also a Command but with a postProcess method that is called after the execution of the Chain.

Our Filter will send a notification to the customer & the bank:

public class AuditFilter implements Filter {

    public boolean postprocess(Context context, Exception exception) {
        // send notification to bank and user
        return false;

    public boolean execute(Context context) throws Exception {
        return false;

8. Chain Catalog

It is a collection of Chains and Commands with their logical names.

In our case, our Catalog will contain the AtmWithdrawalChain.

public class AtmCatalog extends CatalogBase {

    public AtmCatalog() {
        addCommand("atmWithdrawalChain", new AtmWithdrawalChain());

9. Using the Chain

Let's see how we can use the above Chain to process a withdrawal request. We'll first create a Context and then pass it the Chain. The Chain will process the Context.

We'll write a test case to demonstrate our AtmWithdrawalChain:

public class AtmChainTest {

    public void givenInputsToContext_whenAppliedChain_thenExpectedContext() throws Exception {
        Context context = new AtmRequestContext();
        context.put("totalAmountToBeWithdrawn", 460);
        context.put("amountLeftToBeWithdrawn", 460);
        Catalog catalog = new AtmCatalog();
        Command atmWithdrawalChain = catalog.getCommand("atmWithdrawalChain");
        assertEquals(460, (int) context.get("totalAmountToBeWithdrawn"));
        assertEquals(0, (int) context.get("amountLeftToBeWithdrawn"));
        assertEquals(4, (int) context.get("noOfHundredsDispensed"));
        assertEquals(1, (int) context.get("noOfFiftiesDispensed"));
        assertEquals(1, (int) context.get("noOfTensDispensed"));

10. Conclusion

In this tutorial, we explored a practical scenario using the Apache's Apache Commons Chain library – which you can read more about here.

And, as always, the code for this article is available over on Github.

November Discount Launch 2022 – Bottom
We’re finally running a Black Friday launch. All Courses are 30% off until the end of this week:


Generic footer banner
Comments are closed on this article!