流程引擎之KIE项目简介

一、KIE 工程是什么

近期学习流程 jBPM 引擎时,发现 jBPM 是基于 jBoss 公司的 KIE 工程建设的,所以在学习 jBPM 之前需要弄明白 KIE 工程是什么。KIE 是“Knowledge Is Everything”的简称,KIE 名称也被用于系统的共享方面,比如统一构建、部署和使用。jBoss 公司通过 KIE 将 jBPM 和 Drools 等相关项目进行了一个整合,统一了他们的使用方式。目前 KIE 子工程如下:

KIE 工程或者模块只是一个 Maven Java 项目或者模块,并包括了元数据文件 META-INF/kmodule.xml。kmodule.xml 是为 KIE bases 选择资源,并配置 KIE bases 和 sessions,推荐使用 Mavan 插件 kie-maven-plugin 来构造和打包。

 <build>
    <plugins>
      <plugin>
        <groupId>org.kie</groupId>
        <artifactId>kie-maven-plugin</artifactId>
        <version>6.2.0.Final</version>
        <extensions>true</extensions>
      </plugin>
    </plugins>
  </build>

KIE 使用默认值来最小化配置量, kmodule.xml 必不可少,空的 kmodule.xml 是最简单的配置,主要用来发现 jar 的内容。KIE 将扫描类路径并查找包含 kmodule.xml 的所有 jar,并使用 KieModule 接口来表示。

二、KIE 工程使用示例

1)代码示例地址

2)使用示意图

kie 工程使用比较简单,以 jBPM 流程文件为例,首先需要使用 kie-maven-plugin 插件将资源打成 jar 包并上传到指定仓库,然后应用程序直接从指定仓库拉取,并在每次会话话中使用即可,如下图所示:

3)代码示例

以 kie-maven-plugin 插件打包的本地仓库为例,下面示例源码地址:https://download.csdn.net/download/zhuqiuhui/87452118

三、KIE 工程的生命周期

KIE 工程的生命周期如下图所示,下面重点讲一下构建、部署和运行三个阶段。

3.1 构建(Building)

1)作用

KIE 工程构造的过程就是将资源文件打包成 jar 包的过程。Kie 组件(例如 DRL 或 Excel 文件)必须存储在 resources 文件夹或其下的任何其他子文件夹中,编译过程会把这些组件加入到 jar 包中。

2)核心类

构建过程涉及几个核心类:

KieServices

KieServices 是访问所有 Kie 构建和运行时设施的接口,KieServices 充当集线器的角色为其他服务提供线程安全的单例。

KieContainer

所有 Java 源代码和 Kie 资源都被编译并部署到 KieContainer 中,使其内容可在运行时使用。

KieBase

KieBase 是应用程序知识定义的存储库。它包含了规则、流程、函数和类型模型。KieBase 本身不包含数据,而是从 KieBase 中创建 sessions,可以在其中插入数据并启动流程实例。KieBase 可以从 KieContainer 中获取或者从已经定义 KieBase 的 kmodule 获取。

KieBase kBase = kContainer.getKieBase();
KieSession

KieSession 存储和执行运行时数据,如果它已在 kmodule.xml 文件中定义,则它是从 KieBase 中创建或直接 KieContainer 中创建。

KieModule

像 maven 的 pom 文件定义 ReleaseId 一样,KieModule 是定义 KieBase 的容器,一个 kmodule.xml 文件声明了 KieBase 和 KieSession 相关的配置。

怎么定义 KieModule?
  • Case 1:使用 kmodule.xml

<!--示例一:空的 kmodule.xml 文件-->
<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns="http://www.drools.org/xsd/kmodule"/>

