最新Java规则引擎easy-rules详细介绍(2),java虚拟机内存模型面试

总结

这个月马上就又要过去了,还在找工作的小伙伴要做好准备了,小编整理了大厂java程序员面试涉及到的绝大部分面试题及答案,希望能帮助到大家

在这里插入图片描述

在这里插入图片描述

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

// 从两个原始规则创建组合规则

UnitRuleGroup myUnitRuleGroup =

new UnitRuleGroup(“myUnitRuleGroup”, “unit of myRule1 and myRule2”);

myUnitRuleGroup.addRule(myRule1);

myUnitRuleGroup.addRule(myRule2);

// 像常规规则一样注册组合规则

Rules rules = new Rules();

rules.register(myUnitRuleGroup);

RulesEngine rulesEngine = new DefaultRulesEngine();

rulesEngine.fire(rules, someFacts);

复制代码

规则优先级

Easy Rules中的每个规则都有一个优先级。这表示触发注册规则的默认顺序。默认情况下,值越低优先级越高。要覆盖此行为,您应该重写compareTo()方法以提供自定义优先级策略。

  • 如果是继承BasicRule,可以在构造方法中指定优先级,或者重写getPriority()方法。

  • 如果是使用POJO定义规则,可以通过@Rule注解的priority属性指定优先级,或者使用@Priority注解标记一个方法。这个方法必须是public,无参却返回类型为Integer

  • 如果使用RuleBuilder定义规则,可以使用RuleBuilder#priority()方法指定优先级。

Rules API

Easy rules中的一组规则由rules API表示。它的使用方法如下:

Rules rules = new Rules();

rules.register(myRule1);

rules.register(myRule2);

复制代码

Rules表示已注册规则的命名空间,因此,在同一命名空间下,每一个已经注册的规则必须有唯一的名称

Rules是通过Rule#compareTo()方法进行比较的,因此,Rule的实现应该正确的实现compareTo()方法来确保单一空间下拥有唯一的规则名称。

定义事实


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

public class Fact {

private final String name;

private final T value;

}

复制代码

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

下面是一个如何定义事实的例子:

Fact fact = new Fact(“foo”, “bar”);

Facts facts = new Facts();

facts.add(fact);

复制代码

你也可以使用一个更短的版本,用put方法创建命名的事实,如下所示:

Facts facts = new Facts();

facts.put(“foo”, “bar”);

复制代码

可以使用@Fact注解将事实注入到规则的条件和操作方法中。在以下规则中,rain事实被注入到itRains方法的rain参数中:

@Rule

class WeatherRule {

@Condition

public boolean itRains(@Fact(“rain”) boolean rain) {

return rain;

}

@Action

public void takeAnUmbrella(Facts facts) {

System.out.println(“It rains, take an umbrella!”);

// can add/remove/modify facts

}

}

复制代码

类型为Facts的参数将被注入所有已知的事实。

注意:

  • 如果条件方法中缺少注入的事实,引擎将记录一个警告,并认为条件被计算为false

  • 如果动作方法中缺少注入的事实,则不会执行该动作,并且抛出org.jeasy.rules.core.NoSuchFactException异常。

定义规则引擎


Easy Rules提供了RulesEngine接口的两种实现:

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

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

创建规则引擎

可以使用构造方法创建规则引擎。

RulesEngine rulesEngine = new DefaultRulesEngine();

// or

RulesEngine rulesEngine = new InferenceRulesEngine();

复制代码

可以按如下方式触发已注册的规则。

rulesEngine.fire(rules, facts);

复制代码

规则引擎参数

Easy Rules引擎可以配置以下参数:

| 参数 | 类型 | 默认值 |

| — | — | — |

| rulePriorityThreshold | int | MaxInt |

| skipOnFirstAppliedRule | boolean | false |

| rulePriorityThreshold | int | false |

| skipOnFirstFailedRule | boolean | false |

| skipOnFirstNonTriggeredRule | boolean | false |

  • skipOnFirstAppliedRule:当一个规则成功应用时,跳过余下的规则。

  • skipOnFirstFailedRule:当一个规则失败时,跳过余下的规则。

  • skipOnFirstNonTriggeredRule:当一个规则未触发时,跳过余下的规则。

  • rulePriorityThreshold:当优先级超过指定的阈值时,跳过余下的规则。

可以使用RulesEngineParameters API指定这些参数:

RulesEngineParameters parameters = new RulesEngineParameters()

.rulePriorityThreshold(10)

.skipOnFirstAppliedRule(true)

.skipOnFirstFailedRule(true)

.skipOnFirstNonTriggeredRule(true);

RulesEngine rulesEngine = new DefaultRulesEngine(parameters);

复制代码

如果你想从你的引擎中获取参数,你可以使用以下代码段:

RulesEngineParameters parameters = myEngine.getParameters();

复制代码

这允许在创建引擎参数后重新设置引擎参数。

定义规则监听器


可以通过RuleListener API来监听规则执行事件:

