一、背景
當我們在drools
中編寫規則時,有些時候存在重複的程式碼,那麼我們是否可以將這些重複程式碼抽取出來,封裝成一個function
來呼叫呢?那麼在drools
中如何自定義function
?
二、需求
1、當我們的工作記憶體中存在Person
物件時,則需要呼叫drl function
來判斷使用者是否可以玩遊戲。當Person#age >= 18
時可以玩。
2、在then
後面呼叫java
的靜態方法
。
三、前置知識
1、function語法結構
function 返回值型別 方法名(方法引數){
方法體
}
函式的定義
需要放置在drl
檔案中,並且是在規則檔案的then
之後進行呼叫。
2、drl檔案中如何呼叫java的靜態方法
- import 類的全限定名。
- 在
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))
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