<!--示例二-->
<kmodule xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://www.drools.org/xsd/kmodule">
  <configuration>
    <property key="drools.evaluator.supersetOf" value="org.mycompany.SupersetOfEvaluatorDefinition"/>
  </configuration>
  <kbase name="KBase1" default="true" eventProcessingMode="cloud" equalsBehavior="equality" declarativeAgenda="enabled" packages="org.domain.pkg1">
    <ksession name="KSession2_1" type="stateful" default="true"/>
    <ksession name="KSession2_2" type="stateless" default="false" beliefSystem="jtms"/>
  </kbase>
  <kbase name="KBase2" default="false" eventProcessingMode="stream" equalsBehavior="equality" declarativeAgenda="enabled" packages="org.domain.pkg2, org.domain.pkg3" includes="KBase1">
    <ksession name="KSession3_1" type="stateful" default="false" clockType="realtime">
      <fileLogger file="drools.log" threaded="true" interval="10"/>
      <workItemHandlers>
        <workItemHandler name="name" type="org.domain.WorkItemHandler"/>
      </workItemHandlers>
      <calendars>
        <calendar name="monday" type="org.domain.Monday"/>
      </calendars>
      <listeners>
        <ruleRuntimeEventListener type="org.domain.RuleRuntimeListener"/>
        <agendaEventListener type="org.domain.FirstAgendaListener"/>
        <agendaEventListener type="org.domain.SecondAgendaListener"/>
        <processEventListener type="org.domain.ProcessListener"/>
      </listeners>
    </ksession>
  </kbase>
</kmodule>

其中 kmodule.xml 标签的详细解释参考 drools 官方文档:https://docs.jboss.org/drools/release/7.23.0.Final/drools-docs/html_single/index.html#_kiemoduleintroductionbuildingintroductionsection

  • Case 2:以编程方式来定义 KieModule

当 KieFileSystem 的内容成功构建时,KieModule 结果会自动添加到 KieRepository,KieRepository 是一个单例,用来存储所有的 KieModule(即KieRepository 可以用来增加和删除 KieModule)。

 @Test
public void test() {
    KieServices kieServices = KieServices.Factory.get();
    KieResources resources = kieServices.getResources();
    KieModuleModel kieModuleModel = kieServices.newKieModuleModel();//1
    
    KieBaseModel baseModel = kieModuleModel.newKieBaseModel("FileSystemKBase").addPackage("rules");//2
    baseModel.newKieSessionModel("FileSystemKSession");//3
    
    KieFileSystem fileSystem = kieServices.newKieFileSystem();
    String xml = kieModuleModel.toXML();
    System.out.println(xml);//4
    fileSystem.writeKModuleXML(xml);//5
    
    fileSystem.write("src/main/resources/rules/rule.drl",
                     resources.newClassPathResource("kiefilesystem/KieFileSystemTest.drl"));//6
    
    KieBuilder kb = kieServices.newKieBuilder(fileSystem);
    kb.buildAll();//7
    if (kb.getResults().hasMessages(Level.ERROR)) {
        throw new RuntimeException("Build Errors:\n" + kb.getResults().toString());
    }
    
    KieContainer kContainer = kieServices.newKieContainer(kieServices.getRepository().getDefaultReleaseId());
    assertNotNull(kContainer.getKieBase("FileSystemKBase"));
    KieSession kSession = kContainer.newKieSession("FileSystemKSession");
}

3.2 部署(Deploying)

1)作用

这一步将构建的本地 jar 包 deploy 到远程仓库中,以便在运行中使用。

2)核心类
KieScanner

KieScanner 是 maven 仓库(本地和远程)的扫描器,用于自动发现给定 KieModule 及其依赖项是否有新版本,并最终将它们部署到 KieRepository。使用示例代码如下:

KieServices kieServices = KieServices.Factory.get();
ReleaseId releaseId = kieServices.newReleaseId( "org.acme", "myartifact", "1.0-SNAPSHOT" );
KieContainer kContainer = kieServices.newKieContainer( releaseId );
KieScanner kScanner = kieServices.newKieScanner( kContainer );

// Start the KieScanner polling the Maven repository every 10 seconds
kScanner.start( 10000L );

使用 KieScanner 需要引入 kie-ci 依赖。

3.3 运行(Running)

1)运行 demo 示例

KIE 项目运行示例如下:

KieServices ks = KieServices.Factory.get();
KieContainer kContainer = ks.getKieClasspathContainer();
KieBase kbase = kContainer.getKieBase();

RuntimeManager manager = createRuntimeManager(kbase);
RuntimeEngine engine = manager.getRuntimeEngine(null);
KieSession ksession = engine.getKieSession();
TaskService taskService = engine.getTaskService();

ksession.startProcess("com.sample.bpmn.hello"); // 启动流程实例
List<TaskSummary> list = taskService.getTasksAssignedAsPotentialOwner("john", "en-UK");
......

以使用 KIE 项目中的 jBPM 为例,在项目中配置参考:

@Configuration
public class JbpmConfig {

