从今天开始,我们将分两期来详细的介绍Drools规则引擎的原理,和各关键类的使用方法。
		
				
						Drools
						规则引擎(上)
				
		
		
				
		
		
				1. 概述
				:
		
		
				Drools
				分为两个主要部分:构建(
				Authoring
				)和运行时(
				Runtime
				)。
				构建的过程涉及到
				.drl
				或
				.xml
				规则文件的创建,它们被读入一个解析器,使用
				ANTLR 3 
				语法进行解析。解析器对语法进行正确性的检查,然后产生一种中间结构“
				descr
				”,
				descr
				用
				AST
				来描述规则。
				AST
				然后被传到
				PackageBuilder
				,由
				PackagBuilder
				来产生
				Packaged
				对象。
				PackageBuilder
				还承担着一些代码产生和编译的工作,这些对于产生
				Package
				对象都时必需的。
				Package
		
		
				对象是一个可以配置的,可序列化的,由一个或多个规则组成的对象。下图阐明了上述过程:
				
		
		 
				
Figure 1.1 Authoring Components
 
		
				
		
		
				
						RuleBase
						是一个运行时组件,它包含了一个或多个
						Package
						对象。可以在任何时刻将一个
						Package
						对象加入或移出
						RuleBase
						对象。一个
						RuleBase
						对象可以在任意时刻实例化一个或多个
						WorkingMemory
						对象,在它的内部保持对这些
						WorkingMemory
						的弱引用。
						WorkingMemory
						由一系列子组件组成。当应用程序中的对象被
						assert
						进
						WorkingMemory
						,可能会导致一个或多个
						Activation
						的产生,然后由
						Agenda
						负责安排这些
						Activation
						的执行。下图说明了上述过程:
				
		
		 
				
Figure 1.2 . Runtime Components
2.构建(Authoring):
主要有三个类用来完成构建过程:DrlParser, XmlParser 和 PackageBuilder。两个解析器类从传入的Reader实例产生descr AST模型。PackageBuilder提供了简便的API,使你可以忽略那两个类的存在。这两个简单的方法是:“addPackageFromDrl”和“addPackageFromXml”,两个都只要传入一个Reader实例作为参数。下面的例子说明了如何从classpath中的xml和drl文件创建一个Package对象。注意:所有传入同一个PackageBuilder实例的规则源,都必须是在相同的package 命名空间(namespace)中。
PackageBuilder builder = new PackageBuilder();
builder.addPackageFromDrl( new InputStreamReader( getClass().getResourceAsStream( "package1.drl" ) ) );
builder.addPackageFromXml( new InputStreamReader( getClass().getResourceAsStream( "package2.drl" ) ) );
Package pkg = builder.getPackage();

Figure 2.1 PackageBuilder
PackageBuilder是可以配置的,使用PackageBuilderConfiguration。通常,你可以指定另一个parent ClassLoader和用什么编译器(compiler),默认是Eclipse JDT。下面显示了如何指定JANINO编译器:
PackageBuilderConfiguration conf = new PackageBuilderConfiguration();
conf.setCompiler( PackageBuilderConfiguration.JANINO );
PackageBuilder builder = new PackageBuilder( conf );
 Figure 2.2 . PackageBuilderConfiguration
Figure 2.2 . PackageBuilderConfiguration
3.RuleBase:

Figure 3.1 . RuleBase
一个RuleBase包含了多个将被使用的规则包(packages of rules)。一个RuleBase是可以序列化的,所以它可以被配置到JNDI或其他类似的服务。通常,第一次使用时,一个RuleBase被创建并缓存。RuleBase用RuleBaseFactory来实例化,默认返回一个ReteOO RuleBase。可以传入参数来指定采用ReteOO或Leaps。然后,用addPackage方法加入Package实例。你可以加入有相同命名空间(namespace)的多个Package。
RuleBase ruleBase  = RuleBaseFactory.newRuleBase();
ruleBase.addPackage(pkg);
  
		
				 Figure 3.2. RuleBaseFactory
				
				Figure 3.2. RuleBaseFactory
				
						
								一个
								rulebase
instance
								是线程安全的,所有你可以在你的应用中,让一个
								rulebase instance
								在多个线程中共享。对于一个
								rulebase
								的最通常的操作是产生一个新的
								WorkingMemory
								。
						
						
								这个
								rulebase
								保持着到它所产生的
								WorkingMemoryd
								的弱引用,所以在长时间运行的
								WorkingMemory
								中,如果
								rules
								发生改变,这些
								WorkingMemory
								可以即使的根据最新的
								rules
								进行更新,而不必重启
								WorkingMemory
								。你也可以指定
								RuleBase
								不必保持一个弱引用,但是你要保证
								RuleBase
								不用更新。
						
						
								
										
												
												ruleBase.newWorkingMemory();  
												//
												 maintains a weak reference.
												
														
												
												ruleBase.newWorkingMemory( 
												false
												 ); 
												//
												 do not maintain a weak reference
										
								
						
						
								任何时候,
								Package
								可以被加入或移除;所有的改变都会被反映到现存的
								WorkingMemory
								中。不要忘了调用
								fireAllRules()
								让
								Activations
								激发。
						
						
								
										
												
												ruleBase.addPackage( pkg  );  
												//
												 Add a package instance
												
														
												
												ruleBase.removePackage( 
												"
												org.com.sample
												"
												  );  
												//
												 remove a package, and all its parts, 
												
												
												by it's namespace
												
														
												
												ruleBase.removeRule( 
												"
												org.com.sample
												"
												, 
												"
												my rule
												"
												 ); 
												//
												 remove a specific rule from a 
												
												
												namespace
										
								
						
						
								虽然有删除一个单独规则的方法,但是却没有加入一个单独规则的方法(要达到这个目的只有加入一个只有一条规则的
								package
								)。
						
						
								
										
										
										
								
						
						
								RuleBaseConfigurator
								可以指定
								RuleBase
								的附加行为。在加入
								RuleBase
								后,
								RuleBaseConfiguration
								就变成不可变对象。
						
						
								
								RuleBaseConfiguration conf 
								=
								 
								new
								 RuleBaseConfiguration();
conf.setProperty( RuleBaseConfiguration.PROPERTY_ASSERT_BEHAVIOR,
                  RuleBaseConfiguration.WM_BEHAVIOR_EQUALITY );
RuleBase ruleBase 
								=
								 
								new
								 ReteooRuleBase( conf );
						
				 
		 
		
				两个主要的属性是:
				PROPERT_ASSERT_BEHAVIOR
				和
				PROPERTY_LOGICAL_OVERRIDE_BEHAVIOR
				(在以后的部分中会解释)。所有的属性值都是
				RuleBaseConfiguration
				类中的静态域常量。
		
		
				 Figure 3.3 RuleBaseConfiguration
				
				Figure 3.3 RuleBaseConfiguration