posts - 193,  comments - 520,  trackbacks - 0
                  萬(wàn)物生長(zhǎng)靠太陽(yáng),兒童的生長(zhǎng)離不開(kāi)土壤、空氣和水,當(dāng)然,也離不開(kāi)綠壩娘的調(diào)教。應(yīng)用程序也是如此,離不開(kāi)數(shù)據(jù)庫(kù)連接、事務(wù)、日志、消息等,這些,共同構(gòu)成了應(yīng)用程序的運(yùn)行期環(huán)境。
                  理想中的環(huán)境是什么樣子的哩。好吧,一句話(huà),召之即來(lái),揮之即去,當(dāng)需要某個(gè)服務(wù)時(shí),ok,打個(gè)響指,該服務(wù)就準(zhǔn)備好被調(diào)用了,調(diào)用完畢后也不用費(fèi)心費(fèi)力地擦屁股,不必老是提心吊膽有好事者追問(wèn):你擦了嗎,確定擦了?真的確定擦了?直接丟棄給環(huán)境降解處理,自然又環(huán)保,還有個(gè)好名聲叫專(zhuān)注領(lǐng)域邏輯。

          一、    運(yùn)行期環(huán)境就是一個(gè)餐館
          1、    提供必要的服務(wù)
          作為一個(gè)餐館,必須有廚師做飯我吃,必須有桌子和椅子。作為運(yùn)行期環(huán)境同樣如此,我要發(fā)消息,你得提供我發(fā)消息的Service,我要獲取節(jié)點(diǎn)任務(wù),你得扔給我TaskService。

          2、    提供獲取這些服務(wù)的統(tǒng)一方式
          好吧,我不會(huì)親自到廚房告訴廚師我想吃什么(因?yàn)槲覔?dān)心這樣一來(lái)我會(huì)吃不下去),我也不會(huì)親自到收銀臺(tái)給錢(qián)。這些服務(wù)有一個(gè)統(tǒng)一的獲取方式:服務(wù)員。我想吃什么和結(jié)賬,告訴服務(wù)員即可。關(guān)鍵是這一方式要統(tǒng)一,要足夠簡(jiǎn)單。Spring最懶,把服務(wù)給你全部注入了,當(dāng)然你也可以握住BeanFactory的纖纖細(xì)手,一個(gè)一個(gè)的get。

          3、    提供特定于我線(xiàn)程不安全的服務(wù)
          我點(diǎn)了一盤(pán)魚(yú)香肉絲,隔壁也點(diǎn)了一盤(pán)魚(yú)香肉絲,結(jié)果服務(wù)員讓我們吃同一盤(pán)魚(yú)香肉絲。我立刻跳起來(lái):靠,你們的服務(wù)不是線(xiàn)程安全的嗎?!Hibernate的Session正是屬于這么一種情況,需要環(huán)境進(jìn)行隔離,我的唯一職責(zé)就是吃飯!我的領(lǐng)域邏輯是如何優(yōu)美的進(jìn)餐!為此還要不斷重構(gòu)我吃飯的姿勢(shì)哩。
          好不容易吃完飯,付完款,正準(zhǔn)備離場(chǎng)。服務(wù)員風(fēng)度翩翩地走到我的身旁,我以為還有打折券供應(yīng),結(jié)果是:服務(wù)員小姐輕啟朱唇:先生,麻煩您把吃剩的盤(pán)子清洗完畢。
          崩潰!
          像數(shù)據(jù)庫(kù)連接的打開(kāi),關(guān)閉、事務(wù)的打開(kāi)、提交等都屬于運(yùn)行期環(huán)境應(yīng)該做的事情。

          4、    其他的七七八八
          雜事不少,例如統(tǒng)一的事件機(jī)制、權(quán)限攔截等等。

          二、    jBPM4的運(yùn)行期環(huán)境
          好吧,先來(lái)看看如何建立jBPM4的運(yùn)行期環(huán)境:
          EnvironmentFactory environmentFactory = new DefaultEnvironmentFactory();
           
            
           
            Environment environment 
          = environmentFactory.openEnvironment();
            
          try {
           
               everything available in 
          this block 
           
            } 
          finally {
              environment.close();
            }


          兩個(gè)關(guān)鍵的類(lèi):EnvironmentFactory和Environment。

          EnvironmentFactory是全局的,在整個(gè)應(yīng)用程序中保持一個(gè)實(shí)例即可。

          Environment則是每次方法調(diào)用則要new一個(gè)。

          看看Environment的主要方法:
          public abstract Object get(String name);
          public abstract <T> T get(Class<T> type);


          是的,environment為我們的代碼提供所需要的服務(wù)類(lèi)實(shí)例。

          那么,如何獲得environment?
          繼續(xù)看:
          public static Environment getCurrent();

          static,我喜歡也。方便、快捷,不管是在地上、車(chē)上還是房頂上,隨處都可調(diào)用。

          那么,為什么Environment每次調(diào)用要new呢?
          好吧,當(dāng)你需要獲取數(shù)據(jù)庫(kù)Session的時(shí)候,是不是每次都要new呢。Environment提供的服務(wù)里包括了非線(xiàn)程安全的數(shù)據(jù)庫(kù)操作服務(wù)。

          三、    jBPM4運(yùn)行期環(huán)境的實(shí)現(xiàn)

          1、JbpmConfiguration
          JbpmConfiguration是jBPM4里最重要的類(lèi),它是整個(gè)應(yīng)用程序的入口。它實(shí)現(xiàn)了EnvironmentFactory接口。

                JbpmConfiguration加載jBPM總的配置文件,還是大概掃一下這個(gè)配置文件:
                <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。
          對(duì)應(yīng)于兩個(gè)IOC容器(WireContext)的配置文件。

          作為EnvironmentFactory,JbpmConfiguration持有成品process-engine-context對(duì)應(yīng)的IOC容器(全局的)實(shí)例,持有半成品transaction-context的WireDefinition。當(dāng)調(diào)用openEnvironment方法時(shí),JbpmConfiguration會(huì)new Environment,然后將process-engine-context IOC填充入environment,同時(shí)初始化transaction-context IOC,并將其也填充入environment。這樣通過(guò)environment就可以獲得所有所需要的服務(wù),包括全局的和非線(xiàn)程安全的服務(wù)實(shí)例。也就是environment透過(guò)IOC容器提供了查找各種服務(wù)的能力。


           

          2、與線(xiàn)程綁定的environment
          environment初始化之后,避免參數(shù)傳遞得一塌糊涂的方式就是將environment與線(xiàn)程綁定。看Environment的代碼:
            static ThreadLocal<Environment> currentEnvironment = new ThreadLocal<Environment>();

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


          是的,在openEnvironment時(shí),有這么一行代碼:
          Environment.pushEnvironment(environment);


          這樣environment就與線(xiàn)程綁定了,可以通過(guò)Environment.getCurrent()任意調(diào)用了。

          哪里有壓迫,哪里就有放抗。
          在environment.close()方法里:

          Environment.popEnvironment();


          OK,結(jié)束。




          http://www.aygfsteel.com/ronghao 榮浩原創(chuàng),轉(zhuǎn)載請(qǐng)注明出處:)
          posted on 2009-06-17 18:15 ronghao 閱讀(2817) 評(píng)論(5)  編輯  收藏 所屬分類(lèi): JbpmSide

          FeedBack:
          # re: jBPM4的運(yùn)行期環(huán)境
          2009-06-17 21:08 | 虎嘯龍吟
          有jbpm4這方面的例子?  回復(fù)  更多評(píng)論
            
          # re: jBPM4的運(yùn)行期環(huán)境
          2009-06-18 16:44 | 魔獸世界私服
          static ThreadLocal<Stack<Environment>> currentEnvironmentStack = new ThreadLocal<Stack<Environment>>();這一行是嘛?  回復(fù)  更多評(píng)論
            
          # re: jBPM4的運(yùn)行期環(huán)境
          2009-06-18 16:47 | WOW私服
          jBPM4的運(yùn)行期環(huán)境還真不是一般的復(fù)雜?  回復(fù)  更多評(píng)論
            
          # re: jBPM4的運(yùn)行期環(huán)境
          2009-06-22 16:40 | ronghao
          @魔獸世界私服
          實(shí)現(xiàn)了一個(gè)棧,可以壓入多個(gè)Environment  回復(fù)  更多評(píng)論
            
          # re: jBPM4的運(yùn)行期環(huán)境
          2009-06-22 16:41 | ronghao
          @WOW私服
          很簡(jiǎn)單的,即壓入了兩個(gè)IOC容器,并與線(xiàn)程綁定方便訪問(wèn)。  回復(fù)  更多評(píng)論
            
          <2009年6月>
          31123456
          78910111213
          14151617181920
          21222324252627
          2829301234
          567891011

          關(guān)注工作流和企業(yè)業(yè)務(wù)流程改進(jìn)。現(xiàn)就職于ThoughtWorks。新浪微博:http://weibo.com/ronghao100

          常用鏈接

          留言簿(38)

          隨筆分類(lèi)

          隨筆檔案

          文章分類(lèi)

          文章檔案

          常去的網(wǎng)站

          搜索

          •  

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 岗巴县| 福贡县| 荥经县| 龙山县| 永清县| 宁德市| 铁岭市| 开平市| 巨鹿县| 青田县| 湘乡市| 冕宁县| 沙田区| 黑龙江省| 汶川县| 徐闻县| 郧西县| 龙游县| 友谊县| 旌德县| 兴隆县| 酒泉市| 闻喜县| 岗巴县| 肇庆市| 漠河县| 个旧市| 怀集县| 二连浩特市| 罗定市| 石柱| 云南省| 三亚市| 武安市| 颍上县| 济源市| 张家界市| 陇南市| 南开区| 定兴县| 凌源市|