Transforming Monolithic Order Processing with LiteFlow: A Component‑Based Workflow Blueprint
This article examines the challenges of sprawling order‑processing code in logistics systems and presents a strategic component‑based approach using the open‑source LiteFlow framework, detailing its architecture, execution rules, example XML flow, Java implementations, and key advantages for scalable backend development.
Background
In logistics systems, order intake is a critical information flow that often evolves into complex, multi‑department processes with thousands of lines of code, making maintenance and extension difficult.
Problems
Waterfall‑style iteration leads to massive, hard‑to‑read methods.
Personalized logic is scattered across many steps.
Inconsistent context handling causes large refactoring when extensibility was not considered.
Strategic Thinking
The strategy is to adopt a "workbench" pattern where workers (components) operate around a shared context (the workbench), pulling resources (parameters) as needed. This decouples components, stabilizes the workflow, and improves reusability.
Tactical Details
Component Definition
Components are the smallest executable units. Besides ordinary components, the framework supports boolean, conditional, loop, parallel, and exception‑handling components, which can be expressed via code inside ordinary components.
Two practical ways to group logic into components are:
Divide by business sub‑domains (e.g., shipping, receiving, carrier, product).
Define components based on actions (e.g., write to DB, dispatch to WMS).
Context
The context carries input and output data for components and should be transmissible, shareable, and dynamic. Each component only accesses the portion of the context it needs, allowing updates and propagation throughout the flow.
Execution Rules
Execution rules determine the order and conditions for component execution. Traditional XML, Spring injection, or manual assembly often hide these rules in code, making them hard to discover. Abstracting rules into a separate store (database, Redis, etc.) enables hot‑updates and clearer visibility.
Solution: LiteFlow
LiteFlow is an open‑source rule engine that implements the above concepts. It lets developers replace monolithic waterfall code with a component‑centric structure where components are loosely coupled and driven by declarative rules written in a simple DSL.
Example Flow Definition (XML)
<?xml version="1.0" encoding="UTF-8"?>
<flow>
<chain name="chain1">
THEN(
SWITCH(businessSwitch).TO(
THEN(smallChain).id("small"),
THEN(coldChain).id("cold")
),
ITERATOR(goodsIterator).DO(goodsItem),
SWITCH(kaSwitch).TO(dajiang, lining, nike).DEFAULT(defaultKa)
);
</chain>
<chain name="smallChain">
WHEN(commonDept, smallWarehouse);
</chain>
<chain name="coldChain">
WHEN(commonDept, coldWarehouse);
</chain>
</flow>Project Structure
.
├── LiteFlowDemoApplication.java
└── demos
└── web
├── BasicController.java
├── context
│ └── OrderContext.java
├── dto
│ ├── Dept.java
│ ├── Goods.java
│ ├── Request.java
│ └── WareHouse.java
├── enums
│ ├── BusinessEnum.java
│ └── KaEnum.java
└── node
├── BusinessSwitchCmp.java
├── ColdWarehouseCmp.java
├── CommonDeptCmp.java
├── GoodsItemCmp.java
├── GoodsIteratorCmp.java
├── KaSwitchCmp.java
├── SmallWarehouseCmp.java
└── ka
├── DaJiangCmp.java
├── DefaultCmp.java
├── LiNingCmp.java
└── NikeCmp.java
8 directories, 21 filesKey Component Implementations
Business Switch Component
@LiteflowComponent("businessSwitch")
public class BusinessSwitchCmp extends NodeSwitchComponent {
@Override
public String processSwitch() throws Exception {
Request request = this.getRequestData();
if (Objects.equals(request.getDept().getDeptNo(), "dept1")) {
return BusinessEnum.SMALL.getBusiness();
} else {
return BusinessEnum.COLD.getBusiness();
}
}
}Goods Iterator Component
@LiteflowComponent("goodsIterator")
public class GoodsIteratorCmp extends NodeIteratorComponent {
@Override
public Iterator<Goods> processIterator() throws Exception {
Request requestData = this.getRequestData();
return requestData.getGoodList().iterator();
}
}Goods Item Component (Loop Body)
@Slf4j
@LiteflowComponent("goodsItem")
public class GoodsItemCmp extends NodeComponent {
@Override
public void process() throws Exception {
log.info("goods item index = {}", this.getLoopIndex());
Goods goods = this.getCurrLoopObj();
goods.setGoodsId(this.getLoopIndex());
OrderContext orderContext = this.getContextBean(OrderContext.class);
List<Goods> goodsList = orderContext.getData("goods");
if (goodsList == null) {
goodsList = new ArrayList<>();
this.getContextBean(OrderContext.class).setData("goods", goodsList);
}
goodsList.add(goods);
}
}Test Case
public String testConfig() {
Request request = new Request();
Dept dept = new Dept();
dept.setDeptNo("nike");
request.setDept(dept);
WareHouse wareHouse = new WareHouse();
request.setWareHouse(wareHouse);
Goods goods1 = new Goods();
goods1.setGoodsName("goods1");
Goods goods2 = new Goods();
goods2.setGoodsName("goods2");
request.setGoodList(Arrays.asList(goods1, goods2));
LiteflowResponse liteflowResponse = flowExecutor.execute2Resp("chain1", request, OrderContext.class);
OrderContext contextBean = liteflowResponse.getContextBean(OrderContext.class);
List<Goods> goodsList = contextBean.getData("goods");
WareHouse warehouse = contextBean.getData("warehouse");
Dept dept1 = contextBean.getData("dept");
log.info("=== dept = {}", JsonUtil.toJsonString(dept1));
log.info("=== warehouse = {}", JsonUtil.toJsonString(warehouse));
log.info("=== goodsList = {}", JsonUtil.toJsonString(goodsList));
return "yes";
}Key Features of LiteFlow
Unified component definition – all logic is encapsulated as components.
Rule persistence – native support for storing rules in databases, Nacos, Etcd, Zookeeper, Apollo, Redis, or custom stores.
Context isolation – reliable isolation prevents data leakage under high concurrency.
Broad framework support – works with Spring Boot, Spring, and other Java frameworks.
Lightweight rule files – low learning curve for rule authoring.
Conclusion
LiteFlow provides a powerful, extensible workflow rule engine that addresses the pain points of monolithic order‑processing code by abstracting components, contexts, and execution rules. Its design enables clear separation of concerns, easy rule management, and rapid iteration, making it a valuable reference for backend architects seeking scalable solutions.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
JD Tech Talk
Official JD Tech public account delivering best practices and technology innovation.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
