歡迎您光臨本站 註冊首頁

jBPM4的運行期環境

←手機掃碼閱讀     火星人 @ 2014-03-10 , reply:0

萬物生長靠太陽,兒童的生長離不開土壤、空氣和水,當然,也離不開綠壩娘的調教.應用程序也是如此,離不開資料庫連接、事務、日誌、消息等,這些,共同構成了應用程序的運行期環境.

理想中的環境是什麼樣子的哩.好吧,一句話,召之即來,揮之即去,當需要某個服務時,ok,打個響指,該服務就準備好被調用了,調用完畢后也不用費心費力地擦屁股,不必老是提心弔膽有好事者追問:你擦了嗎,確定擦了?真的確定擦了?直接丟棄給環境降解處理,自然又環保,還有個好名聲叫專註領域邏輯.

一、運行期環境就是一個餐館

1、提供必要的服務作為一個餐館,必須有廚師做飯我吃,必須有桌子和椅子.作為運行期環境同樣如此,我要發消息,你得提供我發消息的Service,我要獲取節點任務,你得扔給我TaskService.

2、提供獲取這些服務的統一方式好吧,我不會親自到廚房告訴廚師我想吃什麼(我擔心這樣一來我會吃不下去),我也不會親自到收銀台給錢.這些服務有一個統一的獲取方式:服務員.我想吃什麼和結賬,告訴服務員即可.關鍵是這一方式要統一,要足夠簡單.Spring最懶,把服務給你全部注入了,當然你也可以握住BeanFactory的纖纖細手,一個一個的get.

3、提供特定於我線程不安全的服務我點了一盤魚香肉絲,隔壁也點了一盤魚香肉絲,結果服務員讓我們吃同一盤魚香肉絲.我立刻跳起來:靠,你們的服務不是線程安全的嗎?!Hibernate的Session正是屬於這麼一種情況,需要環境進行隔離,我的唯一職責就是吃飯!我的領域邏輯是如何優美的進餐!為此還要不斷重構我吃飯的姿勢哩.

好不容易吃完飯,付完款,正準備離場.服務員風度翩翩地走到我的身旁,我以為還有打折券供應,結果是:服務員小姐輕啟朱唇:先生,麻煩您把吃剩的盤子清洗完畢.

崩潰!

像資料庫連接的打開,關閉、事務的打開、提交等都屬於運行期環境應該做的事情.

4、 其他的七七八八雜事不少,例如統一的事件機制、許可權攔截等等.

二、jBPM4的運行期環境

好吧,先來看看如何建立jBPM4的運行期環境:

EnvironmentFactory environmentFactory = new DefaultEnvironmentFactory();




Environment environment
= environmentFactory.openEnvironment();
try {

everything available in
this block

}
finally {
environment.close();
}

兩個關鍵的類:EnvironmentFactory和Environment.

EnvironmentFactory是全局的,在整個應用程序中保持一個實例即可.

Environment則是每次方法調用則要new一個.

看看Environment的主要方法:

public abstract Object get(String name);
public abstract <T> T get(Class<T> type);

是的,environment為我們的代碼提供所需要的服務類實例.

那麼,如何獲得environment?

繼續看:

public static Environment getCurrent();

static,我喜歡也.方便、快捷,不管是在地上、車上還是房頂上,隨處都可調用.

那麼,為什麼Environment每次調用要new呢?

好吧,當你需要獲取資料庫Session的時候,是不是每次都要new呢.Environment提供的服務里包括了非線程安全的資料庫操作服務.

三、 jBPM4運行期環境的實現

1、JbpmConfiguration JbpmConfiguration是jBPM4里最重要的類,它是整個應用程序的入口.它實現了EnvironmentFactory介面.

JbpmConfiguration載入jBPM總的配置文件,還是大概掃一下這個配置文件:

<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.對應於兩個IOC容器(WireContext)的配置文件.

作為EnvironmentFactory,JbpmConfiguration持有成品process-engine-context對應的IOC容器(全局的)實例,持有半成品transaction-context的WireDefinition.當調用openEnvironment方法時,JbpmConfiguration會new Environment,然後將process-engine-context IOC填充入environment,同時初始化transaction-context IOC,並將其也填充入environment.這樣通過environment就可以獲得所有所需要的服務,包括全局的和非線程安全的服務實例.也就是environment透過IOC容器提供了查找各種服務的能力.

2、與線程綁定的environment

environment初始化之後,避免參數傳遞得一塌糊塗的方式就是將environment與線程綁定.看Environment的代碼:

static ThreadLocal<Environment> currentEnvironment = new ThreadLocal<Environment>();

static ThreadLocal<Stack<Environment>> currentEnvironmentStack = new ThreadLocal<Stack<Environment>>();

是的,在openEnvironment時,有這麼一行代碼:

Environment.pushEnvironment(environment);

這樣environment就與線程綁定了,可以通過Environment.getCurrent()任意調用了.

哪裡有壓迫,哪裡就有放抗.

在environment.close()方法里:

Environment.popEnvironment();

OK,結束.


[火星人 ] jBPM4的運行期環境已經有553次圍觀

http://coctec.com/docs/java/show-post-61301.html