Backend Development 6 min read

Using a Flow Engine and Plugin Extension for Business Isolation and Extensibility

The article explains why simple code quickly becomes unmanageable in multi‑business systems, introduces workflow engines and plugin extensions as solutions, and demonstrates configuration, node definition, execution, and the underlying Java implementation to achieve clean, isolated, and extensible business logic.

Architect's Tech Stack
Architect's Tech Stack
Architect's Tech Stack
Using a Flow Engine and Plugin Extension for Business Isolation and Extensibility

As a good programmer, one should keep solutions simple and avoid over‑design; however, in a middle‑platform (mid‑platform) team, workflow orchestration becomes essential for handling many heterogeneous business lines without littering the code with countless if‑else branches.

The author describes the pain points of code coupling, difficulty of testing across dozens of business flows, and the risk of accidental regressions when adding new business logic.

Two main remedies are proposed: using a flow engine to configure separate execution chains for each business, and employing a plugin extension engine so that each business can implement its own variations.

Configure Flow Execution Chains

In the MemberClub project, the DemoMemberPurchaseExtension demonstrates how different member product purchase processes are configured via distinct flow chains (see screenshot in the original article).

Define Flow Nodes

Each flow node implements process , success , rollback , and callback methods.

Flow Execution

Execution requires a flow context object; invoking FlowChain.execute runs the chain.

Flow Engine Execution Principle

The following Java method shows the internal logic of FlowChain.execute :

public <T> void execute(FlowChain<T> chain, T context) {
    Exception exception = null;
    int index = -1;
    for (FlowNode<T> node : chain.getNodes()) {
        try {
            node.process(context);
            index++;
        } catch (Exception e) {
            if (e instanceof SkipException) {
                CommonLog.warn("当前流程:{} 发出 Skip请求,后续流程不再执行", node.getClass().getSimpleName());
                break;
            }
            exception = e;
            break;
        }
    }

    if (exception != null) {
        for (int i = index; i >= 0; i--) {
            FlowNode<T> node = chain.getNodes().get(i);
            try {
                node.rollback(context, exception);
            } catch (Exception e) {
                CommonLog.error("rollback执行异常,忽略 name:{}", node.getClass().getSimpleName(), e);
            }
        }
    } else {
        for (int i = index; i >= 0; i--) {
            FlowNode<T> node = chain.getNodes().get(i);
            try {
                node.success(context);
            } catch (Exception e) {
                CommonLog.error("success 执行异常,忽略 name:{}", node.getClass().getSimpleName(), e);
            }
        }
    }

    for (int i = index; i >= 0; i--) {
        FlowNode<T> node = chain.getNodes().get(i);
        try {
            node.callback(context, exception);
        } catch (Exception e) {
            CommonLog.error("callback执行异常,忽略 name:{}", node.getClass().getSimpleName(), e);
        }
    }
    if (exception != null) {
        throw exception;
    }
}

The engine processes each node sequentially; on exception it rolls back, otherwise it runs success callbacks in reverse order, followed by a final callback step.

For more details and the full source code, see the project repository: https://gitee.com/juejinwuyang/memberclub .

backendJavaflow engineworkflowPlugin Architecturebusiness isolation
Architect's Tech Stack
Written by

Architect's Tech Stack

Java backend, microservices, distributed systems, containerized programming, and more.

0 followers
Reader feedback

How this landed with the community

login 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.