欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

[Drools Demos] 其 (二) : 数据传递

程序员文章站 2022-05-28 11:38:35
...

前言

本章主要对应项目内的drools-demos内的HelloWorld样例.主要讲解Drools内是如何进行数据传递的.

基础配置: JDK 1.7 + Eclipse Mar + Maven
依赖: Drools插件(非必须)

本章主要对应项目内的drools-quickstart子模块.
Github地址: https://github.com/SeanYanxml/drools-train


详细内容

通过上节我们可以看到,通过kSession.insert(message);方法,将message对象传递给了DRL规则文件内部.

  • Q1:
    那么,有一个问题,DRL内改变对象后,规则文件外的对象message是否改变了?我们带着这个问题进行今天的测试

Message.java(POJO类)

package com.yanxml.drools.demos.pojo;

public class Message {
	// status 4 种状态
	public static final int STATUS_1 = 1;
	public static final int STATUS_2 = 2;
	public static final int STATUS_3 = 3;
	public static final int STATUS_4 = 4;
	
	private String message;
	private int status;
	
	public String getMessage() {
		return message;
	}
	public void setMessage(String message) {
		this.message = message;
	}
	public int getStatus() {
		return status;
	}
	public void setStatus(int status) {
		this.status = status;
	}

}

kmodule.xml(kmodule配置文件)

<?xml version="1.0" encoding="utf-8" ?>
<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule">
	<!-- demo helloworld -->
	<kbase name="kbase-helloworld" packages="com.yanxml.drools.demos.helloworld">
		<ksession name="ksession-helloworld"/>
	</kbase>
	
</kmodule>

Helloworld.drl


import com.yanxml.drools.demos.pojo.Message;

no-loop true

rule "TransmitHelloworldRule"
	when 
		$m : Message( status == Message.STATUS_1, myMessage:message)
	then
		System.out.println("Hit Transmit HelloWorld Rule.");
		$m.setMessage("STATUS_2");
		$m.setStatus(Message.STATUS_2);
//		update(m);
end

DroolsBaseTest.java(基础测试类)

package com.yanxml.drools.demos.test;

import org.junit.Before;
import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;

public abstract class DroolsBaseTest {
	
	protected KieServices kieServices;
	protected KieContainer kieContainer;
	
	@Before
	public void init(){
		kieServices =  KieServices.Factory.get();
		kieContainer = kieServices.getKieClasspathContainer(); 
	}

}

HelloWorldTest.java(HelloWorld测试类)

package com.yanxml.drools.demos.test;

import org.drools.core.base.RuleNameStartsWithAgendaFilter;
import org.junit.Test;
import org.kie.api.runtime.KieSession;

import com.yanxml.drools.demos.pojo.Message;
import com.yanxml.drools.demos.service.HelloWolrdMessageService;

public class HelloWorldTest extends DroolsBaseTest {
	
//	@Test
	public void testHelloWorld(){
		KieSession kieSession = kieContainer.newKieSession("ksession-helloworld");
		Message message = new Message();
		message.setMessage("STATUS_1");
		message.setStatus(Message.STATUS_1);
		
		System.out.println("Rule Before - Message: "+message.getMessage()+" status:"+message.getStatus());
		
		// hit rule
		kieSession.insert(message);
		kieSession.fireAllRules();
		
		// 同步等待 - 等待rule执行完毕后 后面的语句才被执行。
		System.out.println("Rule After - Message: "+message.getMessage()+" status:"+message.getStatus());
	}
	
}

测试结果:

Rule Before - Message: STATUS_1 status:1
Hit Transmit HelloWorld Rule.
Rule After - Message: STATUS_2 status:2

结论: 规则内和规则外使用的是同一个对象.规则内对象改变了,规则外也会跟随改变.

  • Q2:
    我们在规则内部调用规则外的工具类等,应当进行如何调用呢?

HelloWorldService(待回调的Service方法)

package com.yanxml.drools.demos.service;

import com.yanxml.drools.demos.pojo.Message;

public class HelloWolrdMessageService {
	
	// 更改业务
	public void changeMessageState(Message message,String msg, int status){
		message.setMessage(msg);
		message.setStatus(status);
	}
	
	public void insertMessage(Message message){
		// 插入message业务(暂略)
		// messageDao.insert();
	}

}

Helloworld.drl(规则补充)

rule "InvokeHelloWorldRule"
	when
		$m : Message()
		$msg : String()
		$status : Integer()
		$helloWolrdMessageService : HelloWolrdMessageService()
	then
		System.out.println("Hit Invoke HelloWorld Rule.");
		$helloWolrdMessageService.changeMessageState($m,$msg,$status);
end

HelloWorldTest(测试类补充)

@Test
	public void testHelloWorldInvoke(){
		KieSession kieSession = kieContainer.newKieSession("ksession-helloworld");
		Message message = new Message();
		message.setMessage("STATUS_1");
		message.setStatus(Message.STATUS_1);
		
		HelloWolrdMessageService helloWolrdMessageService = new HelloWolrdMessageService();
		
		
		System.out.println("Rule Before - Message: "+message.getMessage()+" status:"+message.getStatus());
		
		// hit rule
		kieSession.insert(message);
		
		kieSession.insert("STATUS_3");
		kieSession.insert(Message.STATUS_3);
		kieSession.insert(helloWolrdMessageService);
		
//		kieSession.fireAllRules();

		kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("Invoke"));
		
		// 同步等待 - 等待rule执行完毕后 后面的语句才被执行。
		System.out.println("Rule After - Message: "+message.getMessage()+" status:"+message.getStatus());
	}

测试结果:

Rule Before - Message: STATUS_1 status:1
Hit Invoke HelloWorld Rule.
Rule After - Message: STATUS_3 status:3

结论: 通过kieSession.insert(service)方法一并传入即可.