Integrating URule Rule Engine with Spring Boot: Installation, Configuration, and Practical Examples
This article introduces the URule rule engine, explains its core concepts and library types, shows how to install and configure it within a Spring Boot project, demonstrates rule set and decision‑table creation, and provides complete Java code examples for practical usage.
The author shares the experience of selecting a rule engine to simplify complex conditional logic during a project refactor, ultimately choosing URule because it offers a browser‑based visual editor and does not require additional installation.
A rule engine is a component that extracts business rules from code, allowing the program to focus on core logic while the engine evaluates inputs against predefined rules to produce results; URule runs on various OSes and provides a pure‑browser editing mode.
Installation involves adding the open‑source URule module to a Spring Boot project, configuring a MySQL datasource, and starting the service; once the server runs, the UI is accessible at http://localhost:8090/urule/frame .
URule’s core consists of two parts: the designer (library files and rule files) and the execution engine. Library files include variable, constant, parameter, and action libraries, analogous to Java POJOs, enums, maps, and Spring beans.
Variable libraries map POJO classes to rule variables. For example, the following POJO is annotated with @Label to expose fields to the rule engine:
package com.cicada;
import com.bstek.urule.model.Label;
import lombok.Data;
@Data
public class Stu {
@Label("姓名")
private String name;
@Label("年龄")
private int age;
@Label("班级")
private String classes;
}Constant libraries store enums or fixed values, parameter libraries act as dynamic maps for temporary variables, and action libraries expose Spring bean methods to rules using @ExposeAction annotations. An example action class is shown below:
package com.bstek.urule.cicada;
import com.bstek.urule.action.ActionId;
import com.bstek.urule.model.ExposeAction;
import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat;
import java.util.Date;
@Component("action")
public class Action {
@ActionId("Hello")
public String hello() { return "hello"; }
@ExposeAction(value="方法1")
public boolean evalTest(String username) {
if (username == null) return false;
else if (username.equals("张三")) return true;
return false;
}
@ExposeAction(value="测试Int")
public int testInt(int a, int b) { return a + b; }
@ExposeAction(value="打印内容")
public void printContent(String username, Date birthday) {
SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
if (birthday != null) {
System.out.println(username + "今年已经" + sd.format(birthday) + "岁了!");
} else {
System.out.println("Hello " + username);
}
}
@ExposeAction(value="打印Stu")
public void printUser(Stu m) {
System.out.println("Hello " + m.getName() + ", is age:" + m.getAge());
}
}Rule sets can be created in two styles: wizard‑style (visual drag‑and‑drop) and script‑style (written in DSL). The wizard style is demonstrated with a simple if‑then‑else rule set, and the corresponding Java code that loads and fires the rules is:
package com.cicada;
import cn.hutool.core.bean.BeanUtil;
import com.Result;
import com.bstek.urule.Utils;
import com.bstek.urule.runtime.*;
import com.bstek.urule.runtime.service.KnowledgeService;
import com.cicada.req.StuReq;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
@RestController
@RequestMapping("/rule")
public class RuleDataController {
@PostMapping("/stu")
public Result rule(@RequestBody StuReq stuReq) throws IOException {
KnowledgeService knowledgeService = (KnowledgeService) Utils.getApplicationContext().getBean(KnowledgeService.BEAN_ID);
KnowledgePackage knowledgePackage = knowledgeService.getKnowledge("xxx/xxx");
KnowledgeSession knowledgeSession = KnowledgeSessionFactory.newKnowledgeSession(knowledgePackage);
Stu stu = BeanUtil.copyProperties(stuReq, Stu.class);
knowledgeSession.insert(stu);
knowledgeSession.fireRules();
return Result.success(stu.getTeacher());
}
}Decision tables provide an alternative, spreadsheet‑like view of rule sets, making the logic easier for non‑technical stakeholders to understand.
In a real‑world scenario, the author models a user‑level promotion system (ordinary → member → elite) with rules such as registration counts, order amounts, and continuity rates, configuring them via a decision table.
The article concludes that while a rule engine is optional, it helps separate complex business decisions from core code, making maintenance and evolution more manageable.
Code Ape Tech Column
Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn
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.