规则引擎听起来是蛮高深的一个词语,但透过现象看本质,Martin Fowler 有如下言:
You can build a simple rules engine yourself. All you need is to create a bunch of objects with conditions and actions, store them in a collection, and run through them to evaluate the conditions and execute the actions.
虽然一个完美的规则引擎不会这么简单,但是如果你只是想要一个够用的规则引擎,这个定义就还蛮清楚的。
同样就有人根据这个想法,已经实现了一个简单的规则名字,easyRules,好吧,名字也是简单。下面我们就看看如何使用这个规则引擎。
首先还是先定义了一个接口,这个不是必须的,只是为了后续使用方便:
public interface IRule {
void setInput(JobEntity jobEntity);
String getDescription();
}
基类有一些基本的实现,注意action和priority的注解:
public abstract class BaseRule implements IRule{
protected JobEntity value;
private String desc; public BaseRule(String desc){
this.desc = desc;
} @Override
public String getDescription() {
return desc;
} @Override
public void setInput(JobEntity jobEntity){
this.value = jobEntity;
} @Action
public void printWarning(){
System.out.print(....);
} @Priority
public int getPriority(){
return 1;
}
}
真正的一个实现类,condition的注解用来判断是否触发:
@Rule
public class BlackListUserRule extends BaseRule{
private List<String> blackList = new ArrayList<>(); public BlackListUserRule(RuleItemEntity ruleItemEntity){
super(ruleItemEntity.getDesc()) ; if (ruleItemEntity.getBwType().equalsIgnoreCase(Constants.CHECK_BLACKLIST) &&
ruleItemEntity.getCheckType().equalsIgnoreCase(Constants.CHECK_USER) &&
null != ruleItemEntity.getCheckValue()) {
String[] users = ruleItemEntity.getCheckValue().split(";");
blackList.addAll(Arrays.asList(users));
}
} @Condition
public boolean inBlackList(){
if(blackList.size() == 0){
return false;
} return blackList.contains(value.getUser());
} }
还支持多个规则组成的实现:
public class MultipleRules extends CompositeRule implements IRule{ public MultipleRules(Object... rules){
for (Object rule : rules) {
addRule(rule);
}
} @Override
public void execute() throws Exception {
super.execute();
System.out.println("CompositeRule reached.");
} @Override
public void setInput(JobEntity jobEntity) {
if (!rules.isEmpty()) {
for (Rule rule : rules) {
if (rule instanceof IRule) {
IRule iRule = (IRule) rule;
iRule.setInput(jobEntity);
}
}
}
}
}
在建立完rule之后,就是如何使用了
RulesEngine jobRulesEngine= RulesEngineBuilder.aNewRulesEngine().withSkipOnFirstAppliedRule(false)
.withSilentMode(true).build(); for (RuleEntity ruleEntityEnt : ruleEntityEntList) {
IRule rule = RuleFactory.getRule(ruleEntityEnt);
if (null != rule) {
jobRulesEngine.registerRule(rule);
ruleList.add(rule);
}
} for (IRule rule : ruleList) {
rule.setInput(jobEntity);
} jobRulesEngine.fireRules();
上面的代码只是一个示意,稍微改下就可以运行。
别忘了添加依赖:
<dependency>
<groupId>org.easyrules</groupId>
<artifactId>easyrules-core</artifactId>
<version>2.4.0</version>
</dependency> 版本现在好像已经到3.3了 而且改动蛮大 上面的代码在3.3里可能不能运行。