[Drools Demos] 其 (四) : SpringBoot-Drools模板

版权声明:欢迎转载,转载请说明出处. 大数据Github项目地址https://github.com/SeanYanxml/bigdata。 https://blog.csdn.net/u010416101/article/details/87887901

前言

前几节我们说了Drools的快速启动、数据传递和动态加载.本章我们提供一个简单的 Drools-SpringBoot实例模板.

本章主要对应项目内的drools-springboot-dynamic内容.

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

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


详细内容(Demos-1-模板基础)

pom.xml(导入相关Jar包)

	<!-- drools jars -->
	<properties>
		<drools-version>6.5.0.Final</drools-version>
		<springboot.version>1.5.13.RELEASE</springboot.version>
	</properties>
	
	<dependencies>
	
		<!-- spring boot -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
			<version>${springboot.version}</version>
			<exclusions>
				<exclusion>
					<groupId>org.springframework.boot</groupId>
					<artifactId>spring-boot-starter-logging</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		
		<!-- spring boot log4j2 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-log4j2</artifactId>
			<version>${springboot.version}</version>
		</dependency>
		
				<!--spring-boot -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
			<version>${springboot.version}</version>
			<exclusions>
				<exclusion>
					<groupId>org.springframework.boot</groupId>
					<artifactId>spring-boot-starter-logging</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		
	<!-- 	<dependency>
			<groupId>org.drools</groupId>
			<artifactId>drools-core</artifactId>
			<version>${drools-version}</version>
		</dependency> -->

		<dependency>
			<groupId>org.drools</groupId>
			<artifactId>drools-compiler</artifactId>
			<version>${drools-version}</version>
		</dependency>

		<!-- <dependency>
			<groupId>org.drools</groupId>
			<artifactId>knowledge-api</artifactId>
			<version>${drools-version}</version>
		</dependency>

		<dependency>
			<groupId>org.drools</groupId>
			<artifactId>drools-decisiontables</artifactId>
			<version>${drools-version}</version>
		</dependency>
		<dependency>
			<groupId>org.drools</groupId>
			<artifactId>drools-templates</artifactId>
			templates 模板
			<version>${drools-version}</version>
		</dependency>
		<dependency>
			<groupId>org.kie</groupId>
			<artifactId>kie-api</artifactId>
			<version>${drools-version}</version>
		</dependency> -->

		<dependency>
			<groupId>org.kie</groupId>
			<artifactId>kie-spring</artifactId>
			<version>${drools-version}</version>
			<exclusions>
				<exclusion>
					<groupId>org.springframework</groupId>
					<artifactId>spring-tx</artifactId>
				</exclusion>
				<exclusion>
					<groupId>org.springframework</groupId>
					<artifactId>spring-beans</artifactId>
				</exclusion>
				<exclusion>
					<groupId>org.springframework</groupId>
					<artifactId>spring-core</artifactId>
				</exclusion>
				<exclusion>
					<groupId>org.springframework</groupId>
					<artifactId>spring-context</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<!-- other jars -->
		
		<!-- test -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.7</version>
			<scope>test</scope>
		</dependency>

		<dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
            <scope>compile</scope>
        </dependency>
        
        <!--log4j-->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
        	
	</dependencies>

DroolsConfig.java(Drools动态加载配置类)

package com.yanxml.drools.springboot.config;

import java.io.IOException;
import org.kie.api.KieBase;
import org.kie.api.KieServices;
import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.builder.KieModule;
import org.kie.api.builder.KieRepository;
import org.kie.api.builder.Message;
import org.kie.api.builder.ReleaseId;
import org.kie.api.builder.Results;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.kie.internal.io.ResourceFactory;
import org.kie.spring.KModuleBeanFactoryPostProcessor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;

@Configuration
public class DroolsConfig {
	private static final String RULES_PATH = "rules/";

	@Bean
	@ConditionalOnMissingBean(KieFileSystem.class)
	public KieFileSystem kieFileSystem() throws IOException {
		KieFileSystem kieFileSystem = getKieServices().newKieFileSystem();
		for (Resource file : getRuleFiles()) {
//			((org.kie.api.io.Resource) file).setResourceType(ResourceType.DRL);
			kieFileSystem.write(ResourceFactory.newClassPathResource(
					RULES_PATH + file.getFilename(), "UTF-8"));
//			FileInputStream fis = new FileInputStream( "src/main/resources/"+RULES_PATH + file.getFilename() );
//			kieFileSystem.write( "src/main/resources/"+RULES_PATH + file.getFilename(),
//					getKieServices().getResources().newInputStreamResource( fis ) );
		}
		return kieFileSystem;
	}

	private Resource[] getRuleFiles() throws IOException {
		ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
		return resourcePatternResolver
				.getResources("classpath*:" + RULES_PATH + "**/*.*");
	}

