本文主要研究下easy-rules。
easy-rules是一款轻量级的规则引擎。
<dependency>
<groupId>org.jeasy</groupId>
<artifactId>easy-rules-core</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.jeasy</groupId>
<artifactId>easy-rules-mvel</artifactId>
<version>3.1.0</version>
</dependency>
easy-rules首先集成了mvel表达式,后续可能集成SpEL
@Rule
public class BuzzRule {
@Condition
public boolean isBuzz(@Fact("number") Integer number) {
return number % 7 == 0;
}
@Action
public void printBuzz() {
System.out.println("buzz");
}
@Priority
public int getPriority() {
return 2;
}
}
easy-rules-core-3.1.0-sources.jar!/org/jeasy/rules/api/Rule.java
/**
* Abstraction for a rule that can be fired by the rules engine.
*
* Rules are registered in a rule set of type <code>Rules</code> in which they must have a <strong>unique</strong> name.
*
* @author Mahmoud Ben Hassine (mahmoud.benhassine@icloud.com)
*/
public interface Rule extends Comparable<Rule> {
/**
* Default rule name.
*/
String DEFAULT_NAME = "rule";
/**
* Default rule description.
*/
String DEFAULT_DESCRIPTION = "description";
/**
* Default rule priority.
*/
int DEFAULT_PRIORITY = Integer.MAX_VALUE - 1;
/**
* Getter for rule name.
* @return the rule name
*/
String getName();
/**
* Getter for rule description.
* @return rule description
*/
String getDescription();
/**
* Getter for rule priority.
* @return rule priority
*/
int getPriority();
/**
* Rule conditions abstraction : this method encapsulates the rule's conditions.
* <strong>Implementations should handle any runtime exception and return true/false accordingly</strong>
*
* @return true if the rule should be applied given the provided facts, false otherwise
*/
boolean evaluate(Facts facts);
/**
* Rule actions abstraction : this method encapsulates the rule's actions.
* @throws Exception thrown if an exception occurs during actions performing
*/
void execute(Facts facts) throws Exception;
}
实现这个接口,也是创建rule的一种形式。
即基于注解的形式
),则利用JDK的动态代理进行包装。下面以getName为例看下如何根据注解来返回
private String getRuleName() {
org.jeasy.rules.annotation.Rule rule = getRuleAnnotation();
return rule.name().equals(Rule.DEFAULT_NAME) ? getTargetClass().getSimpleName() : rule.name();
}
可以看到这里对注解进行了解析
从本质上看,规则引擎的目的就是要以松散灵活的方式来替代硬编码式的if else判断,来达到解耦的目的,不过实际场景要额外注意规则表达式的安全问题。