一、背景

当我们在drools中编写规则时,有些时候存在重复的代码,那么我们是否可以将这些重复代码抽取出来,封装成一个function来调用呢?那么在drools中如何自定义function

二、需求

1、当我们的工作内存中存在Person对象时,则需要调用drl function来判断用户是否可以玩游戏。当Person#age >= 18时可以玩。

2、在then 后面调用java静态方法

三、前置知识

1、function语法结构

function 返回值类型 方法名(方法参数){
方法体
}

函数的定义需要放置在drl文件中,并且是在规则文件的then之后进行调用。

2、drl文件中如何调用java的静态方法

  1. import 类的全限定名。
  2. then的部分使用 类名.静态方法名

四、实现

1、项目结构

2、引入drools依赖

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-bom</artifactId>
<type>pom</type>
<version>7.69.0.Final</version>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement> <dependencies>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-mvel</artifactId>
</dependency>
</dependencies>

一些不重要的依赖省略了,比如logback和lombok

3、编写kmodule.xml文件

<kmodule xmlns="http://www.drools.org/xsd/kmodule">
<kbase name="function-kabse" packages="rules" default="false">
<ksession name="function-ksession" default="false" type="stateful"/>
</kbase>
</kmodule>

4、编写Person实体类

@Data
@AllArgsConstructor
public class Person {
private String name;
private Integer age;
}

5、drl function编写

6、编写测试类

public class DroolsApplication {
public static void main(String[] args) {
KieServices kieServices = KieServices.get();
KieContainer kieContainer = kieServices.getKieClasspathContainer();
KieSession kieSession = kieContainer.newKieSession("function-ksession");
kieSession.addEventListener(new DebugRuleRuntimeEventListener()); Person person = new Person("张三", 16);
kieSession.insert(person);
kieSession.fireAllRules();
kieSession.dispose();
}
}

7、查看运行结果

到此我们的自定义function功能就完成了。

五、假设我想在when阶段调用function

对于上面这个功能是可以实现的,但是需要借助eval来实现,不过需要通过 eval来实现是不好的,而且性能也差。

举例:

rule "rule_eval"
when
$person: Person()
// eval 也可以调用java的静态方法
eval(playGameOk($person))
// 这样也可以进行调用,不过这个获取到的结果不会进行模式匹配,但是可以用在下方的模式匹配条件中
$playGameOk: Boolean() from playGameOk($person)
then
System.out.println("ok");
end

不推荐使用eval

参考链接:https://stackoverflow.com/questions/17487725/how-much-of-a-performance-hit-does-eval-cause-in-drools

六、完整代码

https://gitee.com/huan1993/spring-cloud-parent/tree/master/drools/drools-drl-function

七、参考链接

1、https://stackoverflow.com/questions/17487725/how-much-of-a-performance-hit-does-eval-cause-in-drools

2、https://docs.drools.org/7.69.0.Final/drools-docs/html_single/index.html#drl-functions-con_drl-rules