public interface RuleListener {

/**

  • 在评估规则之前触发。

  • @param rule 正在被评估的规则

  • @param facts 评估规则之前的已知事实

  • @return 如果规则应该评估,则返回true,否则返回false

*/

default boolean beforeEvaluate(Rule rule, Facts facts) {

return true;

}

/**

  • 在评估规则之后触发

  • @param rule 评估之后的规则

  • @param facts 评估规则之后的已知事实

  • @param evaluationResult 评估结果

*/

default void afterEvaluate(Rule rule, Facts facts, boolean evaluationResult) { }

/**

  • 运行时异常导致条件评估错误时触发

  • @param rule 评估之后的规则

  • @param facts 评估时的已知事实

  • @param exception 条件评估时发生的异常

*/

default void onEvaluationError(Rule rule, Facts facts, Exception exception) { }

/**

  • 在规则操作执行之前触发。

  • @param rule 当前的规则

  • @param facts 执行规则操作时的已知事实

*/

default void beforeExecute(Rule rule, Facts facts) { }

/**

  • 在规则操作成功执行之后触发

  • @param rule t当前的规则

  • @param facts 执行规则操作时的已知事实

*/

default void onSuccess(Rule rule, Facts facts) { }

/**

  • 在规则操作执行失败时触发

  • @param rule 当前的规则

  • @param facts 执行规则操作时的已知事实

  • @param exception 执行规则操作时发生的异常

*/

default void onFailure(Rule rule, Facts facts, Exception exception) { }

}

复制代码

可以实现这个接口来提供自定义行为,以便在每个规则之前/之后执行。要注册监听器,请使用以下代码段:

DefaultRulesEngine rulesEngine = new DefaultRulesEngine();

rulesEngine.registerRuleListener(myRuleListener);

复制代码

可以注册任意数量的侦听器,它们将按照注册顺序执行。

注意:当使用组合规则时,监听器是围绕组合规则调用的。

定义规则引擎监听器


可以通过RulesEngineListener API来监听规则引擎的执行事件:

public interface RulesEngineListener {

/**

  • 在执行规则集之前触发

  • @param rules 要触发的规则集

  • @param facts 触发规则前的事实

*/

default void beforeEvaluate(Rules rules, Facts facts) { }

/**

  • 在执行规则集之后触发

  • @param rules 要触发的规则集

  • @param facts 触发规则前的事实

*/

default void afterExecute(Rules rules, Facts facts) { }

}

复制代码

RulesEngineListener允许我们在触发整个规则集之前/之后提供自定义行为。可以使用如下方式注册监听器。

DefaultRulesEngine rulesEngine = new DefaultRulesEngine();

rulesEngine.registerRulesEngineListener(myRulesEngineListener);

复制代码

可以注册任意数量的监听器,它们将按照注册顺序执行。

表达式语言(EL)支持


Easy Rules支持用MVELSpELJEXL定义规则。

EL提供者注意事项

EL提供者在行为上有一些区别。例如,当一个事实在条件中缺失时,MVEL抛出一个异常,而SpEL将忽略它并返回false。因此,在选择Easy Rules使用哪个EL之前,你应该了解这些差异。

通过编程的方式定义规则

条件、动作和规则分别由MVELCondition/SpELCondition/JexlConditionMVELAction/SpELAction/JexlActionMVELRule/SpELRule/JexlRule类表示。下面是一个使用MVEL定义规则的例子:

Rule ageRule = new MVELRule()

.name(“age rule”)

.description(“Check if person’s age is > 18 and marks the person as adult”)

.priority(1)

.when(“person.age > 18”)

.then(“person.setAdult(true);”);

复制代码

通过规则描述文件定义规则

可以使用规则描述文件定义规则,使用MVELRuleFactory/SpELRuleFactory/JexlRuleFactory来从描述符文件创建规则。下面是一个在alcohol-rule.yml中以YAML格式定义的MVEL规则示例:

name: “alcohol rule”

description: “children are not allowed to buy alcohol”

priority: 2

condition: “person.isAdult() == false”

actions:

  • “System.out.println(“Shop: Sorry, you are not allowed to buy alcohol”);”

复制代码

MVELRuleFactory ruleFactory = new MVELRuleFactory(new YamlRuleDefinitionReader());

MVELRule alcoholRule = ruleFactory.createRule(new FileReader(“alcohol-rule.yml”));

复制代码

还可以使用一个文件创建多个规则。


name: adult rule

description: when age is greater than 18, then mark as adult

priority: 1

condition: “person.age > 18”

actions:

  • “person.setAdult(true);”

name: weather rule

description: when it rains, then take an umbrella

priority: 2

condition: “rain == true”

actions:

  • “System.out.println(“It rains, take an umbrella!”);”

复制代码

可以使用如下方式将这些规则加载到rules对象中。

MVELRuleFactory ruleFactory = new MVELRuleFactory(new YamlRuleDefinitionReader());

Rules rules = ruleFactory.createRules(new FileReader(“rules.yml”));

复制代码

