Drools关于session的不同方法

这里小编就针对session而言,单独拿出一个章节来讲session,因为这个在实际应用中是非常重要的。定义了一个像前一个示例中的一个kmodule.xml,现在可以使用他们的名字从KieContainer中简单地检索KieBase和KieSessions。

从KieContainer抢走KieBases和KieSessions

KieServices kieServices = KieServices.Factory.get();
KieContainer kContainer = kieServices.getKieClasspathContainer();

KieBase kBase1 = kContainer.getKieBase("KBase1");
KieSession kieSession1 = kContainer.newKieSession("KSession2_1");
StatelessKieSession kieSession2 = kContainer.newStatelessKieSession("KSession2_2")

必须注意的是,由于KSession2_1和KSession2_2有2种不同的类型(第一种是有状态的,而第二种是无状态的),所以有KieContainer必要根据其声明的类型调用2种不同的方法 。如果所KieSession 请求的类型KieContainer与kmodule.xml文件中声明的类型不符,KieContainer将抛出一个RuntimeException。此外,由于KieBase和KieSession被标记为默认值,它可以从KieContainer没有传递任何名称的情况下获得它们。

小编为什么会要将session独立出来一个章节呢,这是有原因的,我们在开发过程会遇到各种情况,这个session的状态是很重要的,也会在开发中经常使用。

KieSession用于与规则引擎进行交互的会话。

会话分为两类:

  1. 有状态的 KieSession
  2. 无状态的 StatelessKieSession

 KieSession  有状态的

KieSession 会在多次与规则引擎进行交互中,维护会话的状态。

定义 KieSession,在kmodule.xml文件中定义 type 为stateful的 session:

type="stateful"> 

注意:stateful 是 type 属性的默认值。

获取 KieSession实例

KieSession statefulSession = kieContainer.newKieSession("stateful_session"); 

接下来,可以在 KieSession执行一些操作。最后,如果需要清理 KieSession维护的状态,调用 dispose()方法。

这里有状态的值插入数据是通过ksession.insert(Object) 迭代方式插入的(笛卡尔积),请注意,迭代方式。怎么理解呢,举个例子:

Ksession.insert(obj1)
Ksession.insert(obj2)
这是两个不同的对象值,通过这样的方式,在rule中进行应用,后续还会使用更多次的有状态的应用例子,读者仔细体会

StatelessKIESession 无状态的

与 KieSession相反,StatelessKIESession 隔离了每次与规则引擎的交互,不会维护会话的状态,所以保证了数据的正确性,比较适用于高并发,多线程之类的互联网项目。

如果将 session 比作编程语言中的函数,StatelessKIESession 就是无副作用的函数。

定义 StatelessKIESession,在kmodule.xml文件中定义type为stateless的 session:

ype="stateless">

如果我们想要用无状态的kie-session的话 就必须这样定义了。

该StatelessKieSession包装的 KieSession,而不是扩展它。其主要重点是决策服务类型场景。它避免了调用的需要 dispose()。无状态会话不支持迭代插入和fireAllRules()来自Java代码的方法调用; 调用的行为execute()是一个单一的方法,将内部实例化一个KieSession,添加所有用户数据并执行用户命令,调用 fireAllRules(),然后调用dispose()。虽然使用这个类的主要方式是通过接口支持的BatchExecution(一个子接口Command),但是CommandExecutor当简单的对象插入是必需的时候,提供了两种方便的方法。

Drools关于session的不同方法_第1张图片

获取 StatelessKIESession 实例:

StatelessKieSession statelessKieSession = kieContainer.newStatelessKieSession("stateless_session");  
//通过 KieServices 获取 command 工厂类 KieCommands:
KieCommands commandFactory = kieServices.getCommands();  
//可以使用工程类 KieCommands 调用 newXXXCommand 开头的方法创建 command 实例。
//会话执行 command:
statelessKieSession.execute(command);
//----------------------- 分隔线-----------------------
[source code]  调用的是该接口 
public interface StatelessRuleSession {
    void execute(java.lang.Object o);
    void execute(java.lang.Iterable iterable);
}
StatelessKnowledgeSessionImpl 实现类
	public void execute(Object object) {
        StatefulKnowledgeSession ksession = newWorkingMemory();
        try {
            ksession.insert( object );
            ksession.fireAllRules();
        } finally {
            dispose(ksession);
        }
 }

从代码中我们可以看出来,也是通过finally中的dispose方法来删除的,只是与kieSession方式不同。

  • 无状态批处理命令
StatelessKieSession ksession = kbase.newStatelessKieSession();

List cmds = new ArrayList();
cmds.add( CommandFactory.newInsert( new Cheese( "stilton", 1), "stilton") );
cmds.add( CommandFactory.newStartProcess( "process cheeses" ) );
cmds.add( CommandFactory.newQuery( "cheeses" ) );
ExecutionResults bresults = ksession.execute( CommandFactory.newBatchExecution( cmds ) );
Cheese stilton = ( Cheese ) bresults.getValue( "stilton" );
QueryResults qresults = ( QueryResults ) bresults.getValue( "cheeses" );

在上面的例子中,执行多个命令,其中两个填充ExecutionResults。query命令默认使用与查询名称相同的标识符,但也可以映射到不同的标识符。所有命令都支持使用XStream的XML和jSON编组,以及JAXB编组。命令API 部分将介绍这一点。

如果获取这些批处理或只通过execute的值呢,仔细的你一定会发现,这里不是有标识嘛,Cheese stilton = ( Cheese ) bresults.getValue( "stilton" );是的,获取值是可以通过这样的方式的,后面在kie-server高级应用的时候会讲到。

 

 

你可能感兴趣的:(Drools规则引擎说明及应用)