drools中使用function的更多相关文章

  1. 项目中Ajax调用ashx页面中的Function的实战

    前台页面: 使用几个display=none的空间存储DropdownList中的值,点击Search Button后刷新页面再次给DropdownList赋值使用 <%@ Page Langu ...

  2. JavaScript中的Function(函数)对象详解

    JavaScript中的Function对象是函数,函数的用途分为3类: 作为普通逻辑代码容器: 作为对象方法: 作为构造函数. 1.作为普通逻辑代码容器 function multiply(x, y ...

  3. Shell脚本中使用function(函数)示例

    这篇文章主要介绍了Shell脚本中使用function(函数)示例,本文着重讲解的是如何在shell脚本中使用自定义函数,并给出了两个例子,需要的朋友可以参考下   函数可以在shell script ...

  4. Lua 中的 function、closure、upvalue

    Lua 中的 function.closure.upvalue function,local,upvalue,closure 参考: Lua基础 语句 lua学习笔记之Lua的function.clo ...

  5. 如何在开启了log-bin的MySQL Server中创建FUNCTION

    在MySQL主从复制机器的master的数据库中创建function,报出如下错误: Error Code: 1418. This function has none of DETERMINISTIC ...

  6. jquery中的 $(function(){ .. }) 函数

    2017-04-29 在讲解jquery中的 $(function(){ .. }) 函数之前,我们先简单了解下匿名函数.匿名函数的形式为:(function(){ ... }),又如 functio ...

  7. js中在window.onload中写function函数产生的问题

    转载自:https://blog.csdn.net/c_p_h/article/details/63684510 今天在jsp中的form表单利用οnclick=”xxx”来监听js中一个functi ...

  8. javascript中的function命名空間與模擬getter、setter

    function的命名空間 在javascript中,function也可以擁有自己的命名空間例如以下這段程式碼: 12345678 function () { return 'I am A';} A ...

  9. js中使用function定义类、实例化,函数的调用方法

    function Test002(name, age){ name, age, this.printInfo = function(){ //定义的公有方法 console.log(name, age ...

  10. java高级用法之:JNA中的Function

    目录 简介 function的定义 Function的实际应用 总结 简介 在JNA中,为了和native的function进行映射,我们可以有两种mapping方式,第一种是interface ma ...

随机推荐

  1. JS实现一个布隆过滤器

    之前专门聊过令牌桶算法,而类似的方案还有布隆过滤器.它一般用于高效地查找一个元素是否在一个集合中. 用js实现如下所示: class BloomFilter { constructor(size, h ...

  2. NC210981 mixup2混乱的奶牛

    题目链接 题目 题目描述 混乱的奶牛 [Don Piele, 2007] Farmer John的 N(4 <= N <= 16) 头奶牛中的每一头都有一个唯一的编号 \(S_i (1 & ...

  3. 【Unity3D】流动雾效

    1 前言 ​ 屏幕深度和法线纹理简介中对深度和法线纹理的来源.使用及推导过程进行了讲解,激光雷达特效中讲述了一种重构屏幕像素点世界坐标的方法,本文将介绍使用深度纹理重构屏幕像素点在相机坐标系下的坐标计 ...

  4. 【Android】使用Binder实现进程间传递对象案例

    1 前言 使用AIDL实现进程间通讯简单案例 和 使用AIDL实现进程间传递对象案例 中介绍了使用 AIDL 进行进程间通讯,其本质仍然是Binder,aidl 文件对应生成的接口中,将服务端调用的抽 ...

  5. 解决springboot整合freemarker页面跳转404

    问题说明 spring boot 2.1.5集成freemarker时跳转报404! 集成过程说明 pom.xml <dependency> <groupId>org.free ...

  6. Spring Security实现JDBC用户登录认证

    在搭建博客后端服务框架时,我采用邮件注册+Spring Security登录认证方式,结合mysql数据库,给大家展示下具体是怎么整合的. 本篇是基于上一篇:spring boot实现邮箱验证码注册 ...

  7. Ubuntu常用工具和问题整理

    安装Ubuntu虚拟机时常会遇到的几个问题 1.安装时设置镜像 安装Ubuntu系统时设置国内镜像可以加快安装速度:http://mirrors.aliyun.com/ubuntu/ 参考:ubunt ...

  8. 麒麟系统开发笔记(九):在国产麒麟系统上搭建宇视摄像头SDK基础环境Demo

    前言   国产麒麟系统开发上,使用宇视摄像头,本篇使用宇视官网的提供的SDK,搭建基础的国产系统上宇视摄像头SDK开发化境Demo.   效果演示      宇视SDK下载   CSDN粉丝0积分下载 ...

  9. 用NavigationManager实现订单的列表和新增页面之间的导航

    1.在订单列表页面放置"新增"按钮 2.注入NavigationManager,按钮被点击后导航到新增订单的路径 3.测试一下,能工作了. 4.订单新增后,返回订单列表页面 5.测 ...

  10. 5-事件组&任务通知

    获取某个事件 获取若干事件中的某个事件 获取若干事件中的全部事件 !!!!不可获得若干事件中的几个事件 创建事件组,设置事件,等待事件 static EventGroupHandle_t xEvent ...