Master QLExpress: A Hands‑On Guide to Rule Engine Integration with Spring Boot 3
This article introduces the QLExpress rule engine, outlines its key features such as thread‑safety and high‑performance execution, and provides step‑by‑step Spring Boot 3 integration examples—including dependency setup, simple expressions, function definitions, operator aliases, macro usage, and variable querying—complete with runnable code snippets and output illustrations.
1. Introduction
In complex business environments, a rule engine is the core of system decision‑making, allowing business logic to be adjusted flexibly. QLExpress, developed by Alibaba, offers a concise syntax, high‑performance execution, and flexible configuration, making it suitable for Java backend projects such as Spring Boot 3.
2. Features of QLExpress
Thread‑safe: temporary variables are stored in ThreadLocal.
High‑efficiency execution: compiled scripts can be cached locally and variable creation uses a buffer pool, comparable to Groovy performance.
Weakly‑typed script language similar to Groovy/JavaScript, enhancing business flexibility.
Safety controls: can prevent infinite loops and risky API calls via runtime parameters.
Lightweight: only a 250 KB JAR, suitable for any Java runtime.
3. Quick Start
Add the Maven dependency:
<code><dependency>
<groupId>com.alibaba</groupId>
<artifactId>QLExpress</artifactId>
<version>3.3.3</version>
</dependency>
</code>No additional configuration is required; the library can be used directly.
Simple Example
<code>ExpressRunner runner = new ExpressRunner();
DefaultContext<String, Object> context = new DefaultContext<>();
context.put("a", 1);
context.put("b", 2);
context.put("c", 3);
String express = "a + b * c";
Object ret = runner.execute(express, context, null, true, false);
System.out.printf("%s = %d%n", express, ret);
</code>Basic Syntax
Supported operators: +, -, *, /, <, >, <=, >=, ==, !=, %, ++, --, in, like, &&, ||, !, etc. Control structures such as for, break, continue, if‑then‑else are also supported.
Defining Functions
<code>context.put("arg1", 10);
context.put("arg2", 20);
String express = """
function add(int a, int b) {
return a + b ;
}
return Math.PI + add(arg1, arg2) ;
""";
Object ret = runner.execute(express, context, null, true, false);
System.out.printf("Result: %s%n", ret);
</code>Operator Aliases (Chinese)
<code>runner.addOperatorWithAlias("如果", "if", null);
runner.addOperatorWithAlias("否则", "else", null);
runner.addOperatorWithAlias("大于", ">", null);
runner.addOperatorWithAlias("返回", "return", null);
String express = "如果(a大于b){返回 1;} 否则 {返回 0;}";
Object ret = runner.execute(express, context, null, true, false);
</code>Binding Objects or Methods
<code>runner.addFunctionOfClassMethod("四舍五入", CommonService.class, "roundUp",
new Class[]{double.class}, null);
String express = "四舍五入(56.54788)";
Object ret = runner.execute(express, null, null, true, false);
System.out.printf("Result: %s%n", ret);
</code>Macro Definition
<code>runner.addMacro("计算平均成绩", "(语文+数学+英语) / 3.0");
runner.addMacro("是否优秀", "计算平均成绩 > 90");
DefaultContext<String, Object> ctx = new DefaultContext<>();
ctx.put("语文", 88);
ctx.put("数学", 99);
ctx.put("英语", 95);
Object ret = runner.execute("是否优秀", ctx, null, false, false);
System.out.printf("是否优秀: %s%n", ret);
</code>Query Variables
<code>String express = """
int ret = (a + b + Math.PI * c ) / 4 ;
return ret ;
""";
String[] vars = runner.getOutVarNames(express);
for (String var : vars) {
System.out.printf("var: %s%n", var);
}
</code>The above code demonstrates how to retrieve variable names required by an expression.
4. Conclusion
QLExpress provides a powerful yet lightweight rule‑engine solution for Java backend developers. Its thread‑safety, performance, and extensibility make it a practical choice for integrating dynamic business rules into Spring Boot 3 applications.
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.
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.