1. Background

When we write rules in drools , sometimes there are duplicate codes, so can we extract these duplicate codes and encapsulate them into a function to call? So how to customize ---4c2ac56c044810bc46fdd7bc05c04528 drools in function ?

2. Demand

1. When there is a Person object in our working memory, we need to call drl function to determine whether the user can play the game. Playable when Person#age >= 18 .
2. After then call java of 静态方法 .

3. Preliminary knowledge

1. Function syntax structure

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

函数的定义 needs to be placed in the drl file and called after then in the rules file.

2. How to call the static method of java in the drl file

  1. The fully qualified name of the import class.
  2. In the part of ---eb9fac6828106dc9254e9a7f9e54dcfd then use 类名.静态方法名

4. Realization

1. Project structure

2. Introduce drools dependencies

 <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>

Some unimportant dependencies are omitted, such as logback和lombok .

3. Write the kmodule.xml file

 <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. Write the Person entity class

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

5. Writing drl function

6. Write test classes

 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. View the running results


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

5. Suppose I want to call the function in the when phase

The above function can be realized, but it needs to be realized by eval , but it is not good to realize it through eval , and the performance is also poor.
Example:

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

不推荐使用eval
Reference link: https://stackoverflow.com/questions/17487725/how-much-of-a-performance-hit-does-eval-cause-in-drools

6. Complete code

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

7. Reference link

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


huan1993
218 声望34 粉丝

java工程师