现在的位置: 首页 > 综合 > 正文

Drools Expert

2014年01月24日 ⁄ 综合 ⁄ 共 8517字 ⁄ 字号 评论关闭

2.2.3  Drools Expert 

2.2.3.1  非对称Rete算法实现 

不再需要影子代理。影子代理保护引擎免受有关实事的信息变化的影响,如果发生在引擎控件的外部,它可能不会被修改或撤消。 

2.2.3.2  包构建器现在可以构建多个命名空间 

你不再需要对一个包命名空间构建一个PackageBuilder 。只要保持为所有命名空间增加你的DRLs,并且getPackages()为每个使用的命名空间返加一个包数组。 

例子 2.26 获得多个包 

Package[] packages = pkgBuilder.getPackages(); 

2.2.3.3  规则库连接包构建器 

现在可以连接一个 RuleBase到一个 PackageBuilder,这意味着规则被构建,并且同时被添加到规则库。PackageBuilder使用现行的RuleBasePackage实例作为它的资源,取消了发生在现有方法中的Package创造和融合。 

例子 2.27 连接规则库(RuleBase)到包构建器(PackageBuilder 

RuleBase ruleBase = RuleBaseFactory.newRuleBase();

PackageBuilder pkgBuilder = new PackageBuilder( ruleBase, null ); 

2.2.3.4  有状态会话的二进制编码 

有状态会话现在可以保存,并可在以后的日期中恢复。预加载数据会话现在可以被创建。对用户对象的持久化可使用可插式策略,例如,hibernate或特征(identity)映射。 

2.2.3.5  类型声明 

Drools现在支持一种新的基础结构,称为类型声明。这个结构达到两个目的:能够声明实事元数据,以及能够为规则引擎动态地产生局部的新的事实类型。Guvnor模拟工具在底层使用了它。下面是该结构的一个例子: 

例子 2.28 声明StockTick 

declare StockTick

  @role( event )

  @timestamp( timestampAttr ) 

  companySymbol : String

  stockPrice : double

  timestampAttr : long

end 

2.2.3.6  声明实事元数据 

要声明和关联事实的元数据,只需要对你想声明的每个元数据ID使用@符号。例子: 

例子 2.29 声明元数据 

declare StockTick

  @role( event )

end 

2.2.3.7  触发Bean产生 

要激活动态bean产生,仅为你的类型声明添加字段和类型。 

例子 2.30 声明Person 

declare Person

  name : String

  age : int

end 

2.2.3.8  DSL的改进 

一系列DSL的改进被实现,包括一个完善的新解析器,并且能够为匹配的变量声明匹配的掩码(mask)。例如,它可限定一个电话号码字段为2位数的国家代码+ 3位区号+ 8位数字电话号码,所有连接以“ - ”(破折号)连接,通过象这样声明DSL映射:电话号码为{number:/d{2}-/d{3}-/d{8}},所有有效的Java正则表达式可以用于变量的掩码中。 

2.2.3.9  fireUntilHalt() 

Drools现在支持fireUntilHalt()功能,它以一种被动模式启动引擎,在那儿规则会被连续引发,直到调用了halt()。这尤其对CEPcomplex event processing)场景有用,CEP场景需要俗称的活动查询 

2.2.3.10   规则库分区和多线程传播 

Drools ReteOO算法现在支持一个选项,用于以多线程模式启动规则库,在那儿Drools ReteOO网络被划分为多个部分,然后规则被多个线程并发计算。对通常有几个独立规则并发运行的CEP,它也有一个要求,接近实时性能/吞吐量的要求,并且一个计算不能干扰其他的计算。 

2.2.3.11   XSD模式支持 

Drools现在支持XSD模式。记住虽然XSD模式以用于Drools类加载器的本地POJO类生成。在包构建器中存在有一个帮助类用于模式的产生。一旦数据模式被生成,你通常使用JAXB数据加载器插入数据。 

2.2.3.12   数据加载器 

Drools现在支持两种数据加载器,SmooksJAXBSmooks是一个用于ETL的开源数据转换工具,JAXB是一个标准的Sun数据映射工具。单元测试显示SmooksJAXB均可在这里找到。 

2.2.3.13   类型安全配置 

Drools中,除了能够通过配置文件配置选项外,也可用系统属性配置,通过API setProperty()方法设置属性,Drools-API现在支持类型安全配置。我们不希望为每个可能的配置方法增加特殊的方法,有两个原因:它污染了API,并且每次都有一个新选项增加到DroolsAPI将不得不改变。而这种方式,我们遵循模块化,类基于配置,在此处为每个可能的配置,一个新的选项类增加到了API,除了灵活之外,也维持了API的稳定。所以,现在为了设置配置选项,你只需要使用枚举或者提供每个选项的工厂。例如,如果你希望为断言行为"equality" 配置知识库,并且自动从模式匹配中删除特征(identities),你只需要使用下面的枚举: 

