前言

本章主要对应项目内的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)方法一并传入即可.

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