规则的加载与管理者——KieContainer的获取与其类型的区别(虽然标题是KieContainer,其实说的还是KieServices)

之前梳理了一下有关KieServices的获取,与获取中的代码走向,详情请见:

“万恶”之源的KieServices,获取代码就一行,表面代码越少里面东西就越多,本以为就是个简单的工厂方法,没想到里面弯弯绕绕这么多东西_zcrazy胡说八道的博客-CSDN博客

在我使用drools时,第一行的语句就是获取KieServices,紧接着就是获取KieContainer,就是下面这一句

代码1

KieContainer kContainer = kieServices.getKieClasspathContainer();

然后我就去看了这个getKieClasspathContainer方法的源码,源码如下:

代码2 KieServicesImpl类中的getKieClasspathContainer方法

/**
* 获取类路径容器
* 
* @param containerId 容器Id
* @param classLoader 类加载器
* @return Kie容器
*/
public KieContainer getKieClasspathContainer(String containerId, ClassLoader classLoader) {if (this.classpathKContainer == null) {//如果是第一次调用该方法,这个classpathKContainer肯定是null的//这个变量会在if处理中进行初始化synchronized(this.lock) {//下面的内容为同步内容if (this.classpathKContainer == null) {//将传入的类加载器赋值给当前实例this.classpathClassLoader = classLoader;if (containerId == null) {//如果containerId是null的,则会给当前实例赋值一个UUID作为containerIdthis.classpathKContainerId = UUID.randomUUID().toString();} else {this.classpathKContainerId = containerId;}//会调用KieServices的两个创建方法this.classpathKContainer = this.newKieClasspathContainer(this.classpathKContainerId, 、classLoader);} else if (classLoader != this.classpathClassLoader) {throw new IllegalStateException("There's already another KieContainer created from a different ClassLoader");}}} else if (classLoader != this.classpathClassLoader) {throw new IllegalStateException("There's already another KieContainer created from a different ClassLoader");}if (containerId != null && !this.classpathKContainerId.equals(containerId)) {throw new IllegalStateException("The default global singleton KieClasspathContainer was already created with id " + this.classpathKContainerId);} else {return this.classpathKContainer;}
}

里面的注释是我添加的,如果在正常情况下,第一次调用该方法,会直接进入到newKieClasspathContainer方法中去,源码如下:

代码3 KieServicesImpl中的newKieClasspathContainer方法

public KieContainer newKieClasspathContainer(String containerId, ClassLoader classLoader, ReleaseId releaseId) {KieContainerImpl newContainer;if (containerId == null) {//如果containerId为nullnewContainer = new KieContainerImpl(UUID.randomUUID().toString(), new ClasspathKieProject(classLoader, this.listener, releaseId), (KieRepository)null);return newContainer;} else if (this.kContainers.get(containerId) == null) {//containerId不为null,但是kContainers映射中没有该containerIdnewContainer = new KieContainerImpl(containerId, new ClasspathKieProject(classLoader, this.listener, releaseId), (KieRepository)null, releaseId);KieContainer check = (KieContainer)this.kContainers.putIfAbsent(containerId, newContainer);if (check == null) {//如果check为null,说明kContainers中没有当前的containerId,返回newContainer。return newContainer;} else {//如果check不为null,说明kContainers已经有当前containerIdnewContainer.dispose();throw new IllegalStateException("There's already another KieContainer created with the id " + containerId);}} else {throw new IllegalStateException("There's already another KieContainer created with the id " + containerId);}
}

注释也是我自己添加的,最终就是会返回一个KieContainerImpl的实例,到这里,基本就已经返回一个KieContainer了,工作就结束了,但是凡事就怕琢磨,这个KieContainer到底是个什么呢?

KieContainer:是用于加载和管理规则资源的核心组件

规则资源又是什么呢?

规则资源(Rule Resources)指的是包含业务规则定义的文件,这些规则文件描述了系统在特定条件下应该如何进行推理或决策。

这些规则资源文件通常以.drl、.xls、.dslr、.bpmn等扩展名保存

简单来说,就是咱们项目里面的drl文件需要KieContainer加载,可能后续还有移除,更新,添加等等跟管理相关的操作。

回到代码1中我发现getKieClasspathContainer这个方法,方法名有问题,为什么不是getContainer,而是getKieClasspathContainer,这说明这个Container是由不同种类的,于是我在KieService中又发现了这个方法newKieContainer,为什么有了newKieClasspathContainer,还会有个newKieContainer方法呢?于是我就看了一下源码:

代码4 KieServicesImpl中的newKieContainer方法

public KieContainer newKieContainer(String containerId, ReleaseId releaseId, ClassLoader classLoader) {InternalKieModule kieModule = (InternalKieModule)this.getRepository().getKieModule(releaseId);if (kieModule == null) {throw new RuntimeException("Cannot find KieModule: " + releaseId);} else {if (classLoader == null) {classLoader = kieModule.getModuleClassLoader();}KieProject kProject = new KieModuleKieProject(kieModule, classLoader);if (classLoader != kProject.getClassLoader()) {kProject.init();}KieContainerImpl newContainer;if (containerId == null) {newContainer = new KieContainerImpl(UUID.randomUUID().toString(), kProject, this.getRepository(), releaseId);return newContainer;} else if (this.kContainers.get(containerId) == null) {newContainer = new KieContainerImpl(containerId, kProject, this.getRepository(), releaseId);KieContainer check = (KieContainer)this.kContainers.putIfAbsent(containerId, newContainer);if (check == null) {return newContainer;} else {newContainer.dispose();throw new IllegalStateException("There's already another KieContainer created with the id " + containerId);}} else {throw new IllegalStateException("There's already another KieContainer created with the id " + containerId);}}
}

总体来说newKieContainer方法和newKieClasspathContainer方法的代码很像,但是多出了几步,多出了KieModule的获取,以及KieProject 的获取,从代码里来看获取KieModule就是为了获取KieProject,然后在实例化KieContainerImpl时,让这个KieProject作为参数输入,在newKieClasspathContainer中也有出现KieProject,只不过在newKieClasspathContainer中出现的是ClasspathKieProject,而在newKieContainer中出现的是KieModuleKieProject。

KieServices类提供了两种方法来创建KieContainer对象,分别是newKieClasspathContainer()和newKieContainer(),他们的区别如下:

  • newKieClasspathContainer()

    • 从类路径(classpath)加载规则资源。规则资源通常位于项目的src/main/resources目录下或其他在类路径中的位置。

    • 可以自动扫描类路径中的规则文件并加载它们。

    • 适用于需要将规则文件打包到应用程序中,并在运行时从类路径加载规则资源的场景。

  • newKieContainer(groupId, artifactId, version)

    • 通过Maven坐标(groupId、artifactId和version)指定规则资源的位置。

    • 需要在Maven仓库中存在相应的规则资源(JAR包)。

    • 适用于从远程Maven仓库或本地Maven仓库加载规则资源的场景。

总结

在KieServices中,实例化KieContainer其实就两个方法,一个是从类路径加载规则资源的newKieClasspathContainer,一个是从Maven仓库中加载资源的newKieContainer,如果直接使用getKieClasspathContainer,第一次用会默认使用newKieClasspathContainer,之后再使用就是可以直接获取KieServicesImpl实例中对应的KieContainer。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/95742.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AIGC:【LLM(六)】——Dify:一个易用的 LLMOps 平台

文章目录 一.简介1.1 LLMOps1.2 Dify 二.核心能力三.Dify安装3.1 快速启动3.2 配置 四.Dify使用五.调用开源模型六.接通闭源模型七.在 Dify.AI 探索不同模型潜力7.1 快速切换,测验不同模型的表现7.2 降低模型能力对比和选择的成本 一.简介 1.1 LLMOps LLMOps&…

打印技巧——word中A4排版打印成A3双面对折翻页

在进行会议文件打印时,我们常会遇到需要将A4排版的文件,在A3纸张上进行双面对折翻页打印,本文对设置方式进行介绍: 1、在【布局】选项卡中,点击右下角小箭头,打开页面设置选项卡 1.1在【页边距】中将纸张…

使用EasyExcel实现Excel表格的导入导出

使用EasyExcel实现Excel表格的导入导出 文章目录 使用EasyExcel实现Excel表格的导入导出1.集成easyExcel2.简单导出示例实体与excel列的映射导出excel的代码 3.Excel复杂表头导出与实体的映射导出代码 3.Excel导入 Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们…

nginx代理webSocket链接响应403

一、场景 使用nginx代理webSocket链接,nginx响应403 1、nginx访问日志响应403 [18/Aug/2023:09:56:36 0800] "GET /FS_WEB_ASS/webim_api/socket/message HTTP/1.1" 403 5 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit…

SpringBoot 微人事 职称管理模块(十三)

职称管理前端页面设计 在职称管理页面添加输入框 export default {name: "JobLevelMarna",data(){return{Jl:{name:""}}}}效果图 添加一个下拉框 v-model的值为当前被选中的el-option的 value 属性值 <el-select v-model"Jl.titlelevel" …

opencv 矩阵运算

1.矩阵乘&#xff08;*&#xff09; Mat mat1 Mat::ones(2,3,CV_32FC1);Mat mat2 Mat::ones(3,2,CV_32FC1);Mat mat3 mat1 * mat2; //矩阵乘 结果 2.元素乘法或者除法&#xff08;mul&#xff09; Mat m Mat::ones(2, 3, CV_32FC1);m.at<float>(0, 1) 3;m.at…

面试题-React(三):什么是JSX?它与常规JavaScript有什么不同?

在React的世界中&#xff0c;JSX是一项引人注目的技术&#xff0c;它允许开发者在JavaScript中嵌套类似HTML的标签&#xff0c;用于描述UI组件的结构。本篇博客将通过丰富的代码示例&#xff0c;深入探索JSX语法&#xff0c;解析其在React中的用法和优势。 一、JSX基础语法 在…

Springboot 实践(8)springboot集成Oauth2.0授权包,对接spring security接口

此文之前&#xff0c;项目已经添加了数据库DAO服务接口、资源访问目录、以及数据访问的html页面&#xff0c;同时项目集成了spring security&#xff0c;并替换了登录授权页面&#xff1b;但是&#xff0c;系统用户存储代码之中&#xff0c;而且只注册了admin和user两个用户。在…

(搜索) 剑指 Offer 13. 机器人的运动范围 ——【Leetcode每日一题】

❓剑指 Offer 13. 机器人的运动范围 难度&#xff1a;中等 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动&#xff0c;它每次可以向左、右、上、下移动一格&#xff08;不能移动到方格外&#xff09;&…

List

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;那个传说中的man的主页 &#x1f3e0;个人专栏&#xff1a;题目解析 &#x1f30e;推荐文章&#xff1a;题目大解析2 目录 &#x1f449;&#x1f3fb;List概念&#x1f449;&#x1f3fb;List constructo…

vue项目预览pdf功能(解决动态文字无法显示的问题)

最近&#xff0c;因为公司项目需要预览pdf的功能&#xff0c;开始的时候找了市面上的一些pdf插件&#xff0c;都能用&#xff0c;但是&#xff0c;后面因为pdf变成了需要根据内容进行变化的&#xff0c;然后&#xff0c;就出现了需要动态生成的文字不显示了。换了好多好多的插件…

Java:ArrayList集合、LinkedList(链表)集合的底层原理及应用场景

ArrayList集合的底层原理及应用场景 LinkedList&#xff08;链表&#xff09;集合的底层原理及应用场景 单向链表 增加数据 删除数据 双向链表 LinkedList的应用场景之一:可以用来设计队列 入队 出队 LinkedList的应用场景之一:可以用来设计栈 压栈&#xff08;push),addFirst…

AWS security 培训笔记

云计算的好处 Amazon S3 (Storage) Amazon EC2 (Compute) 上图aws 的几个支柱&#xff1a;安全是其中一个啦 其中安全有几个方面 IAMdetection基础架构保护数据保护应急响应 关于云供应商的责任 data center 原来长这样 &#xff0c;据说非常之隐蔽的 如果有天退役了&#xf…

SpringBoot + Vue 微人事(十)

职位管理前后端接口对接 先把table中的数据展示出来&#xff0c;table里面的数据实际上是positions里面的数据&#xff0c;就是要给positions:[] 赋上值 可以在methods中定义一个initPosition方法 methods:{//定义一个初始化positions的方法initPositions(){//发送一个get请求…

【学习FreeRTOS】第12章——FreeRTOS时间管理

1.FreeRTOS系统时钟节拍 FreeRTOS的系统时钟节拍计数器是全局变量xTickCount&#xff0c;一般来源于系统的SysTick。在STM32F1中&#xff0c;SysTick的时钟源是72MHz/89MHz&#xff0c;如下代码&#xff0c;RELOAD 9MHz/1000-1 8999&#xff0c;所以时钟节拍是1ms。 portNV…

《TCP IP网络编程》第十八章

第 18 章 多线程服务器端的实现 18.1 理解线程的概念 线程背景&#xff1a; 第 10 章介绍了多进程服务端的实现方法。多进程模型与 select 和 epoll 相比的确有自身的优点&#xff0c;但同时也有问题。如前所述&#xff0c;创建&#xff08;复制&#xff09;进程的工作本身会…

蔚来李斌卖手机:安卓系统,苹果售价,一年一发

‍作者 | Amy 编辑 | 德新 车圈大佬的玩法真让人寻不着套路&#xff01; 苹果的库克和小米的雷布斯&#xff0c;甚至是FF贾老板准备许久&#xff0c;都想分一块新能源车的蛋糕&#xff0c;蔚来李斌却反手进军手机界&#xff0c;从宣布造手机到手机入网仅仅隔了一年。 近期&a…

阿里云使用WordPress搭建个人博客

手把手教你使用阿里云服务器搭建个人博客 一、免费创建服务器实例 1.1 点击试用 点击试用会需要你创建服务器实例&#xff0c;直接选择默认的操作系统即可&#xff0c;点击下一步 1.2 修改服务器账号密码 二、创建云数据库实例 2.1 免费获取云数据库使用 2.2 实例列表页 在…

Three.js 实现模型材质局部辉光效果和解决辉光影响场景背景图显示的问题

1.Three.js 实现模型材质局部辉光效果 2.解决辉光效果影响场景背景图显示的问题 相关API的使用&#xff1a; 1. EffectComposer&#xff08;渲染后处理的通用框架&#xff0c;用于将多个渲染通道&#xff08;pass&#xff09;组合在一起创建特定的视觉效果&#xff09; 2. …

变更通知在开源SpringBoot/SpringCloud微服务中的最佳实践

目录导读 变更通知在开源SpringBoot/SpringCloud微服务中的最佳实践1. 什么是变更通知2. 变更通知的场景分析3. 变更通知的技术方案3.1 变更通知的技术实现方案 4. 变更通知的最佳实践总结5. 参考资料 变更通知在开源SpringBoot/SpringCloud微服务中的最佳实践 1. 什么是变更通…