实现动态业务规则的方法(Java)

企业信息化系统核心在于业务领域的概念模型及于此基础上复杂多变的业务规则,实现中通常抽象规则的接口方法,使用继承或策略等设计模式实现不同的业务规则的实现。领域的概念模型在特定领域是稳定的,比如,采购场景下的报价模型包括是:报价供应商、价格、税率、汇率、报价标的物有效数量、有效地点、有效时间、送货时间等业务概念。从定标规则,从众多报价中选择最终报价的规则则在不同企业,不同商品都有则不同,如按最低价、按最高价(卖出场景)、按最快送货、按供应商评分等等可能的选择方式,在每次规则变化的时候重新迭代实现是一种方式,编写业务规则并支持动态替换执行是另一种选择。 本文介绍了Java实现动态业务规则几种方法。

Java动态类装载

基本流程如下:

  1. 将新业务以Java实现, 并编译成class文件,上传至类路径下。
  2. 实现ClassLoader在运行时加载类。
  3. 使用放射或Spring容器Bean管理等方法使用新的类实现。

Spring 中动态加载类替换Bean的一个示例过程:

脚本引擎

Java 内置的Nashorn引擎支持在Java中执行JavaScript 代码。ScriptEngineManager是Nashorn引擎的API。使用方法如下:

  1. 获取脚本引擎
  2. 设置参数
  3. 编译JavaScript脚本。
  4. 执行编译后的JavaScript脚本获取结果。也可以直接跳过编译,直接执行原始脚本,这样会在每次执行都重新编译,会带来极大的性能损耗问题。

示例代码如下:

引擎也支持将脚本编译为方法供Java代码调用,但从耦合角度并不是很好的实践,脚本应尽可能的实现单一职能、独立的规则。而不是耦合到一个复杂逻辑中。

表达式引擎

表达式引擎是根据传入参数执行计算公式或特定表达式并返回结果的工具。表达式引擎通道都使用类java的语法规则,可以方便的和java运行时不同类型的数据对象进行交互,强调高效的性能。另外也有源自金融领域,专门提供各类数学计算公式的表达式引擎。 如Express4j。表达式引擎和脚本引擎比起来更轻量化,更强调性能。

表达式引擎的应用场景如定义一个风险规则表达式,当执行业务逻辑前对输入数据是进行检查。

在Spring 项目推荐使用SPEL进行表达式计算。

Fel 样例:

FelEngine fel = new FelEngineImpl();

Object result = fel.eval(“3000*10+7500”);

System.out.println(result);

Ognl样例:

Ognl.getValue("#user.name", context, user)

Express4j 样例:

Expression expression = ExpressionFactory.createExpression("f()=abs(-3)");

expression.evaluate(null).getRealValue();

SPEL 样例:

SpelExpressionParser parser = new SpelExpressionParser();

StandardEvaluationContext standardEvaluationContext = new StandardEvaluationContext();

standardEvaluationContext.setBeanResolver(new BeanFactoryResolver(applicationContext));

parser.parseExpression("@testService.test()").getValue(standardEvaluationContext, Boolean.class);

规则引擎

脚本引擎提供的是脚本执行能力,表达式引擎提供的是表达式计算能力,规则引擎是供以规则为核心的编程模型。规则引擎通常支持多种表达式语言引擎作为规则条件的执行引擎。

脚本引擎、表达式引擎是工具,规则引擎是框架或者甚至是产品(Drools)。

Drools

Drools是一种业务规则管理系统(BRMS)解决方案。它提供了一个核心业务规则引擎(BRE)、一个创建和管理规则web应用程序(Drools Workbench)、对Decision Model and Notation (DMN)提供了一致性级别中Level3的支持,同时提供了IDE的开发插件。

    Drools是一个重量级的规则引擎产品,很多像金融行业、电信行业的大公司都使用它作为规则引擎。

项目官网:Drools - Drools - Business Rules Management System (Java™, Open Source)
项目地址:GitHub - kiegroup/drools: Mirror of https://github.com/apache/incubator-kie-drools

在项目中如果仅仅是使用Drools的规则引擎核心BRE,可以引入依赖Maven使用,也可以使用BRMS的整套解决方案以Drools为核心构建业务系统。
 

样例:

  1. 规则文件: 对有效期内账户对象的存取行为进行余额增加或扣减。
  1. 触发执行引擎

EasyRules

EasyRules是一个轻量的规则引擎框架, 它提供了Rule抽象来创建带有条件和操作的规则,以及使用API:RulesEngine。

主要特性:

  1. 轻量化的库,易于使用的API
  2. 提供基于注解的,POJO模型。
  3. 为Java提供为定义业务规则的良好抽象。
  4. 可以通过简单规则组合成为复杂规则。
  5. 可以使用表达式语言定义规则(如SPEL,MVEL,见表达式引擎)

项目地址:https://github.com/j-easy/easy-rules

样例:

  1. 通过类注解定义规则:@Rule、@Condition、@Action

Rule: 当Ccondition满足,则执行Action

  1. 通过文件定制规则
  1. 执行规则
09-27 03:31