例子2.31 配置 

KnowledgeBaseConfiguration config = KnowledgeBaseFactory.newKnowledgeBaseConfiguration();

config.setOption( AssertBehaviorOption.EQUALITY );

config.setOption( RemoveIdentitiesOption.YES ); 

对于选项,我们不需要预定义约束,或者可以假设多个值,提供一个工厂方法。例如,配置alpha值为5,只使用get()工厂方法: 

例子 2.32 配置alpha 

config.setOption( AlphaThresholdOption.get(5) );

正如你所见,为每个不同的可能配置,使用了相同的setOption()方法,然而它们仍然是类型安全的。 

2.2.3.14   新的累积函数:collectSet和collectList 

有时候,有必要收集来自实事属性的值的集合或列表,而不是实事本身。在这种情况下,不可能使用collect CE。所以对这种情况,现在Drools有两个新的累积函数:collectSet用于收集值的集合(即,无重复的值),collectList用于收集值的列表(即,允许重复的值): 

例子 2.33 新的累积函数 

# collect the set of unique names in the working memory

$names : Set() from accumulate( Person( $n : name, $s : surname ),

                        collectSet( $n + " " + $s ) )

 

# collect the list of alarm codes from the alarms in the working memory

$codes : List() from accumulate( Alarm( $c : code, $s : severity ),

                         collectList( $c + $s ) ) 

2.2.3.15  用于类型声明的新元数据:@propertyChangeSupport 

事实实现了象定义在Javabean(tm)规范中的属性改变的支持。现在可以注释,让引擎注册自身来侦听事实属性的变化。在Drools 4 APIinsert()方法中使用的布尔参数已过时,并且不存在于drools-aip模块中了。 

例子 2.34  @propertyChangeSupport 

 declare Person

       @propertyChangeSupport

end 

2.2.3.16  批处理器 

批处理器允许一个知识会话使用命令脚本,此外,无论是StatelessKnowledgeSession 还是 StatefulKnowledgeSession实现都可以使用CommandFactory创建这个接口命令,且使用"execute" 方法执行,如下所示: 

例子 2.35 使用CommandFactory 

ksession.execute( CommandFactory.newInsert( person ) ); 

尽管这样,你通常会希望执行一个批处理命令,通过组合命令 BatchExecution可以完成它。BatchExecutionResults现在用来处理结果,某些命令可以使用"out"标识符,用它来添加结果到BatchExecutionResult。现在可以轻松地执行查询,并把结果添加到BatchExecutionResult。这个结果进一步被限定到这个执行调用,并且通过BatchExecutionResults返回。 

例子 2.36  使用BatchExecutionResult 

List<Command> cmds = new ArrayList<Command>();

cmds.add( CommandFactory.newSetGlobal( "list1", new ArrayList(), true ) );

cmds.add( CommandFactory.newInsert( new Person( "jon", 102 ), "person" ) );

