What are Easy Rules?
Easy Rules is a simple and powerful Java Rules engine that provides the following features:
- Lightweight framework and easy to learn API
- Pojo-based development and annotation programming model
- Define abstract business rules and easily apply them
- The ability to create composite rules from simple rules
- Support for the ability to define rules using expression languages such as MVEL and SpEL
Runtime environment
Easy Rules is a Java library that runs on Java 1.7 and above.
Maven rely on
<properties>
<easy.rules.version>4.1.0</easy.rules.version>
</properties>
<! -- Easy rules execution engine -->
<dependency>
<groupId>org.jeasy</groupId>
<artifactId>easy-rules-core</artifactId>
<version>${easy.rules.version}</version>
</dependency>
<dependency>
<groupId>org.jeasy</groupId>
<artifactId>easy-rules-mvel</artifactId>
<version>${easy.rules.version}</version>
</dependency>
<dependency>
<groupId>org.jeasy</groupId>
<artifactId>easy-rules-spel</artifactId>
<version>${easy.rules.version}</version>
</dependency>
<! -- Easy rules execution engine -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.30</version>
</dependency>
Copy the code
Programming model based on MVEL expression
Define the rules
Most business rules can be represented by the following definitions:
- Name: a unique rule Name in a namespace
- Description: Brief Description of the rule
- Priority: Priority relative to other rules
- Facts are immediately available for data to be processed
- Conditions: A set of Conditions that must be met in order to apply a rule
- Actions: A group of Actions that are performed when a condition is met
Easy Rules provides an abstraction for each key point to define business Rules.
Entity class user
import lombok.Data;
@Data
public class User {
private Integer age;
}
Copy the code
Run the demo
import org.jeasy.rules.api.Facts;
import org.jeasy.rules.api.Rules;
import org.jeasy.rules.api.RulesEngine;
import org.jeasy.rules.core.DefaultRulesEngine;
import org.jeasy.rules.mvel.MVELRule;
import java.util.HashMap;
import java.util.Map;
public class MTest {
public static void main(String[] args) {
// Rules engine
RulesEngine rulesEngine = new DefaultRulesEngine();
/ / rules
MVELRule ageRule = new MVELRule()
.name("test rule1")
.description("test demo rule1")
.priority(1)
.when("user.age > 18")
.then("map.put('code',200); Map. Put (' MSG ',' adult ');");
Rules rules = new Rules();
rules.register(ageRule);
Facts facts = new Facts();
Map<String,Object> map = new HashMap<>();
User user = new User();
user.setAge(19);
facts.put("user", user);
facts.put("map", map); rulesEngine.fire(rules, facts); System.out.println(map); }}Copy the code
The results
14:01:21.699 [main] DEBUG org.jeasy.rules.core.DefaultRulesEngine - Engine parameters { skipOnFirstAppliedRule = false, skipOnFirstNonTriggeredRule = false, skipOnFirstFailedRule = false, priorityThreshold = 2147483647 }
14:01:21.704 [main] DEBUG org.jeasy.rules.core.DefaultRulesEngine - Registered rules:
14:01:21.705 [main] DEBUG org.jeasy.rules.core.DefaultRulesEngine - Rule { name = 'test rule1', description = 'test demo rule1', priority = '1'}
14:01:21.705 [main] DEBUG org.jeasy.rules.core.DefaultRulesEngine - Known facts:
14:01:21.705 [main] DEBUG org.jeasy.rules.core.DefaultRulesEngine - Fact{name='map', value={}}
14:01:21.705 [main] DEBUG org.jeasy.rules.core.DefaultRulesEngine - Fact{name='user', value=User(age=19)}
14:01:21.723 [main] DEBUG org.jeasy.rules.core.DefaultRulesEngine - Rules evaluation started
14:01:21.767 [main] DEBUG org.jeasy.rules.core.DefaultRulesEngine - Rule 'test rule1' triggered
14:01:21.817 [main] DEBUG org.jeasy.rules.core.DefaultRulesEngine - Rule 'test rule1'Performed successfully {MSG = Adult, code=200}
Copy the code
RuleListener RuleListener
public class CustomRuleListener implements RuleListener {
@Override
public boolean beforeEvaluate(Rule rule, Facts facts) {
System.out.println("---CustomRuleListener------beforeEvaluate-----");
return true;
}
@Override
public void afterEvaluate(Rule rule, Facts facts, boolean b) {
System.out.println("---CustomRuleListener------afterEvaluate-----");
}
@Override
public void beforeExecute(Rule rule, Facts facts) {
System.out.println("---CustomRuleListener------beforeExecute-----");
}
@Override
public void onSuccess(Rule rule, Facts facts) {
System.out.println("---CustomRuleListener------onSuccess-----");
}
@Override
public void onFailure(Rule rule, Facts facts, Exception e) {
System.out.println("---CustomRuleListener------onFailure-----"); }}Copy the code
-
BeforeEvaluate This method is executed before the @condition modified method is executed. If this method returns false, the current rule is skipped.
-
AfterEvaluate This method is executed after the @condition modifier is executed.
-
BeforeExecute This method is executed before the @Action modified method is executed.
-
The onSuccess method is executed after the @Action modified method is executed.
-
OnFailure Executes when an exception occurs in a method that executes the @Action modifier.
In the rulesEngine. The fire (rules and facts); Register rule listeners before
((DefaultRulesEngine) rulesEngine).registerRuleListener(new CustomRuleListener());
Copy the code
RulesEngineListener
public class CustomRulesEngineListener implements RulesEngineListener {
@Override
public void beforeEvaluate(Rules rules, Facts facts) {
System.out.println("---CustomRulesEngineListener------beforeEvaluate-----");
}
@Override
public void afterExecute(Rules rules, Facts facts) {
System.out.println("---CustomRulesEngineListener------afterExecute-----"); }}Copy the code
beforeEvaluate
The method is executing@Action
The decorated method is then executed. Execute before RuleListenerafterExecute
The method is executing@Condition
The decorated method is executed before. Execute after RuleListener
In the rulesEngine. The fire (rules and facts); Register rule engine listeners before
((DefaultRulesEngine) rulesEngine).registerRulesEngineListener(new CustomRulesEngineListener());
Copy the code
Rule engine initialization parameters
-
When the skipOnFirstAppliedRule is true, starting with the first rule, matching one rule skips subsequent rule matches, failing which the rule continues
-
If skipOnFirstFailedRule is true, subsequent rule matches will be skipped if an exception occurs during the execution of @Action
-
SkipOnFirstNonTriggeredRule is true, from the first article, match a will to perform, does not match the skip
-
If rulePriorityThreshold is greater than the specified priority, no match is performed
RulesEngineParameters parameters = new RulesEngineParameters()
parameters.skipOnFirstAppliedRule(true);
parameters.skipOnFirstFailedRule(true);
parameters.skipOnFirstNonTriggeredRule(true);
parameters.priorityThreshold(3);
RulesEngine rulesEngine = new DefaultRulesEngine(parameters);
Copy the code