集成Spring
Drools 6.0重要變更
Drools Spring集成經歷了與Drools 6.0的變化完全一致的改造。 以下是一些主要的變化:
-
T*推薦的Drools Spring的前綴已經從“drools:”改為“kie:”
-
6.0中的新頂級標簽
-
kie:kmodule
-
kie:import (from version 6.2)
-
kie:releaseId (from version 6.2)
-
-
以下標簽不再作為頂級標簽有效。
-
kie:kbase - A child of the kie:kmodule tag.
-
kie:ksession - A child of the kie:kbase tag.
-
-
從以前的版本中刪除標簽Drools 5.x
-
drools:resources
-
drools:resource
-
drools:grid
-
drools:grid-node
-
與Drools Expert整合
在本節中,我們將解釋kie命名空間。
KieModule
<kie:kmodule> 定義了KieBase和相關的KieSession的集合。 kmodule標簽有一個MANDATORY參數“id”。
屬性 |
說明 |
需要 |
id |
Bean的id是從其他bean引用的名稱。標准的Spring ID語義適用。 |
Yes |
kmodule標簽只能包含以下標簽作為子標簽。
-
kie:kbase 請參閱Drools Expert文檔中的kmodule.xml文檔,以獲取有關kmodule需求的詳細說明。
KieBase
<kie:kbase>的參數作為屬性:
Attribute |
Description |
Required |
name |
KieBase的名字 |
Yes |
packages |
以逗號分隔的資源包列表將包含在此kbase |
No |
includes |
包含kbase名稱。來自相應kbase的所有資源都包含在這個kbase中。 |
No |
default |
布爾(TRUE / FALSE)。默認kbase,如果沒有提供,則假定為FALSE |
No |
scope |
prototype | singleton。如果沒有提供假設為singleton(默認) |
No |
eventProcessingMode |
事件處理模式。有效的選項是STREAM,CLOUD |
No |
equalsBehavior |
有效的選項是IDENTITY,EQUALITY |
No |
declarativeAgenda |
有效選項是啟用,禁用,true,false |
No |
kbase標簽只能包含以下標簽作為子標簽
-
kie:ksession
<kie:kbase>的定義示例
kmodule可以包含多個(1..n)kbase元素。
<kie:kmodule id="sample_module"> <kie:kbase name="kbase1" packages="org.drools.spring.sample"> ... </kie:kbase> </kie:kmodule> <bean id="kiePostProcessor" class="org.kie.spring.KModuleBeanFactoryPostProcessor"/>
Spring Bean范圍(用於KieBase和KieSession)
當定義一個KieBase或一個KieSession時,你可以選擇為該bean聲明一個范圍。例如,為了強制Spring在每次需要時產生一個新的bean實例,你應該聲明bean的scope屬性是“prototype”。類似的方法,如果你希望Spring在每次需要的時候返回相同的bean實例,你應該聲明bean的scope屬性是'singleton'。
重要的提示
對於KMODULE對象的正確初始化(kbase / ksession),它是強制性的類型org.kie.spring.KModuleBeanFactoryPostProcessor
或的一個bean`org.kie.spring.annotations.KModuleAnnotationPostProcessor
來限定。
<bean id="kiePostProcessor" class="org.kie.spring.KModuleBeanFactoryPostProcessor"/>
<bean id="kiePostProcessor" class="org.kie.spring.annotations.KModuleAnnotationPostProcessor"/>
沒有org.kie.spring.KModuleBeanFactoryPostProcessor或org.kie.spring.annotations.KModuleAnnotationPostProcessor bean定義,kie-spring集成將無法工作。 |
KieSessions
<kie:ksession>元素定義了KieSessions。相同的標記用於定義有狀態(org.kie.api.runtime.KieSession)和無狀態(org.kie.api.runtime.StatelessKieSession)會話。
<kie:ksession>的參數作為屬性:
Attribute |
Description |
Required |
name |
ksession的名字。 |
Yes |
type |
是會話stateful還是stateless?。如果此屬性為空或缺少,則會話將被視為Stateful類型。 |
No |
default |
這是默認會話嗎? |
no |
scope |
prototype | singleton. 如果沒有提供假設為單例(默認) |
no |
clockType |
REALTIME或PSEUDO |
no |
listeners-ref |
指定對事件偵聽器組的引用(請參閱https://docs.jboss.org/drools/release/7.4.1.Final/drools-docs/html_single/index.html#_kie_grouping_listeners ['定義偵聽器組')]以下部分)。 |
no |
<kie:kmodule id="sample-kmodule"> <kie:kbase name="drl_kiesample3" packages="drl_kiesample3"> <kie:ksession name="ksession1" type="stateless"/> <kie:ksession name="ksession2"/> </kie:kbase> </kie:kmodule> <bean id="kiePostProcessor" class="org.kie.spring.KModuleBeanFactoryPostProcessor"/>
Spring Bean范圍(用於KieBase和KieSession)
當定義一個KieBase或一個KieSession時,你可以選擇為該bean聲明一個范圍。例如,為了強制Spring在每次需要時產生一個新的bean實例,你應該聲明bean的scope屬性是“prototype”。類似的方法,如果你希望Spring在每次需要的時候返回相同的bean實例,你應該聲明bean的scope屬性是'singleton'。
https://docs.jboss.org/drools/release/7.4.1.Final/drools-docs/html_single/index.html#_kie_releaseidhttps://docs.jboss.org/drools/release/7.4.1.Final/drools-docs/html_single/index.html#_kie_releaseid[14.2.5. Kie:ReleaseId]
<kie:releaseId>的屬性參數:
Attribute |
Description |
Required |
id |
Bean的id是從其他bean引用的名稱。標准的Spring ID語義適用。 |
Yes |
groupId |
ggroupId來自Maven GAV |
Yes |
artifactId |
來自Maven GAV的artifactId |
Yes |
version |
Maven GAV |
Yes |
<kie:releaseId id="beanId" groupId="org.kie.spring" artifactId="named-artifactId" version="1.0.0-SNAPSHOT"/>
Kie:Import
從版本6.2開始,kie-spring允許從classpath中的kjar中導入kie對象。目前支持導入kie對象的兩種模式。
Attribute |
Description |
Required |
releaseId |
引用一個Bean ID。標准的Spring ID語義適用。 |
No |
enableScanner |
啟用掃描儀。該屬性僅在指定了“releaseId”的情況下使用。 |
No |
scannerInterval |
掃描間隔以毫秒為單位。該屬性僅在指定了“releaseId”的情況下使用。 |
No |
Global Import
import標簽將強制自動掃描類路徑上的所有jar,初始化Kie對象(Kbase / KSessions)並將這些對象導入到spring上下文中。
Global Import
<kie:import />
Specific Import - ReleaseId
在導入標簽上使用releaseId-ref屬性將初始化特定的Kie對象(Kbase / KSessions)並將這些對象導入到spring上下文中。
<kie:import releaseId-ref="namedKieSession"/> <kie:releaseId id="namedKieSession" groupId="org.drools" artifactId="named-kiesession" version="7.4.1.Final"/>
Kie掃描功能可以啟用KieBase的導入與一個特定的releaseId。此功能目前不適用於全球導入。
<kie:import releaseId-ref="namedKieSession" enableScanner="true" scannerInterval="1000"/> <kie:releaseId id="namedKieSession" groupId="org.drools" artifactId="named-kiesession" version="7.4.1.Final"/>
如果掃描器已定義並啟用,則會創建一個隱式KieScanner對象並將其插入到彈簧上下文中。它可以從春天的背景來回顧。
// the implicit name would be releaseId#scanner KieScanner releaseIdScanner = context.getBean("namedKieSession#scanner", KieScanner.class); releaseIdScanner.scanNow();
kie-ci必須在類路徑上可用,才能使releaseId導入功能正常工作。 |
Annotations
@KContainer,@KBase和@KSession都支持可選的“name”屬性。 Spring通常在注入時會“獲取”,所有注入都會為同一組注釋接收相同的實例。 “名稱”注釋強制每個名稱的唯一實例,盡管該名稱的所有實例都將是identity equals。
@KReleaseId
用於將實例綁定到KieModule的特定版本。如果kie-ci位於類路徑上,則會自動解析依賴關系,從遠程存儲庫下載。
@KContainer
@KContainer private KieContainer kContainer;
@KContainer @KReleaseId(groupId = "jar1", artifactId = "art1", version = "1.1") private KieContainer kContainer;
@KContainer(name = "kc1") @KReleaseId(groupId = "jar1", artifactId = "art1", version = "1.1") private KieContainer kContainer;
@KBase
默認的參數,如果給定的,映射到值屬性,並指定春季xml文件中的KieBase的名稱。
@KBase private KieBase kbase;
@KBase @KReleaseId( groupId = "jar1", artifactId = "art1", version = "1.0") private KieBase kbase;
@KBase("kbase1") @KReleaseId( groupId = "jar1", artifactId = "art1", version = "1.0") private KieBase kbase1v10; @KBase("kbase1") @KReleaseId( groupId = "jar1", artifactId = "art1", version = "1.1") private KieBase kbase1v11;
@KSession("ksession1") @KReleaseId( groupId = "jar1", artifactId = "art1", version = "1.0") private KieSession ksession11kb2; @KSession("ksession1") @KReleaseId( groupId = "jar1", artifactId = "art1", version = "1.1") private KieSession ksession11kb2;
@KSession for KieSession
默認參數(如果給出)映射到value屬性,並從kmodule.xml或spring xml文件指定KieSession的名稱
@KSession private KieSession ksession;
@KSession @KReleaseId( groupId = "jar1", artifactId = "art1", version = "1.0") private KieSession ksession;
@KSession("ksession1") @KReleaseId( groupId = "jar1", artifactId = "art1", version = "1.0") private KieSession ksessionv10; @KSession("ksession1") @KReleaseId( groupId = "jar1", artifactId = "art1", version = "1.1") private KieSession ksessionv11;
@KSession("ksession1") @KReleaseId( groupId = "jar1", artifactId = "art1", version = "1.0") private KieSession ksession1ks1 @KSession("ksession1") @KReleaseId( groupId = "jar1", artifactId = "art1", version = "1.0") private KieSession ksession1ks2
@KSession for StatelessKieSession
默認參數(如果給出)映射到value屬性,並從kmodule.xml或spring xml文件指定KieSession的名稱。
@KSession private StatelessKieSession ksession;
@KSession @KReleaseId( groupId = "jar1", artifactId = "art1", version = "1.0") private StatelessKieSession ksession;
@KSession("ksession1") @KReleaseId( groupId = "jar1", rtifactId = "art1", version = "1.0") private StatelessKieSession ksessionv10; @KSession("ksession1") @KReleaseId( groupId = "jar1", rtifactId = "art1", version = "1.1") private StatelessKieSession ksessionv11;
@KSession(value="ksession1", name="ks1") @KReleaseId( groupId = "jar1", artifactId = "art1", version = "1.0") private StatelessKieSession ksession1ks1 @KSession(value="ksession1", name="ks2") @KReleaseId( groupId = "jar1", artifactId = "art1", version = "1.0") private StatelessKieSession ksession1ks2
重要的提示
當使用注釋時,為了正確初始化kmodule對象(kbase / ksession),必須定義org.kie.spring.annotations.KModuleAnnotationPostProcessor類型的Bean
<bean id="kiePostProcessor" class="org.kie.spring.annotations.KModuleAnnotationPostProcessor"/>
<context:component-scan base-package="org.kie.spring.annotations"/>
使用注釋時后處理器是不同的。 |
事件監聽器
Drools支持添加三種類型的監聽器到KieSessions - AgendaListener,WorkingMemoryListener,ProcessEventListener
kie-spring模塊允許您使用XML標簽將這些偵聽器配置為KieSessions。這些標記與實際的監聽器接口名稱相同,即<kie:agendaEventListener …>,<kie:ruleRuntimeEventListener …>和<kie:processEventListener …>。
kie-spring提供了將偵聽器定義為獨立(個人)偵聽器的功能,並將它們定義為一個組。
定義獨立的監聽器
屬性
Attribute |
Required |
Description |
ref |
No |
對另一個聲明的bean的引用。 |
<bean id="mock-agenda-listener" class="mocks.MockAgendaEventListener"/> <bean id="mock-rr-listener" class="mocks.MockRuleRuntimeEventListener"/> <bean id="mock-process-listener" class="mocks.MockProcessEventListener"/> <kie:kmodule id="listeners_kmodule"> <kie:kbase name="drl_kiesample" packages="drl_kiesample"> <kie:ksession name="ksession2"> <kie:agendaEventListener ref="mock-agenda-listener"/> <kie:processEventListener ref="mock-process-listener"/> <kie:ruleRuntimeEventListener ref="mock-rr-listener"/> </kie:ksession> </kie:kbase> </kie:kmodule> <bean id="kiePostProcessor" class="org.kie.spring.KModuleBeanFactoryPostProcessor"/>
嵌套元素
-
bean
-
class = String
-
name = String (可選)示例199.偵聽器配置示例 - 使用嵌套的Bean。
-
<kie:kmodule id="listeners_module"> <kie:kbase name="drl_kiesample" packages="drl_kiesample"> <kie:ksession name="ksession1"> <kie:agendaEventListener> <bean class="mocks.MockAgendaEventListener"/> </kie:agendaEventListener> </kie:ksession> </kie:kbase> </kie:kmodule> <bean id="kiePostProcessor" class="org.kie.spring.KModuleBeanFactoryPostProcessor"/>
空標簽:沒有'ref'且沒有nestedbean的聲明
當定義偵聽器時沒有引用實現bean而不包含嵌套bean時, <drools:ruleRuntimeEventListener /> 底層實現添加了在API中定義的偵聽器的Debug版本。
調試偵聽器將相應的Event toString消息打印到_System.err。 _
<bean id="mock-agenda-listener" class="mocks.MockAgendaEventListener"/> <bean id="mock-rr-listener" class="mocks.MockRuleRuntimeEventListener"/> <bean id="mock-process-listener" class="mocks.MockProcessEventListener"/> <kie:kmodule id="listeners_module"> <kie:kbase name="drl_kiesample" packages="drl_kiesample"> <kie:ksession name="ksession2"> <kie:agendaEventListener /> <kie:processEventListener /> <kie:ruleRuntimeEventListener /> </kie:ksession> </kie:kbase> </kie:kmodule> <bean id="kiePostProcessor" class="org.kie.spring.KModuleBeanFactoryPostProcessor"/>
不同聲明樣式的混合搭配
drools-spring模塊允許您在相同的KieSession中混合和匹配不同的聲明式樣式。下面的例子提供了更多的清晰。
<bean id="mock-agenda-listener" class="mocks.MockAgendaEventListener"/> <bean id="mock-rr-listener" class="mocks.MockRuleRuntimeEventListener"/> <bean id="mock-process-listener" class="mocks.MockProcessEventListener"/> <kie:kmodule id="listeners_module"> <kie:kbase name="drl_kiesample" packages="drl_kiesample"> <kie:ksession name="ksession1"> <kie:agendaEventListener> <bean class="org.kie.spring.mocks.MockAgendaEventListener"/> </kie:agendaEventListener> </kie:ksession> <kie:ksession name="ksession2"> <kie:agendaEventListener ref="mock-agenda-listener"/> <kie:processEventListener ref="mock-process-listener"/> <kie:ruleRuntimeEventListener ref="mock-rr-listener"/> </kie:ksession> </kie:kbase> </kie:kmodule> <bean id="kiePostProcessor" class="org.kie.spring.KModuleBeanFactoryPostProcessor"/>
定義相同類型的多個偵聽器
為KieSession定義多個相同事件監聽器類型的bean也是有效的。
<bean id="mock-agenda-listener" class="mocks.MockAgendaEventListener"/> <kie:kmodule id="listeners_module"> <kie:kbase name="drl_kiesample" packages="drl_kiesample"> <kie:ksession name="ksession1"> <kie:agendaEventListener ref="mock-agenda-listener"/> <kie:agendaEventListener> <bean class="org.kie.spring.mocks.MockAgendaEventListener"/> </kie:agendaEventListener> </kie:ksession> </kie:kbase> </kie:kmodule> <bean id="kiePostProcessor" class="org.kie.spring.KModuleBeanFactoryPostProcessor"/>
定義一組監聽器
drools-spring允許分組的監聽器。當您定義一組偵聽器並希望將它們附加到多個會話時,這是特別有用的。分組功能也非常有用,當我們為“測試”定義一組監聽器,然后將其切換為“生產”使用時。
屬性
Attribute |
Required |
Description |
ID |
yes |
唯一標識符 |
嵌套元素
-
kie:agendaEventListener…
-
kie:ruleRuntimeEventListener…
-
kie:processEventListener…
上述子元素可以以任何順序聲明。一個組中只允許一個類型的聲明。 |
示例
<bean id="mock-agenda-listener" class="mocks.MockAgendaEventListener"/> <bean id="mock-rr-listener" class="mocks.MockRuleRuntimeEventListener"/> <bean id="mock-process-listener" class="mocks.MockProcessEventListener"/> <kie:kmodule id="listeners_module"> <kie:kbase name="drl_kiesample" packages="drl_kiesample"> <kie:ksession name="statelessWithGroupedListeners" type="stateless" listeners-ref="debugListeners"/> </kie:kbase> </kie:kmodule> <kie:eventListeners id="debugListeners"> <kie:agendaEventListener ref="mock-agenda-listener"/> <kie:processEventListener ref="mock-process-listener"/> <kie:ruleRuntimeEventListener ref="mock-rr-listener"/> </kie:eventListeners> <bean id="kiePostProcessor" class="org.kie.spring.KModuleBeanFactoryPostProcessor"/>
Loggers
Drools支持將兩種類型的日志添加到KieSessions - ConsoleLogger,FileLogger .
kie-spring模塊允許您使用XML標簽將這些記錄器配置為KieSessions。 這些標簽與實際的記錄器接口名稱相同,即<kie:consoleLogger …>和<kie:fileLogger …>。
定義一個控制台logger:
控制台日志可以通過使用 <kie:consoleLogger /> 標簽附加到KieSession。這個標簽沒有屬性,必須直接出現在<kie:ksession …>元素下。
<kie:kmodule id="loggers_module"> <kie:kbase name="drl_kiesample" packages="drl_kiesample"> <kie:ksession name="ConsoleLogger-statefulSession" type="stateful"> <kie:consoleLogger/> </kie:ksession> </kie:kbase> </kie:kmodule> <bean id="kiePostProcessor" class="org.kie.spring.KModuleBeanFactoryPostProcessor"/>
定義文件logger:
文件記錄器可以通過使用 <kie:fileLogger /> 標簽附加到KieSession。該標簽具有以下屬性,並且必須直接存在於<kie:ksession …>元素下。
Attribute |
Required |
Description |
ID |
yes |
唯一標識符 |
file |
yes |
磁盤上實際文件的路徑 |
threaded |
no |
默認為false。有效值為“true”或“false” |
interval |
no |
整數。指定從內存刷新到磁盤的時間間隔。 |
<kie:kmodule id="loggers_module"> <kie:kbase name="drl_kiesample" packages="drl_kiesample"> <kie:ksession name="ConsoleLogger-statefulSession" type="stateful"> <kie:fileLogger id="fl_logger" file="#{ systemProperties['java.io.tmpdir'] }/log1"/> <kie:fileLogger id="tfl_logger" file="#{ systemProperties['java.io.tmpdir'] }/log2" threaded="true" interval="5"/> </kie:ksession> </kie:kbase> </kie:kmodule> <bean id="kiePostProcessor" class="org.kie.spring.KModuleBeanFactoryPostProcessor"/>
關閉FileLogger
為防止泄漏,建議以編程方式關閉_ <kie:fileLogger …> _。
LoggerAdaptor adaptor = (LoggerAdaptor) context.getBean("fl_logger"); adaptor.close();
定義批處理命令
可以使用 <kie:batch> 元素為給定的ksession定義一組批處理命令。該標記沒有屬性,並且必須直接存在於<kie:ksession …>元素下。支持的命令是 初始化批處理命令
-
insert-object
-
ref = String (optional)
-
Anonymous bean
-
-
set-global
-
identifier = String (required)
-
reg = String (optional)
-
Anonymous bean
-
-
fire-all-rules
-
max : n
-
-
fire-until-halt
-
start-process
-
parameter
-
identifier = String (required)
-
ref = String (optional)
-
Anonymous bean
-
-
-
signal-event
-
ref = String (optional)
-
event-type = String (required)
-
process-instance-id =n (optional)Example 206. Batch commands - example
-
<kie:kmodule id="batch_commands_module"> <kie:kbase name="drl_kiesample" packages="drl_kiesample"> <kie:ksession name="ksessionForCommands" type="stateful"> <kie:batch> <kie:insert-object ref="person2"/> <kie:set-global identifier="persons" ref="personsList"/> <kie:fire-all-rules max="10"/> </kie:batch> </kie:ksession> </kie:kbase> </kie:kmodule> <bean id="kiePostProcessor" class="org.kie.spring.KModuleBeanFactoryPostProcessor"/>
持久化
持久化配置選項
-
jpa-persistence
-
transaction-manager
-
ref = String
-
entity-manager-factory
-
ref = StringExample 207. ksession JPA configuration example
-
<kie:kstore id="kstore" /> <!-- provides KnowledgeStoreService implementation --> <bean id="myEmf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="ds" /> <property name="persistenceUnitName" value="org.drools.persistence.jpa.local" /> </bean> <bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="myEmf" /> </bean> <kie:kmodule id="persistence_module"> <kie:kbase name="drl_kiesample" packages="drl_kiesample"> <kie:ksession name="jpaSingleSessionCommandService"> <kie:configuration> <kie:jpa-persistence> <kie:transaction-manager ref="txManager"/> <kie:entity-manager-factory ref="myEmf"/> </kie:jpa-persistence> </kie:configuration> </kie:ksession> </kie:kbase> </kie:kmodule> <bean id="kiePostProcessor" class="org.kie.spring.KModuleBeanFactoryPostProcessor"/>
利用其他Spring功能
本節提供了與Drools Expert集成時利用其他標准彈簧功能的詳細信息。
使用Spring表達式(Spel)
<kie:kmodule id="batch_commands_module"> <kie:kbase name="drl_kiesample" packages="#{packageRepository.packages}"> <kie:ksession name="ksessionForCommands" type="stateful"/> </kie:kbase> </kie:kmodule> <bean id="kiePostProcessor" class="org.kie.spring.KModuleBeanFactoryPostProcessor"/> <bean id="packageRepository" class="sample.package.class.PackageRepo"> <property name="packages" value="drl_kiesample3"> </bean>
<kie:kmodule id="loggers_module"> <kie:kbase name="drl_kiesample" packages="drl_kiesample"> <kie:ksession name="ConsoleLogger-statefulSession" type="stateful"> <kie:fileLogger id="fl" file="#{ systemProperties['java.io.tmpdir'] }/log1"/> <kie:fileLogger id="tfl" file="#{ systemProperties['java.io.tmpdir'] }/log2" threaded="true" interval="5"/> </kie:ksession> </kie:kbase> </kie:kmodule> <bean id="kiePostProcessor" class="org.kie.spring.KModuleBeanFactoryPostProcessor"/>
使用Spring配置文件
Spring 3.1為spring-beans模式的beans元素引入了新的profile屬性。在不同環境中啟用和禁用配置文件時,此屬性充當開關。這個屬性的一個潛在的用途可以是在“開發”環境中使用調試記錄器定義相同的kbase,並且在“產品”環境中沒有記錄器。
下面的代碼片段說明了“配置文件”的概念。
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:kie="http://drools.org/schema/kie-spring" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://drools.org/schema/kie-spring http://drools.org/schema/kie-spring.xsd"> <beans profile="development"> <kie:kmodule id="test-kmodule"> <kie:kbase name="drl_kiesample" packages="drl_kiesample"> <kie:ksession name="ksession1" type="stateless"> <kie:consoleLogger /> </kie:ksession> </kie:kbase> </kie:kmodule> ... </beans> <beans profile="production"> <kie:kmodule id="test-kmodule"> <kie:kbase name="drl_kiesample" packages="drl_kiesample"> <kie:ksession name="ksession1" type="stateless"/> </kie:kbase> </kie:kmodule> ... </beans> </beans>
如上所示,Spring XML包含配置文件的定義。在加載ApplicationContext時,你必須告訴Spring你正在加載哪個配置文件。
有幾種選擇你的配置文件的方法,最有用的是使用“spring.profiles.active”系統屬性。
System.setProperty("spring.profiles.active", "development"); ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
顯然,如上所示對事物進行硬編碼並不是一個好習慣,推薦的做法是保持系統屬性定義獨立於應用程序。
-Dspring.profiles.active="development"
配置文件也可以通過編程方式加載和啟用
...
GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("beans.xml"); ConfigurableEnvironment env = ctx.getEnvironment(); env.setActiveProfiles("development"); ctx.refresh(); ...
與jBPM Human Task集成
本章描述了在使用Spring配置人工任務服務器時所使用的基礎架構,以及一些關於在執行此操作時使用的基礎架構的信息。
如何用jBPM人工任務配置Spring
TjBPM人工任務服務器可以配置為使用Spring持久性。 [_kie_spring_human_task_example]是一個使用本地事務和Spring的線程安全的例子EntityManager代理。
下圖顯示了https://docs.jboss.org/drools/release/7.4.1.Final/drools-docs/html_single/index.html#_kie_spring_human_task_example 中使用的依賴關系圖。

一個“TaskService”實例依賴於另外兩種類型的bean:一個drools“SystemEventListener”bean以及一個“TaskSessionSpringFactoryImpl”bean。 TaskSessionSpringFactoryImpl bean被注入到TaskService bean中,因為這會導致循環依賴。為了解決這個問題,當TaskService
bean被注入到TaskSessionSpringFactoryImpl
bean中時,所使用的setter方法秘密地將TaskSessionSpringFactoryImpl實例重新注入到TaskService
中,並初始化TaskService
bean也是。
“TaskSessionSpringFactoryImpl”bean負責在人工任務中創建所有處理事務和持久性上下文管理的內部實例。除了一個“TaskService”實例外,這個bean還需要注入一個事務管理器和一個持久化上下文。具體來說,它需要一個“HumanTaskSpringTransactionManager”bean(作為事務管理器)的實例和一個“SharedEntityManagerBean”bean(作為持久化上下文實例)的實例。
我們還使用了一些標准的Spring bean來配置持久性:有一個bean用來存放EntityManagerFactory實例和SharedEntityManagerBean實例。 SharedEntityManagerBean為實際的EntityManager提供了一個共享的,線程安全的代理。
“HumanTaskSpringTransactionManager”bean作為Spring事務管理器的包裝器,在這里是JpaTransactionManager。由於這個,“JpaTransactionManager”bean的一個實例也被實例化了。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jbpm="http://drools.org/schema/drools-spring" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://drools.org/schema/drools-spring org/drools/container/spring/drools-spring-1.2.0.xsd"> <!-- persistence & transactions--> <bean id="htEmf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="persistenceUnitName" value="org.jbpm.task" /> </bean> <bean id="htEm" class="org.springframework.orm.jpa.support.SharedEntityManagerBean"> <property name="entityManagerFactory" ref="htEmf"/> </bean> <bean id="jpaTxMgr" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="htEmf" /> <!-- this must be true if using the SharedEntityManagerBean, and false otherwise --> <property name="nestedTransactionAllowed" value="true"/> </bean> <bean id="htTxMgr" class="org.drools.container.spring.beans.persistence.HumanTaskSpringTransactionManager"> <constructor-arg ref="jpaTxMgr" /> </bean> <!-- human-task beans --> <bean id="systemEventListener" class="org.drools.SystemEventListenerFactory" factory-method="getSystemEventListener" /> <bean id="taskService" class="org.jbpm.task.service.TaskService" > <property name="systemEventListener" ref="systemEventListener" /> </bean> <bean id="springTaskSessionFactory" class="org.jbpm.task.service.persistence.TaskSessionSpringFactoryImpl" init-method="initialize" depends-on="taskService" > <!-- if using the SharedEntityManagerBean, make sure to enable nested transactions --> <property name="entityManager" ref="htEm" /> <property name="transactionManager" ref="htTxMgr" /> <property name="useJTA" value="false" /> <property name="taskService" ref="taskService" /> </bean> </beans>
當使用“SharedEntityManagerBean”實例時,配置Spring事務管理器使用嵌套事務很重要。 這是因為SharedEntityManagerBean
是一個transactional持久化上下文,每次操作后都會關閉持久化上下文。 但是,人工任務服務器需要能夠在操作之后訪問(保持)實體。 嵌套事務允許我們仍然可以訪問實體,否則這些實體將被分離並且不再可訪問,特別是在使用使用實體的延遲初始化的ORM框架時。
另外,雖然TaskSessionSpringFactoryImpl bean接受了一個“useJTA”參數,但是目前與Spring的JTA事務還沒有經過充分的測試。