	@Bean
	@ConditionalOnMissingBean(KieContainer.class)
	public KieContainer kieContainer() throws IOException {
        KieServices kieServices =  getKieServices();
		final KieRepository kieRepository = kieServices.getRepository();

		// 这边出了问题
		kieRepository.addKieModule(new KieModule() {
			public ReleaseId getReleaseId() {
				return kieRepository.getDefaultReleaseId();
			}
		});

		KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem());
		 Results results = kieBuilder.getResults();
	        if (results.hasMessages(Message.Level.ERROR)) {
	            System.out.println(results.getMessages());
	            throw new IllegalStateException("### errors ###");
	        }
		kieBuilder.buildAll();

//		return getKieServices()
//				.newKieContainer(getKieServices().getRepository().getDefaultReleaseId());
        KieContainer kieContainer = kieServices.newKieContainer(kieRepository.getDefaultReleaseId());

		return kieContainer;
	}

	private KieServices getKieServices() {
		return KieServices.Factory.get();
	}

	@Bean
	@ConditionalOnMissingBean(KieBase.class)
	public KieBase kieBase() throws IOException {
		return kieContainer().getKieBase();
	}

	@Bean
	@ConditionalOnMissingBean(KieSession.class)
	public KieSession kieSession() throws IOException {
		return kieContainer().newKieSession();
	}

	@Bean
	@ConditionalOnMissingBean(KModuleBeanFactoryPostProcessor.class)
	public KModuleBeanFactoryPostProcessor kiePostProcessor() {
		return new KModuleBeanFactoryPostProcessor();
	}
}

Application(SpringBoot启动类)

package com.yanxml.drools.springboot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

/**
 * 
 * 主程序的入口
 *
 */
@ComponentScan(basePackages={
		"com.yanxml.drools.springboot"
})
@SpringBootApplication

public class Application {
	
    public static Logger log = LogManager.getLogger(Application.class);

    public static void main(String[] args) {	
		try {
			SpringApplication app = new SpringApplication(Application.class);
			app.setWebEnvironment(true);
	        app.run(args);
	    	log.info("application started successfully");
		} catch (Exception e) {
			log.error("application main exception", e);
		}
	}
	
}

Message(POJO)

package com.yanxml.drools.springboot.beans.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;
	}
}

HelloWorld.drl

package com.yanxml.drools.springboot

import com.yanxml.drools.springboot.beans.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);
//		update(m);
end

HelloworldController

package com.yanxml.drools.springboot.controller;

import javax.annotation.Resource;

import org.drools.core.base.RuleNameStartsWithAgendaFilter;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.yanxml.drools.springboot.beans.pojo.Message;


@RequestMapping("/test")
@Controller
public class HelloworldController {
	@Resource
	private KieContainer kieContainer;
	
//	@Resource
//	private KieSession kieSession;
	
  @ResponseBody
  @RequestMapping("/helloworld")
  public void test(){
	  // newKieSession with name will be NullPointerException.(Bug)
//	  	KieSession kieSession = kieContainer.newKieSession("kSessionHelloWorld");
	  	KieSession kieSession = kieContainer.newKieSession();
		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(new RuleNameStartsWithAgendaFilter("Transmit"));
		
		// 同步等待 - 等待rule执行完毕后 后面的语句才被执行。
		System.out.println("Rule After - Message: "+message.getMessage()+" status:"+message.getStatus());
	}

	
}

测试结果:


[1] localhost:8080/test/helloworld

# output

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

RELATING-CLASS:HelloworldController

详细内容(Demos-2-方法回调)

MessageServiceService

package com.yanxml.drools.springboot.service;

import org.springframework.stereotype.Service;
import com.yanxml.drools.springboot.beans.pojo.Message;

@Service
public class MessageServiceService {
	
	public void insert(Message message){
		// 数据库 Insert语句
		System.out.println("Message Service Insert SQL.");
	}
}

HelloWorld.drl 规则补充

rule "InvokeHelloWorldRule"
	when
		$m : Message()
		$messageServiceService : MessageServiceService()
	then
		System.out.println("Hit Invoke HelloWorld Rule.");
		$messageServiceService.insert($m);
end

MessageServiceController(新Controller)

package com.yanxml.drools.springboot.controller;

import javax.annotation.Resource;

import org.drools.core.base.RuleNameStartsWithAgendaFilter;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.yanxml.drools.springboot.beans.pojo.Message;
import com.yanxml.drools.springboot.service.MessageServiceService;

@Controller
@RequestMapping("/message")
public class MessageServiceController {
	@Resource 
	KieContainer kieContainer;
	
	@Autowired
	MessageServiceService messageServiceService;
	
	@ResponseBody
	@RequestMapping("/insert")
	public void insert(){
		KieSession kieSession = kieContainer.newKieSession();
		
		// insert Facts
		Message message = new Message();
		message.setMessage("Insert-0-Message");
		message.setStatus(Message.STATUS_1);
		kieSession.insert(message);
		
		// insert Service
		kieSession.insert(messageServiceService);
		
		kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("Invoke"));

		
	}

}

测试结果:


[2] http://localhost:8080/message/insert

# output

Hit Invoke HelloWorld Rule.
Message Service Insert SQL.

RELATING-CLASS:MessageServiceController

Reference

[1] 《Drools7.0.0.Final规则引擎教程》Springboot+规则重新加载

[2] Drools入门系列

没有更多推荐了,返回首页