日常生活是由规则驱动的。红灯停绿灯行,这是我们的交通规则;我们站着往上跳,最终还是要落下来,这是地球的引力规则。规则在生活中无处不在。软件开发中我们也需要规则,满足什么规则应该进入什么分支。如果做过风控系统,就知道风控系统里存在非常多的规则(比如:age < 16 || age > 50 -> REJECT )。最便捷的实现就是用 if-else 来写,但是随着规则的增加以及需求的变动,代码将变得越来越难阅读和理解,如果再去修改这些代码,然后测试不够充分的话,将产生严重的生产事故。这时候就要引入Drools等规则引擎了。Drools就是为了解决业务代码和业务规则分离的引擎。
要使用Drools规则引擎,需要先安装安装JBoss Drools Support插件,这里就不多说怎么安装安装JBoss Drools Support插件。下载地址如下:
https://download.jboss.org/dr...
1、 新建项目sc-activiti-drools,对应的pom.xml文件如下
4.0.0
com.sc
sc-activiti-drools
0.0.1-SNAPSHOT
sc-activiti-drools
http://www.example.com
UTF-8
1.8
1.8
org.springframework.boot
spring-boot-starter-parent
2.0.4.RELEASE
org.springframework.cloud
spring-cloud-dependencies
Finchley.RELEASE
pom
import
org.springframework.boot
spring-boot-starter-web
org.activiti
activiti-engine
6.0.0
org.activiti
activiti-spring
6.0.0
mysql
mysql-connector-java
runtime
org.drools
drools-core
7.0.0.Final
org.drools
drools-compiler
7.0.0.Final
org.drools
knowledge-api
6.5.0.Final
maven-clean-plugin
3.0.0
maven-resources-plugin
3.0.2
maven-compiler-plugin
3.7.0
maven-surefire-plugin
2.20.1
maven-jar-plugin
3.0.2
maven-install-plugin
2.5.2
maven-deploy-plugin
2.8.2
2、新建spring配置文件application.yml
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/sc?characterEncoding=utf8&useSSL=true
username: root
password: root
activiti:
check-process-definitions: false #自动部署验证设置:true-开启(默认)、false-关闭
jpa:
properties:
hibernate:
hbm2ddl:
auto: update
show-sql: true
server:
port: 8081
context-path: /
session:
timeout: 10
tomcat:
uri-encoding: UTF-8
3、新建activiti对应的配置文件activiti.cfg.xml
4、新建请假流程对应的bpmn文件如下
= 10}]]>
bpmn文件对应的图如下
package sc.ad;
import sc.ad.model.Leave;
rule "leave1"
when
u : Leave(day < 3);
then
u.setTotal(u.getDay() + 2);
end
rule "leave2"
when
u : Leave(day >= 3);
then
u.setTotal(u.getDay() + 5);
end
package sc.ad;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ImportResource;
@SpringBootApplication
@ImportResource("activiti.cfg.xml")
public class ActivitiDroolsApp {
public static void main(String[] args)
{
SpringApplication.run(ActivitiDroolsApp.class, args);
}
}
7、新建一个controller,用来发起请假请求
package sc.ad.controller;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.DeploymentBuilder;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import sc.ad.model.Leave;
@RestController
public class ADController {
@Autowired
private RepositoryService repositoryService;
@Autowired
private RuntimeService runtimeService;
@Autowired
private TaskService taskService;
// @RequestMapping("/ad")
// public void ad() {
//
// // 根据bpmn文件部署流程
// Deployment deployment = repositoryService.createDeployment()
// .addClasspathResource("holiday.bpmn").deploy();
// // 获取流程定义
// ProcessDefinition processDefinition = repositoryService
// .createProcessDefinitionQuery()
// .deploymentId(deployment.getId()).singleResult();
// // 启动流程定义,返回流程实例
// ProcessInstance pi = runtimeService
// .startProcessInstanceById(processDefinition.getId());
// String processId = pi.getId();
// System.out.println("流程创建成功,当前流程实例ID:" + processId);
//
// Task task = taskService.createTaskQuery().processInstanceId(processId)
// .singleResult();
// System.out.println("第一次执行前,任务名称:" + task.getName());
// taskService.complete(task.getId());
//
// task = taskService.createTaskQuery().processInstanceId(processId)
// .singleResult();
// System.out.println("第二次执行前,任务名称:" + task.getName());
// taskService.complete(task.getId());
//
// task = taskService.createTaskQuery().processInstanceId(processId)
// .singleResult();
// System.out.println("task为null,任务执行完毕:" + task);
// }
@RequestMapping("/drl")
public void drl() {
/**
* 注意这里:必须要把drl文件一起deploy
*/
DeploymentBuilder deploy = repositoryService.createDeployment();
deploy.addClasspathResource("leave.bpmn").addClasspathResource("leave.drl");
deploy.deploy();
ProcessInstance pi = runtimeService.startProcessInstanceByKey("leave");
Map vars = new HashMap();
vars.put("leave", new Leave("白展堂", 12));
/**
* 当前任务
*/
List tasks = taskService.createTaskQuery().processInstanceId(pi.getId()).list();
for(Task task : tasks)
{
System.out.println(task.getId() + " , " + task.getName());
taskService.complete(task.getId(), vars);
}
/**
* 下一步任务
*/
tasks = taskService.createTaskQuery().processInstanceId(pi.getId()).list();
for(Task task : tasks)
{
System.out.println(task.getId() + " , " + task.getName());
}
}
}
8、启动并验证规则是否生效
从日志中看启动成功
把修改controller的如下代码
vars.put("leave", new Leave("白展堂", 12));
改成
vars.put("leave", new Leave("乔峰", 2));
![image.png](/img/bVbGqWV)