JAVA规则引擎 - 调研分析设计搭建全过程<一>
规则引擎调研
规则引擎概念:在开发系统以及设计大型系统时候。刚开始业务比较单一,可能考虑不到规则引擎的事情,随着数据量的增长和系统拆分之后,系统复杂度的提升,简单的代码逻辑 if{} - else if{} - else{} 可能满足不了业务的迭代。如果条件越多,累计的代码层次和代码量也是N呗增长。显然不符合程序的需要。对于随时变化的逻辑。不停的变换代码逻辑。发布上线。这样的隐患太大了。当然有些有经验的开发。一般这个时候会考虑优化代码,提高工作效率。但是依然无法解决开发缓慢,需要上线等问题。 举个例子,在风控系统中,因为风控的逻辑在不断的发生一个改变,如果我们在代码中去写死,那么发生一个改变就改一下代码,上一下线,这明显是我们不能接受的。所以我们需要规则引擎去改变这个现状,通过高效可靠的方式去做这些业务规则的改变。
目前市场主流规则引擎调研
1.什么是规则引擎
规则引擎就是可以动态对某一个功能做规则配置。不用修改代码,达到实现功能的操作。特别适合于电商,金融系统,以及会员等级积分维护系统中。比如电商系统促销打折,风控系统交易拦截,金融系统信贷分析等等。
2.目前主流的规则引擎有哪些
目前市场是主流规则引擎,比较成熟的有,drools,urule, easyrule,groovy,aviator,qlexpress 等等,有些是基于界面的,有些是基于代码层面实现的,有些是处理规则表达式的方案。有兴趣的都可以去了解一下。后面也会列举一两个示例。
drools规则引擎demo
drools也有操作界面的方式,配合workbench可以有决策树和决策表导入功能,demo只演示简单代码实现
引入jar包
<!-- drools依赖 -->
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
<version>${drools.version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
<version>${drools.version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-decisiontables</artifactId>
<version>${drools.version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-templates</artifactId>
<version>${drools.version}</version>
</dependency>
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-api</artifactId>
<version>${drools.version}</version>
</dependency>
测试类
public static void main(String[] args) {
//rule,rule2可以放在数据库中,有个唯一code和他们对于,代码要执行规则的时候,根据code从数据库获取出来就OK了,这样自己开发的规则管理系统那边对数据库里的规则进行维护就行了
String rule = "package com.neo.drools\r\n";
rule += "import com.neo.drools.model.Message;\r\n";
rule += "rule \"rule1\"\r\n";
rule += "\twhen\r\n";
rule += "$m:Message( status == 1, myMessage : msg ,$s:status)";
rule += "\tthen\r\n";
rule += "\t\tSystem.out.println( 1+\":\"+myMessage );\r\n";
rule += "\t\tSystem.out.println( 1+\":\"+$s );\r\n";
rule += "end\r\n";
String rule2 = "package com.neo.drools\r\n";
rule += "import com.neo.drools.model.Message;\r\n";
rule += "rule \"rule2\"\r\n";
rule += "\twhen\r\n";
rule += "Message( status == 2, myMessage : msg )";
rule += "\tthen\r\n";
rule += "\t\tSystem.out.println( 2+\":\"+myMessage );\r\n";
rule += "end\r\n";
StatefulKnowledgeSession kSession = null;
try {
KnowledgeBuilder kb = KnowledgeBuilderFactory.newKnowledgeBuilder();
//装入规则,可以装入多个
kb.add(ResourceFactory.newByteArrayResource(rule.getBytes("utf-8")), ResourceType.DRL);
kb.add(ResourceFactory.newByteArrayResource(rule2.getBytes("utf-8")), ResourceType.DRL);
KnowledgeBuilderErrors errors = kb.getErrors();
for (KnowledgeBuilderError error : errors) {
System.out.println(error);
}
KnowledgeBase kBase = KnowledgeBaseFactory.newKnowledgeBase();
kBase.addKnowledgePackages(kb.getKnowledgePackages());
kSession = kBase.newStatefulKnowledgeSession();
Message message1 = new Message();
message1.setStatus(1);
message1.setMsg("hello world!");
Message message2 = new Message();
message2.setStatus(2);
message2.setMsg("hi world!");
kSession.insert(message1);
kSession.insert(message2);
kSession.fireAllRules();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} finally {
if (kSession != null)
kSession.dispose();
}
}
AviatorScript参考使用demo
引入jar
<dependency>
<groupId>com.googlecode.aviator</groupId>
<artifactId>aviator</artifactId>
<version>5.2.6</version>
</dependency>
测试
@SpringBootTest
@RunWith(SpringRunner.class)
@Slf4j
class DroolsApplicationTests {
// 简单判断
@Test
public void people2() throws IllegalAccessException, NoSuchMethodException {
System.out.println("-----------------------------------------------------------------");
System.out.println("算术表达式【1+1】: " + AviatorEvaluator.execute("1+1"));
System.out.println("逻辑表达式【1==1】: " + AviatorEvaluator.execute("1==1"));
System.out.println("三元表达式【1==1 ? '对' : '错'】: " + AviatorEvaluator.execute("1==1 ? '对' : '错'"));
System.out.println("函数调用【6的3次方】: " + AviatorEvaluator.execute("math.pow(6,3)"));
System.out.println("-----------------------------------------------------------------"+AviatorEvaluator.addStaticFunctions("str", StringUtils.class));
}
//测试输入一个参数
@Test
public void rule() {
//首先构造参数
Map<String, Object> env = new HashMap<String, Object>();
env.put("orderAmount", 101);
env.put("vip", true);
// 执行表达式逻辑
Boolean result = (Boolean) AviatorEvaluator.execute("orderAmount > 100 && vip", env);
System.out.println(result);
}
//判断嵌套对象取值
@Test
public void rule2() {
//首先构造参数
Order order = new Order();
order.setOrderAmount(101);
order.setVip(true);
order.setId("12345");
OrderItem orderItem = new OrderItem();
orderItem.setSku("sku1");
orderItem.setColor("color1");
order.setOrderItem(orderItem);
Map<String, Object> env = JSONObject.parseObject(JSONObject.toJSONString(order),Map.class);
// 执行表达式逻辑
Boolean result = (Boolean) AviatorEvaluator.execute("orderAmount > 100 && vip && orderItem.sku == 'sku1'", env);
System.out.println(result);
}
//判断集合中是否包含某个元素
@Test
public void rule3() {
//首先构造参数
List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
Map<String, Object> env = new HashMap<>();
env.put("aa",list);
// 执行表达式逻辑
Boolean result = (Boolean) AviatorEvaluator.execute("include(aa, 'd')", env);
System.out.println(result);
}
}
easyrule规则引擎demo
引入jar包
测试类
@Rule(priority = 1)
public class ConRule1 {
@Condition
public boolean isTest(@Fact("biz") String biz) {
return biz == "条件1";
}
@Action
public void process(Facts facts) {
String tradeNo = facts.get("tradeNo");
facts.put("tradeNo", "tutor" + tradeNo);
}
}
@Rule(priority = 2)
public class ConRule2{
@Condition
public boolean isBanma(@Fact("biz") String biz) {
return biz == "条件2";
}
@Action
public void process(Facts facts) {
String tradeNo = facts.get("tradeNo");
facts.put("tradeNo", "conan" + tradeNo);
}
}
githup,gitee等平台规则开源规则引擎
这里开源的比较多。大家可以自己去搜索,githup, gitee等平台