10. CDI
更多相关网页:
http://www.jdon.com/38322
http://www.jdon.com/37976
http://www.cdi-spec.org/
10.1.介绍
CDI,全称Contexts and Dependency Injection(上下文和依赖注入),是向应用程序提供声明控制和结构的Java规范。KIE可以用它来实现自动实例化和绑定,而不需要使用编程的API。
10.2.注解
@KContainer, @KBase, @KSession都支持可选的'name'属性。CDI在它注入的时候一般不会"getOrCreate",同一组注解下,所有注入都会得到相同的实例。'name'标签会强制给每个名称一个唯一实例,尽管这个名称的所有的实例会在使用equals方法得到的结果是true。
10.2.1. @KReleaseId
绑定一个实例指向一个特定版本的KieModule。如果kie-ci在classpath中,依赖关系会被自动解决,并从远程仓库中下载。
10.2.2. @KContainer
@KContainer是可选的,因为在使用@Inject和变量类型推断时会被检测到,并添加进来。
图10.1.注入KieContainer
@Inject
private KieContainer kContainer;
图10.2.为动态的KieModule注入KieContainer
@Inject
@KReleaseId(groupId = "jar1", artifactId = "art1", version = "1.1")
private KieContainer kContainer;
图10.3.为动态的KieModule注入带名称的KieContainer
@Inject
@KContainer(name = "kc1")
@KReleaseId(groupId = "jar1", artifactId = "art1", version = "1.1")
private KieContainer kContainer;
10.2.3. @KBase
@KBase是可选的,因为在使用@Inject和变量类型推断时会被检测到,并添加进来。
如果给的话,默认参数是在kmodule.xml中定义的KieBase的值属性和名称。
图10.4. 注入默认的KieBase,从Classpath KieContainer获得
@Inject
private KieBase kbase;
图10.5. 注入默认的KieBase,从动态KieModule获得
@Inject
@KReleaseId( groupId = "jar1", artifactId = "art1", version = "1.0")
private KieBase kbase;
图10.6. 'jar1.KBase1' KieBase版本加载时一起处理(不懂)
@Inject
@KBase("kbase1")
@KReleaseId( groupId = "jar1", artifactId = "art1", version = "1.0")
private KieBase kbase1v10;
@Inject
@KBase("kbase1")
@KReleaseId( groupId = "jar1", artifactId = "art1", version = "1.1")
private KieBase kbase1v10;
图10.7. 使用'name'属性强制为'jar1.KBase1' KieBase创建新实例
@Inject
@KSession(value="kbase1", name="kb1")
@KReleaseId( groupId = "jar1", artifactId = "art1", version = "1.0")
private KieBase kbase1kb1;
@Inject
@KSession(value="kbase1", name="kb2")
@KReleaseId( groupId = "jar1", artifactId = "art1", version = "1.0")
private KieBase kbase1kb2;
10.2.4. @KSession for KieSession
@KSession是可选的,因为在使用@Inject和变量类型推断时会被检测到,并添加进来。
如果指定的话,默认参数是在kmodule.xml中定义的KieSession的值属性和名称。
Figure 10.8. 注入默认的KieSession,从Classpath KieContainer获得
@Inject
private KieSession ksession;
图10.9. 注入默认的KieSession,从动态KieModule获得
@Inject
@KReleaseId( groupId = "jar1", artifactId = "art1", version = "1.0")
private KieSession ksession;
图10.10. 'jar1.KBase1' KieBase版本加载时一起处理(同样不懂)
@Inject
@KSession("ksession1")
@KReleaseId( groupId = "jar1", artifactId = "art1", version = "1.0")
private KieSession ksessionv10;
@Inject
@KSession("ksession1")
@KReleaseId( groupId = "jar1", artifactId = "art1", version = "1.1")
private KieSession ksessionv11;
图10.11. 使用'name'标签强制为'jar1.KBase1' KieSession创建新实例
@Inject
@KSession(value="ksession1", name="ks1")
@KReleaseId( groupId = "jar1", artifactId = "art1", version = "1.0")
private KieSession ksession1ks1
@Inject
@KSession(value="ksession1", name="ks2")
@KReleaseId( groupId = "jar1", artifactId = "art1", version = "1.0")
private KieSession ksession1ks2
10.2.5. @KSession for StatelessKieSession
@KSession是可选的,因为在使用@Inject和变量类型推断时会被检测到,并添加进来。
如果指定的话,默认参数是在kmodule.xml中定义的KieSession的值属性和名称。
图10.12. 注入默认的StatelessKieSession,从Classpath KieContainer获得
@Inject
private StatelessKieSession ksession;
图10.13. 注入默认的StatelessKieSession,从动态KieModule获得
@Inject
@KReleaseId( groupId = "jar1", artifactId = "art1", version = "1.0")
private StatelessKieSession ksession;
图10.14. 'jar1.KBase1' KieBase版本加载时一起处理(同样不懂)
@Inject
@KSession("ksession1")
@KReleaseId( groupId = "jar1", rtifactId = "art1", version = "1.0")
private StatelessKieSession ksessionv10;
@Inject
@KSession("ksession1")
@KReleaseId( groupId = "jar1", rtifactId = "art1", version = "1.1")
private StatelessKieSession ksessionv11;
图10.15.使用'name'标签强制为'jar1.KBase1' StatelessKieSession创建新实例
@Inject
@KSession(value="ksession1", name="ks1")
@KReleaseId( groupId = "jar1", artifactId = "art1", version = "1.0")
private StatelessKieSession ksession1ks1
@Inject
@KSession(value="ksession1", name="ks2")
@KReleaseId( groupId = "jar1", artifactId = "art1", version = "1.0")
private StatelessKieSession ksession1ks2
10.3. API示例对比
CDI可以注入实例到字段,甚至以参数形式传递它们。下面是使用字段注入的例子。
图10.16. CDI示例,命名的KieSession
@Inject
@KSession("ksession1")
KieSession kSession;
public void go(PrintStream out) {
kSession.setGlobal("out", out);
kSession.insert(new Message("Dave", "Hello, HAL. Do you read me, HAL?"));
kSession.fireAllRules();
}
这种方式下代码更少,且比API方法更具声明性。
图10.17. 使用API实现相同功能的代码
public void go(PrintStream out) {
KieServices ks = KieServices.Factory.get();
KieContainer kContainer = ks.getKieClasspathContainer();
KieSession kSession = kContainer.newKieSession("ksession1");
kSession.setGlobal("out", out);
kSession.insert(new Message("Dave", "Hello, HAL. Do you read me, HAL?"));
kSession.fireAllRules();
}