EasyRule基本用法

王俊楚
2023-12-01
easy Rule就是一个轻量级的规则引擎,它可以直接注入spring bean类,可以查看github上对它的介绍:GitHub - j-easy/easy-rules: The simple, stupid rules engine for Java(官网地址

它具有以下特点

  1. 轻量级库和易于学习的 API
  2. 基于注解编程模型的 POJO 开发
  3. 有用的抽象来定义业务规则并使用 Java 轻松应用它们
  4. 从原始规则创建复合规则的能力
  5. 使用表达式语言(如 MVEL、SpEL 和 JEXL)定义规则的能力

1.引入相关依赖

   <dependency>
            <groupId>org.jeasy</groupId>
            <artifactId>easy-rules-core</artifactId>
            <version>4.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.jeasy</groupId>
            <artifactId>easy-rules-mvel</artifactId>
            <version>4.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.jeasy</groupId>
            <artifactId>easy-rules-spel</artifactId>
            <version>4.1.0</version>
        </dependency>

2.使用方式

2.1 创建规则

它分为四种
1.使用注解的方式

@Rule(name = "weather rule", description = "if it rains then take an umbrella")
public class WeatherRule {

    @Condition
    public boolean itRains(@Fact("rain") boolean rain) {
        return rain;
    }
    
    @Action
    public void takeAnUmbrella() {
        System.out.println("It rains, take an umbrella!");
    }
}
  1. 编程方式使用流畅的 API
Rule weatherRule = new RuleBuilder()
        .name("weather rule")
        .description("if it rains then take an umbrella")
        .when(facts -> facts.get("rain").equals(true))
        .then(facts -> System.out.println("It rains, take an umbrella!"))
        .build();
  1. 使用表达式语言
Rule weatherRule = new MVELRule()
        .name("weather rule")
        .description("if it rains then take an umbrella")
        .when("rain == true")
        .then("System.out.println(\"It rains, take an umbrella!\");");
  1. 使用规则描述符
    定义规则文件weather-rule.yml
    name: “weather rule”
    description: “if it rains then take an umbrella”
    condition: “rain == true”
    actions:
  • “System.out.println(“It rains, take an umbrella!”);”
MVELRuleFactory ruleFactory = new MVELRuleFactory(new YamlRuleDefinitionReader());
Rule weatherRule = ruleFactory.createRule(new FileReader("weather-rule.yml"));

2.2 注册规则

通过如下代码:

   Rules rules = new Rules();
   rules.register(weatherRule);

2.3 定义事实

Easy Rules中的一个事实是由Fact表示的:

 Facts facts = new Facts();
 facts.put("rain", true);

一个事实有一个名称和一个值,两者都不能为null。另一方面,Facts API 表示一组事实并充当事实的命名空间。这意味着,在一个Facts实例中,事实必须有唯一的名称。

2.4 定义规则引擎

它分为两种:

  1. DefaultRulesEngine:根据规则的自然顺序(默认为优先级)应用规则。

  2. InferenceRulesEngine:在已知的事实上不断地应用规则,直到没有更多的规则可用。

2.5 组合规则

Easy Rules允许从原始规则创建复杂的规则。一个CompositeRule由一组规则组成。组合规则是一个抽象概念,因为组合规则可以以不同的方式触发。Easy Rules提供了3种CompositeRule的实现。

UnitRuleGroup:单元规则组是作为一个单元使用的组合规则,要么应用所有规则,要么不应用任何规则。
ActivationRuleGroup:激活规则组触发第一个适用规则并忽略组中的其他规则。规则首先按照其在组中的自然顺序(默认情况下优先级)进行排序。
ConditionalRuleGroup:条件规则组将具有最高优先级的规则作为条件,如果具有最高优先级的规则的计算结果为true,那么将触发其余的规则。

2.6 自定义监听器

public class MyRuleListener implements RuleListener {
 
     @Override
    public boolean beforeEvaluate(Rule rule, Facts facts) {
        log.info("-----{}-----Condition之前的执行----", rule.getName());
        String ruleName = rule.getName();
        //拿到规则信息
   
        //这里是可以对参数进行判断校验的
 
 
        return true;
    }
 
    /**
     * 规则条件判断之后的触发器
     * b表示规则是否触发
     */
    @Override
    public void afterEvaluate(Rule rule, Facts facts, boolean b) {
        log.info("----{} ---Condition执行之后 可以得到规则是否触发----", rule.getName());
        if (b) {
            log.info("----{} 规则被触发-----", rule.getName());
 
        } else {
            log.info("-----{} 规则没有被触发----", rule.getName());
 
         
        }
    }
 
    /**
     * 规则执行之前的触发器
     */
    @Override
    public void beforeExecute(Rule rule, Facts facts) {
        log.info("-----{} ----在执行Action之前执行----", rule.getName());
 
    }
 
    /**
     * 规则执行成功之后的触发器
     */
    @Override
    public void onSuccess(Rule rule, Facts facts) {
        log.info("-----{}---- 规则Action执行完并且是成功的---", rule.getName());
 
        String ruleName = rule.getName();
       
 
    }
 
    /**
     * 规则执行失败之后的触发器
     */
    @Override
    public void onFailure(Rule rule, Facts facts, Exception e) {
        log.info("-----{} ----Action执行失败 ----", rule.getName());
        String ruleName = rule.getName();
      
    }
}

2.7 运行规则

我们通过上面注入的规则监听器去监听规则的执行情况 ,下面是我自己定义的监听类,实现类 RuleListener接口

 RulesEngine rulesEngine = new InferenceRulesEngine();
 rulesEngine.fire(rules, facts);

3. 完整示例如下:

  Rule weatherRule = new RuleBuilder()
                .name("weather rule")
                .description("if it rains then take an umbrella")
                .when(facts -> facts.get("rain").equals(true))
                .then(facts -> System.out.println("It rains, take an umbrella!"))
                .build();
        Rules rules = new Rules();
        rules.register(weatherRule);

        // define facts
        Facts facts = new Facts();
        facts.put("rain", true);

        // fire rules on known facts
        RulesEngine rulesEngine = new InferenceRulesEngine();
        rulesEngine.fire(rules, facts);
 类似资料: