和Jbpm3一樣,Jbpm4實現了自己的IOC容器。以現在的眼光看來,應用程序里一個IOC容器幾乎是居家必備的,否則,又要平白多出一坨一坨的工廠類和單態類來。
一、??? Jbpm4 IOC容器介紹
IOC容器的目的是管理組件和實現組件之間的解耦。和Spring里的BeanFactory對應,Jbpm4里的接口是Context,具體實現則是
WireContext。Context實際在Jbpm4里有更多的含義,它與Environment一起,共同構成了代碼運行的運行期環境。在這個環境
里可以獲取系統的組件,更為重要的是提供了數據庫連接(session)和事務(這個稍后會講)。
先來看看Context接口的核心方法:
??????Object?get(String?key);
??<T>?T?get(Class<T>?type);
很明顯,提供兩種從容器里獲取組件的方法,一種是通過name,一種是通過type。
對于IOC容器來說,一般情況下都會提供一種加載的方式,比如從xml文件進行加載、從資源文件進行加載。Jbpm4透過WireParser具備從xml加載的能力。
此外,WireContext通過一個Map緩存初始化后的組件。
二、??? Jbpm4 IOC容器實現
容器的實現有五個關鍵類和接口,分別是:WireParser、Binding、Descriptor、WireDefinition和WireContext。
?

WireParser讀取xml文件,同時WireParser會加載一系列的Binding(默認從jbpm.wire.bindins.xml文件讀取加載)。
Binding負責根據xml里元素的tag將xml元素轉換為對應的Descriptor。
Descriptor負責初始化對象。它們被添加到WireDefinition。
WireDefinition被WireParser返回給WireContext。WireContext創建對象時會訪問WireDefinition里的Descriptor,同時將初始化對象的任務委托給Descriptor自身。
需要注意的是:Jbpm4在初始化對象時有著四種策略,分別是:延遲創建和初始化、延遲創建和立刻初始化、立刻創建和延遲初始化、立刻創建和立刻初始化。
立刻創建:在WireContext創建完畢后對象就已經創建。
延遲創建:調用WireContext的get方法獲取該對象時才創建該對象。
初始化:一般完成對象屬性的注入等操作。
三、??? Jbpm4 IOC容器在Jbpm4里的應用
IOC容器在Jbpm4里最重要的作用就是加載Jbpm的總的配置文件(默認是jbpm.cfg.xml),這也是整個Jbpm應用的起點。大概掃一下這個配置文件:
<?xml?version="1.0"?encoding="UTF-8"?>
<jbpm-configuration?xmlns="http://jbpm.org/xsd/cfg">
??<process-engine-context>
?
????<repository-service?/>
????<repository-cache?/>
????<execution-service?/>
????<history-service?/>
????<management-service?/>
????<identity-service?/>
????<task-service?/>
????<hibernate-configuration>
??????<cfg?resource="jbpm.hibernate.cfg.xml"?/>????
????</hibernate-configuration>
????<hibernate-session-factory?/>
?
??</process-engine-context>
??<transaction-context>
????<repository-session?/>
????<pvm-db-session?/>
????<job-db-session?/>
????<task-db-session?/>
????<message-session?/>
????<timer-session?/>
????<history-session?/>
??</transaction-context>
</jbpm-configuration>
可以看到配置文件被分為了兩部分,分別是:process-engine-context和transaction-context。在實際應用中,它們
分別對應著兩個不同的WireContext:ProcessEngineContext和TransactionConext。
ProcessEngineContext覆蓋了jbpm4里最重要的服務類,這些類是全局唯一的,當然,ProcessEngineContext也是
獨此一份。本是同根生,命運各不同。TransactionConext則是在每次openEnvironment時重新創建,因為其包含了數據庫連接和
事務。
貫穿于整個Jbpm4中,這兩個Context被壓到Environment里(Environment和線程綁定),在任何需要的地方都能提供一條龍的服務。于是,在很多領域類里,利用這些服務實現充血模型就是很順理成章的一件事了。
總結: ProcessEngineContext給引擎領域模型提供全局的組件查找;TransactionConext提供數據庫相關服務。