cmds.add( CommandFactory.newQuery( "Get People" "getPeople" );

 

BatchExecutionResults results = ksession.execute( CommandFactory.newBatchExecution( cmds ) );

results.getValue( "list1" ); // returns the ArrayList

results.getValue( "person" ); // returns the inserted fact Person

results.getValue( "Get People" );// returns the query as a QueryResults instance.

End 

CommandFactory详细描述支持的命令,它们所有都可以使用XStreamBatchExecutionHelper进行编码。可以使用管道组合它们来自动化会话脚本。 

例子 2.37 使用PipelineFactory 

Action executeResultHandler = PipelineFactory.newExecuteResultHandler();

Action assignResult = PipelineFactory.newAssignObjectAsResult();

assignResult.setReceiver( executeResultHandler );

Transformer outTransformer = PipelineFactory.newXStreamToXmlTransformer( BatchExecutionHelper.newXStreamMarshaller() );

outTransformer.setReceiver( assignResult );

KnowledgeRuntimeCommand batchExecution = PipelineFactory.newBatchExecutor();

batchExecution.setReceiver( outTransformer );

Transformer inTransformer = PipelineFactory.newXStreamFromXmlTransformer( BatchExecutionHelper.newXStreamMarshaller() );

inTransformer.setReceiver( batchExecution );

Pipeline pipeline = PipelineFactory.newStatelessKnowledgeSessionPipeline( ksession );

pipeline.setReceiver( inTransformer ); 

对一个规则集使用上面所述的,会更新一个Cheese事实的价格,下面给定的xml会插入一个使用了输出标识符(out-identifier)的Cheese实例。 

例子 2.38 更新Cheese实事 

<batch-execution>

<insert out-identifier='outStilton'>
  <org.drools.Cheese>
    <type>stilton</type>
    <price>25</price>
    <oldPrice>0</oldPrice>
  </org.drools.Cheese>
</insert>
</batch-execution>
 

然后我们会得到BatchExecutionResults 

例子 2.39 更新Cheese实事

<batch-execution-results>
 <result identifier='outStilton'>
   <org.drools.Cheese>
     <type>stilton</type>
     <oldPrice>0</oldPrice>       
     <price>30</price>
   </org.drools.Cheese>
 </result>
</batch-execution-results>
 

2.2.3.17  编码 

MarshallerFactory被用来编码和解码StatefulKnowledgeSessions。最简单的,它可以象下面这样使用: 

例子 2.40 使用MarshallerFactory 

// ksession is the StatefulKnowledgeSession

// kbase is the KnowledgeBase

ByteArrayOutputStream baos = new ByteArrayOutputStream();

Marshaller marshaller = MarshallerFactory.newMarshaller( kbase );

marshaller.marshall( baos, ksession );

baos.close(); 

然而,在处理引用的用户数据时,你需要更有弹性地使用编码。要达成它,我们有一个ObjectMarshallingStrategy接口。我们提供了两个实现,但是用户可以自己实现它。提供的两个是IdentityMarshallingStrategySerializeMarshallingStrategy。默认为SerializeMarshallingStrategy,如上例所示,它只在一个用户实例上调用SerializableExternalizable方法。而IdentityMarshallingStrategy为每个用户对象创建了一个整数id,并存储它们在一个映射中,该id被写入到该流中。在解码时,它只简单地查看IdentityMarshallingStrategy映射,取回该实例。这意味着,如果你使用IdentityMarshallingStrategy,它对编码实例的生命周期是有状态的,并且会创建ids,保持它企图编码的所有对象的引用。 

例子 2.41 使用IdentityMarshallingStrategy编码 

ByteArrayOutputStream baos = new ByteArrayOutputStream();

Marshaller marshaller = MarshallerFactory.newMarshaller( kbase, new ObjectMarshallingStrategy[] { MarshallerFactory.newIdentityMarshallingStrategy() } );

marshaller.marshall( baos, ksession );

baos.close(); 

为增加弹性,我们不能想当然地认为单策略更合适,所以我们增加了一个ObjectMarshallingStrategyAcceptor 接口,每个ObjectMarshallingStrategy都有。编码器有一个策略链,并且当它企图读或写一个用户对象时,它遍历策略,询问它们是否承担负责编码用户对象。提供了一个实现为ClassFilterAcceptor。它允许使用字符和通匹符匹配类名。默认为"*.*",所以在上面使用的IdentityMarshallingStrategy,它有一个默认的"*.*"接收器。然而,比方说,我们希望序列化所有类,一个给定的包除外,这种情况,我们会使用身份查询,如下所示: 

例子 2.42  使用身份查询 

ByteArrayOutputStream baos = new ByteArrayOutputStream();

ObjectMarshallingStrategyAcceptor identityAceceptor = MarshallerFactory.newClassFilterAcceptor( new String[] { "org.domain.pkg1.*" } );

ObjectMarshallingStrategy identityStratetgy = MarshallerFactory.newIdentityMarshallingStrategy( identityAceceptor );

Marshaller marshaller = MarshallerFactory.newMarshaller( kbase, new ObjectMarshallingStrategy[] { identityStratetgy, MarshallerFactory.newSerializeMarshallingStrategy() } );

marshaller.marshall( baos, ksession );

baos.close(); 

2.2.3.18  知识代理 

KnowlegeAgent KnowlegeAgentFactory创建。KnowlegeAgent提供自动加载、缓存和重新加载资源,并且根据一个属性文件配置它。当KnowlegeBase使用的资源更改时,KnowlegeAgent可以更新或重构KnowlegeBase。通过给定工厂的配置确定KnowlegeAgent的策略,但通常使用基于标准轮询的拉策略。我们希望增加基于推的更新,并在将来的版本中重构它。下面的例子,构建了一个代理,它根据在路径字符串中指定的文件构建了一个新的KnowledgeBase。它会每30秒拉这些文件,而不是更新存在的一个,因为 "newInstance" 设置为了"true" (然而,目前只支持"true" 值,并且很难编码到引擎中)。 

例子 2.43 构建一个代理 

// Set the interval on the ResourceChangeScannerService if you are to use it and default of 60s is not desirable.
ResourceChangeScannerConfiguration sconf = ResourceFactory.getResourceChangeScannerService().newResourceChangeScannerConfiguration();
sconf.setProperty( "drools.resource.scanner.interval",
                  "30" ); // set the disk scanning interval to 30s, default is 60s
ResourceFactory.getResourceChangeScannerService().configure( sconf );
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
KnowledgeAgentConfiguration aconf = KnowledgeAgentFactory.newKnowledgeAgentConfiguration();
aconf.setProperty( "drools.agent.scanDirectories",

抱歉!评论已关闭.