    @Bean
    RuntimeEnvironment runtimeEnvironment(EntityManagerFactory entityManagerFactory) {
        return RuntimeEnvironmentBuilder.Factory.get()
                .newDefaultBuilder().entityManagerFactory(entityManagerFactory)
                .addAsset(ResourceFactory.newClassPathResource("user2.bpmn2"), ResourceType.BPMN2)
                .get();
    }

    @Bean
    RuntimeManager runtimeManager(RuntimeManagerFactory runtimeManagerFactory, RuntimeEnvironment runtimeEnvironment) {
        return runtimeManagerFactory.newSingletonRuntimeManager(runtimeEnvironment);
    }

    @Bean
    RuntimeEngine runtimeEngine(RuntimeManager runtimeManager) {
        return runtimeManager.getRuntimeEngine(EmptyContext.get());
    }

    @Bean
    KieSession kieSession(RuntimeEngine runtimeEngine) {
        KieSession kieSession = runtimeEngine.getKieSession();
        kieSession.getWorkItemManager().registerWorkItemHandler("Broken", new BrokenWorkItemHandler());
        kieSession.getWorkItemManager().registerWorkItemHandler("Human Task", new SystemOutWorkItemHandler());
        return kieSession;
    }

    @Bean
    TaskService taskService(RuntimeEngine runtimeEngine) {
        return runtimeEngine.getTaskService();
    }
    
    //.......
}
2)核心类

核心 uml 图如下:

a. 运行时管理类
RuntimeEnvironment

定义 RuntimeManager 运行时的环境。RuntimeEnvironment 被视为管理器使用的配置模板,该模板是只读的,一旦创建了RuntimeManager,就不能被更改。

RuntimeManager

RuntimeManager 主要负责管理 RuntimeEngine 的实例并将其交付给调用者,为 process 和 user task 交付可执行环境。此外,RuntimeManager 确保在manager 被实例化后,所有组件(比如 timer service、task service 等)都能被配置和引导,以确保它从一开始就具有完整的功能。

RuntimeManager 提供以下配置策略:

  • Singleton:无论多少可用的流程,RuntimeManager 只维护单个 KieSession

  • Per Request:RuntimeManager 为每个请求分别提供 KieSession

  • Per Process Instance:RuntimeManager 维护流程实例和 KieSession 之间的映射,且每个流程实例对应唯一的 KieSession

RuntimeEngine

RuntimeEngine 是与流程引擎和 task service 交互的主要入口点。它确保流程引擎和 task service 得到正确配置。RuntimeEngine 总是由 RuntimeManager 生成,因此永远不会手动创建。RuntimeEngine 封装了 jBPM 引擎的两个重要的组件:KieSession 和 TaskService。

b. KieRuntime

KieRuntime提供了适用于”规则“和”流程“的方法,例如设置全局变量和注册信道。

c. Event Model

从类图中可以发现,所有的 rule 和 process 事件都实现了KieRuntimeEvent。

d. Command 和 CommandExecutor

CommandExecutor 允许在 Session 上执行命令,唯一的区别是 StatelessKieSession 在结束会话之前会自动执行 fireAllRules()方法。示例如下:

StatelessKieSession ksession = kbase.newStatelessKieSession();
ExecutionResults bresults = ksession.execute( CommandFactory.newSetGlobal( "stilton", new Cheese( "stilton" ), true);
Cheese stilton = bresults.getValue( "stilton" );
                                             
// 批量命令
StatelessKieSession ksession = kbase.newStatelessKieSession();

List cmds = new ArrayList();
cmds.add( CommandFactory.newInsertObject( new Cheese( "stilton", 1), "stilton") );
cmds.add( CommandFactory.newStartProcess( "process cheeses" ) );
cmds.add( CommandFactory.newQuery( "cheeses" ) );
ExecutionResults bresults = ksession.execute( CommandFactory.newBatchExecution( cmds ) );
Cheese stilton = ( Cheese ) bresults.getValue( "stilton" );
QueryResults qresults = ( QueryResults ) bresults.getValue( "cheeses" );

四、总结

由于 KIE 项目是 jBPM 和 Drools 等相关项目的整合,KIE API是最顶级的抽象,所以看到核心类会位于不同的依赖中,如 kie-api、jbpm-services-api、drools-core等 jar 包,学习流程引擎时重点需要关注 jbpm 的相关包即可,依赖示意如下:

五、流程引擎系列文章

六、参考

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bboyzqh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值