新的Drools 6.x KIE A​​PI如何工作?

Ste*_*lia 5 drools

我正在尝试从Drools 5.x升级到6.x并尽可能地保持简单.新的kieAPI使这项简单的任务变得困难.

经过多次尝试,我设法将标准Drools 5.x示例转换为6.x等效项.请注意,我故意避免使用XML配置文件,依赖注入等,但我仍然不理解某些段落.

我将这两个版本的应用程序包括在内,可能会帮助那些面临同样问题的人.

以下代码或多或少是我们在Drools 5.x中所做的事情:

// Obtain a builder for knowledge base
KnowledgeBuilder builder = KnowledgeBuilderFactory.newKnowledgeBuilder();

// Load a DRL resource from src/main/resources into the builder
String location = "/drools/HelloWorld.drl";
InputStream stream = getClass().getResourceAsStream(location);
Resource resource = ResourceFactory.newInputStreamResource(stream);
builder.add(resource, ResourceType.DRL);

// Check for errors, print them and stop if any
if (builder.hasErrors()) {
    for (KnowledgeBuilderError error : builder.getErrors()) {
        System.out.println(error);
    }
    System.exit(0);
}

// Create a new knowledge base out of the builder
KnowledgeBase base = KnowledgeBaseFactory.newKnowledgeBase();
base.addKnowledgePackages(builder.getKnowledgePackages());

// Start a new working session
StatefulKnowledgeSession session = base.newStatefulKnowledgeSession();

// Inject a new message object into the session
final Message message = new Message();
message.setMessage("Hello World");
message.setStatus(Message.HELLO);
session.insert(message);

// Apply the rules in the knowledge base to the objects in the session
session.fireAllRules();

// Close the working session
session.dispose();
Run Code Online (Sandbox Code Playgroud)

由于Drools 6.x KnowledgeBase已被弃用,因此它可能会在不久的将来逐步淘汰代码库,从而迫使使用新的API.Drools 6.x中的上述示例变为:

// Get access to Drools services
KieServices services = KieServices.Factory.get();

// Obtain a new empty virtual file system
KieFileSystem fileSystem = services.newKieFileSystem();

// Load a DRL resource from src/main/resources into the virtual file system
// The prefix 'src/main/resources' is required since Drools 6.2.x
String location = "/drools/HelloWorld.drl";
InputStream stream = getClass().getResourceAsStream(location);
Resource resource = ResourceFactory.newInputStreamResource(stream);
fileSystem.write("src/main/resources" + location, resource);

// Convert the files in the virtual file system into a builder
KieBuilder builder = services.newKieBuilder(fileSystem).buildAll();

// Check for errors, print them and stop if any
Results results = builder.getResults();
if (results.hasMessages(ERROR)) {
    System.out.println(results.getMessages());
    System.exit(0);
}

// Create a new kie base out of a repository and a container
KieRepository repository = services.getRepository(); // <---= HERE!
KieContainer container = services.newKieContainer(repository.getDefaultReleaseId());
KieBase base = container.getKieBase();

// Start a new working session
KieSession session = base.newKieSession();

// Inject a new message object into the session
final Message message = new Message();
message.setMessage("Hello World");
message.setStatus(Message.HELLO);
session.insert(message);

// Apply the rules in the kie base to the objects in the session
session.fireAllRules();

// Close the working session
session.dispose();
Run Code Online (Sandbox Code Playgroud)

我认为这些新的APIS过于冗长,而且有点模糊不清.我知道它们背后的原因之一是允许更容易地管理规则库(即:包),但实现有点复杂并且无法对该工具公正(即:采用更难).

我知道使用xml配置文件或依赖注入使代码更简单,但前者打破了流程,后者强制包含(许多)更多依赖项.而且,在任何一种情况下,理解正在发生的事情变得更加困难.

但是,回到问题,请注意KieRepository引入的第二个片段中的行:

KieRepository repository = services.getRepository(); // <---= HERE! 
Run Code Online (Sandbox Code Playgroud)

services一个返回KieRepository其默认版本号为用于初始化一个KieContainer.此容器生成一个在需要时KieBase创建KieSession的容器.请注意,先前初始化的KieBuilder包含带有DRL文件的文件系统不会在任何地方用于获取KieBase. 怎么KieBase知道DRL文件?通过一些副作用KieServices?如果是这样,这不是很糟糕吗?

提前感谢您的任何想法或解释.

Est*_*rti 0

Stefano,如果您只对在应用程序中加载一堆 drl 感兴趣,并且不担心 KieContainers、Maven 工件或 KieScanner,那么您可以使用 KieHelper

有关更多信息,请查看我对另一篇文章的回答

这里唯一的缺点是 KieHelper 不是 Drools 公共 API 的一部分。

希望能帮助到你,