Easy Rules还支持从JSON描述符加载规则。具体参考文档,这里不做展开。

规则定义中的错误处理

关于条件中不正确表达式的引擎行为

对于条件求值过程中可能发生的任何运行时异常(丢失事实、表达式中输入错误等),引擎将记录一个警告,并认为条件求值为false。可以使用RuleListener#onEvaluationError来监听评估错误。

关于操作中不正确表达式的引擎行为

对于任何在执行操作时可能发生的运行时异常(丢失事实、表达式中输入错误等),该操作将不会执行,引擎将记录一个错误。可以使用RuleListener#onFailure来监听操作执行异常。当一个规则失败时,引擎将移动到下一个规则,除非设置了skipOnFirstFailedRule参数。

实际栗子

====

本栗子使用Easy Rules实现FizzBuzz应用程序。FizzBuzz是一个简单的应用程序,需要从1数到100,并且:

  • 如果数字是5的倍数,则打印“fizz”

  • 如果数字是7的倍数,请打印“buzz”

  • 如果数字是5和7的倍数,请打印“fizzbuzz”

  • 否则打印数字本身

public class FizzBuzz {

public static void main(String[] args) {

for(int i = 1; i <= 100; i++) {

if (((i % 5) == 0) && ((i % 7) == 0))

System.out.print(“fizzbuzz”);

else if ((i % 5) == 0) System.out.print(“fizz”);

else if ((i % 7) == 0) System.out.print(“buzz”);

else System.out.print(i);

System.out.println();

}

最后

面试前一定少不了刷题,为了方便大家复习,我分享一波个人整理的面试大全宝典

  • Java核心知识整理

2020年五面蚂蚁、三面拼多多、字节跳动最终拿offer入职拼多多

Java核心知识

  • Spring全家桶(实战系列)

2020年五面蚂蚁、三面拼多多、字节跳动最终拿offer入职拼多多

  • 其他电子书资料

2020年五面蚂蚁、三面拼多多、字节跳动最终拿offer入职拼多多

Step3:刷题

既然是要面试,那么就少不了刷题,实际上春节回家后,哪儿也去不了,我自己是刷了不少面试题的,所以在面试过程中才能够做到心中有数,基本上会清楚面试过程中会问到哪些知识点,高频题又有哪些,所以刷题是面试前期准备过程中非常重要的一点。

以下是我私藏的面试题库:

2020年五面蚂蚁、三面拼多多、字节跳动最终拿offer入职拼多多

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

.print(“fizz”);

else if ((i % 7) == 0) System.out.print(“buzz”);

else System.out.print(i);

System.out.println();

}

最后

面试前一定少不了刷题,为了方便大家复习,我分享一波个人整理的面试大全宝典

  • Java核心知识整理

[外链图片转存中…(img-tDDTtIt9-1715640323672)]

Java核心知识

  • Spring全家桶(实战系列)

[外链图片转存中…(img-qDkN5J1p-1715640323672)]

  • 其他电子书资料

[外链图片转存中…(img-XhkeR0i1-1715640323672)]

Step3:刷题

既然是要面试,那么就少不了刷题,实际上春节回家后,哪儿也去不了,我自己是刷了不少面试题的,所以在面试过程中才能够做到心中有数,基本上会清楚面试过程中会问到哪些知识点,高频题又有哪些,所以刷题是面试前期准备过程中非常重要的一点。

以下是我私藏的面试题库:

[外链图片转存中…(img-UayN0KPg-1715640323673)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • 13
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Easy-rules是一个轻量级的Java规则引擎,可以帮助我们在应用程序中使用规则来进行业务逻辑处理。在Spring-boot中使用Easy-rules需要以下步骤: 1. 添加Easy-rules依赖 在pom.xml文件中添加Easy-rules依赖: ```xml <dependency> <groupId>org.easyrules</groupId> <artifactId>easy-rules-core</artifactId> <version>4.1.0</version> </dependency> ``` 2. 创建规则 创建一个规则类,继承自`org.easyrules.core.BasicRule`,并实现`org.easyrules.api.Rules`接口中的方法。例如: ```java public class AdultRule extends BasicRule { private Person person; public AdultRule(Person person) { super("AdultRule", "Check if person is an adult", 1); this.person = person; } @Override public boolean evaluate() { return person.getAge() >= 18; } @Override public void execute() throws Exception { System.out.println(person.getName() + " is an adult"); } } ``` 3. 配置规则引擎 在Spring-boot的配置类中配置规则引擎: ```java @Configuration public class RuleEngineConfiguration { @Bean public RulesEngine rulesEngine() { return new DefaultRulesEngine(); } } ``` 4. 执行规则 在需要执行规则的地方,注入规则引擎,然后将规则添加到规则引擎中并执行: ```java @Autowired private RulesEngine rulesEngine; public void executeRules(Person person) { Rules rules = new Rules(); rules.register(new AdultRule(person)); rulesEngine.fire(rules); } ``` 这样就可以在Spring-boot中使用Easy-rules规则引擎了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值