<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 193,  comments - 520,  trackbacks - 0
     
         摘要: 使用Selenium測試showModalDialog模態對話框一直是一件困難的事情,本文提出一種hack解決的方法。  閱讀全文
    posted @ 2009-07-27 21:17 ronghao 閱讀(3592) | 評論 (0)編輯 收藏
           現在流行抱大腿,不過對眼光的要求也高。要不就如高也,即使四眼,一樣無用。對Java企業開發而言,Spring的腿則是一定要抱的。而所謂抱Spring的腿,無外乎三點:

    一是通過Spring暴露出服務,將服務配置到Spring的IOC容器里;
    二是在自己的運行環境里訪問到Spring的IOC容器,能夠輕松使用Spring容器里所配置的服務;
    三是對于具有事務管理特性的項目來說,將事務管理與Spring的事務管理進行合并。

            下面分別討論:

    一、    通過Spring暴露服務
    還記得在jBPM4的運行期環境里提到的JbpmConfiguration嗎?它是整個jBPM4的入口,并且是整個應用獨此一份的。通過它可以獲取processEngine,并藉此獲得工作流引擎所提供的各種服務:

    ProcessEngine processEngine 
    = new Configuration()
          .buildProcessEngine();


    RepositoryService repositoryService 
    = processEngine.getRepositoryService();
    ExecutionService executionService 
    = processEngine.getExecutionService();
    TaskService taskService 
    = processEngine.getTaskService();
    HistoryService historyService 
    = processEngine.getHistoryService();
    ManagementService managementService 
    = processEngine.getManagementService();

    通過Spring暴露這些服務,配置如下:
    <bean id="jbpmConfiguration" class="org.jbpm.pvm.internal.cfg.SpringConfiguration">
            
    <constructor-arg value="be/inze/spring/demo/jbpm.cfg.xml" />
        
    </bean>
       
        
    <bean id="processEngine" factory-bean="jbpmConfiguration" factory-method="buildProcessEngine" />
        
    <bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService" />
        
    <bean id="executionService" factory-bean="processEngine" factory-method="getExecutionService" />


    細心的你會發現,配置時使用了JbpmConfiguration 的子類SpringConfiguration。SpringConfiguration相比JbpmConfiguration有哪些增強呢,下面再講。總之,現在,就可以使用Spring來獲取或注入這些Jbpm4所提供的服務了。

    二、在environment里加入SpringContext
    jBPM4的environment(運行期環境)提供Engine IOC(process-engine-context)和Transaction IOC(transaction-context)。要想在運行期方便地訪問到Spring里所配置的服務,最直接的方法就是在environment里加入Spring IOC(applicationContext)的引用。
    SpringConfiguration即是對JbpmConfiguration增強了對Spring IOC的一個引用。
     
    SpringConfiguration是如何做到的呢?簡單,實現Spring的ApplicationContextAware接口,自動持有applicationContext,然后openEnvironment時將其加入environment。

    environment.setContext(new SpringContext(applicationContext));


    SpringContext是對applicationContext的簡單封裝。

    那么什么從Engine IOC移民到Spring IOC了呢?是的,最重要的就是Hibernate Session Factory。

    在jbpm.cfg.xml的process-engine-context里干掉:

        <hibernate-configuration>
          
    <cfg resource="jbpm.hibernate.cfg.xml" />    
        
    </hibernate-configuration>

        
    <hibernate-session-factory />

     
    相關配置挪動至Spring配置文件。

    三、    事務
    哪里有數據庫操作,哪里就有事務。對于嵌入式工作流而言,最重要的集成就是事務的集成。這里先分析jBPM4的事務實現,然后再介紹集成入Spring的事務實現。

    1、    Command模式
    jBPM4的邏輯實現采用了Command模式。
     
    采用Command模式后,jBPM4對CommandService構造攔截器(Interceptor)鏈,配置在jbpm.cfg.xml的process-engine-context里:
    <command-service>
          
    <retry-interceptor />
          
    <environment-interceptor />
          
    <standard-transaction-interceptor />
        
    </command-service>


    2、    原有的事務實現
    jBPM4原有的事務通過StandardTransactionInterceptor實現,在CommandService執行Command之前打開事務(實際委派Hibernate的事務管理),完成后提交/回滾。
     
    jBPM4的事務是基于Command的。

    3、    集成入Spring的事務實現
    Spring的事務是基于服務調用的。

    使jBPM4使用Spring提供的事務:
    <command-service>
          
    <retry-interceptor />
          
    <environment-interceptor />
          
    <spring-transaction-interceptor current="true" />
    </command-service>


    攔截器換用SpringTransactionInterceptor,SpringTransactionInterceptor從environment 提供的Spring IOC獲取PlatformTransactionManager,使用事務模板回調Command,事務傳播模式強制加入當前事務。

    同時,對hibernate session的配置(jbpm.cfg.xml的transaction-context)強制從當前線程中獲取:
    <hibernate-session current="true"/>

    并干掉原有的事務實現:
    <transaction />

    參考文檔:
    http://www.slideshare.net/guest8d4bce/spring-integration-with-jbpm4


    posted @ 2009-06-22 16:38 ronghao 閱讀(7373) | 評論 (7)編輯 收藏
            萬物生長靠太陽,兒童的生長離不開土壤、空氣和水,當然,也離不開綠壩娘的調教。應用程序也是如此,離不開數據庫連接、事務、日志、消息等,這些,共同構成了應用程序的運行期環境。
            理想中的環境是什么樣子的哩。好吧,一句話,召之即來,揮之即去,當需要某個服務時,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,結束。


    posted @ 2009-06-17 18:15 ronghao 閱讀(2813) | 評論 (5)編輯 收藏
    一、目前的情況
    目前我們要進行持續集成的對象是一個有著100人左右的開發團隊,他們開發著一套很龐大的系統。整個開發團隊劃分為多個開發小組進行協同開發,每個開發小組負責2-3個模塊的開發,實際這里的模塊已經相當于一個中小型系統。各模塊所有的類都通過eclipse整體編譯在一起,直接放置在WEB-INF/classes下。本地是無法啟動整個系統的,需要耗費大量的資源。

    二、碰到的問題
    在了解具體情況之前,我們最初的想法是為整個產品做一個持續集成,但是很快就發現這一想法存在很多的問題:
    1、整個產品每次構建的時間會很長,這個時間包括代碼的編譯、啟動Weblogic,完成自動化測試,同時對服務器的硬件要求非常高
    2、因為構建時間長,所以如果本地構建通過后再提交會嚴重影響開發效率,況且本地的硬件條件很可能啟動不了
    3、如果本地不構建提交,則由于開發人數眾多,構建會非常不穩定,會經常處于失敗狀態。而構建失敗會導致后續提交的阻塞。
    4、作為一個100人的開發團隊,代碼提交會引發頻繁的服務器構建,服務器無法負擔。

    同時作為客戶,他們有這樣一種想法:敏捷開發是好的,但是不適合于大的項目和大的團隊。

    最重要的問題集中在兩個方面
    1、啟動整個產品過于重量級(不包括自動化測試的情況下已經如此)
    2、如何不影響開發人員的頻繁提交

    三、我們的想法
    我們現在的想法是做多階段的持續集成(multi-stage CI)

    可以參考這里http://www.ddj.com/development-tools/212201506

    具體而言:
    1、各個開發小組內做小組內的持續集成
    2、開發小組間集成做整個產品的持續集成


    大概:
    1、每個開發小組一個分支,整個產品一條主線
    2、在小組分支上搭建持續集成環境,小組內的開發向該分支上提交,各個小組可以并發開發,互不影響
    3、小組完成一個完整的功能后,從主線更新合并代碼,本地構建通過,提交,觸發整個產品的持續集成

    為使小組內持續集成構建加快,小組內盡量劃分清楚對其他模塊的依賴,不必要的模塊(這里的模塊包括基礎模塊,例如工作流模塊)不必加載。
    同時推薦輕量級的web服務器例如Tomcat來完成小組內的測試環境。需要啟動weblogic的情況或功能依賴過多的情況下,建議在產品持續集成時進行測試。
    同時保留原有的啟動單獨測試服務器進行手工測試的習慣。
    posted @ 2009-05-26 23:13 ronghao 閱讀(1526) | 評論 (0)編輯 收藏
           和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提供數據庫相關服務。


    posted @ 2009-05-07 18:43 ronghao 閱讀(3696) | 評論 (2)編輯 收藏
    僅列出標題
    共39頁: First 上一頁 10 11 12 13 14 15 16 17 18 下一頁 Last 
    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    關注工作流和企業業務流程改進。現就職于ThoughtWorks。新浪微博:http://weibo.com/ronghao100

    常用鏈接

    留言簿(38)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    常去的網站

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲精品国产成人专区| 中文字幕久久亚洲一区| 亚洲午夜国产精品无卡| 99久久99这里只有免费费精品| 亚洲今日精彩视频| 一级毛片免费毛片一级毛片免费| 亚洲成AV人片在线观看ww| 国产永久免费高清在线| 亚洲AV第一页国产精品| 亚洲精品视频免费在线观看| 亚洲午夜久久久久久尤物| 成人午夜性A级毛片免费| 亚洲AV无码专区在线电影成人| 在线观看国产情趣免费视频| 美女啪啪网站又黄又免费| 亚洲无码精品浪潮| a级毛片毛片免费观看永久| 久久精品亚洲视频| 在线v片免费观看视频| 亚洲av无码专区青青草原| 亚洲综合另类小说色区色噜噜| 免费a级毛片无码a∨免费软件 | 国产91免费在线观看| 亚洲伊人久久精品| 日韩免费高清一级毛片在线| 中美日韩在线网免费毛片视频| 亚洲免费观看视频| 无码区日韩特区永久免费系列 | 日本视频免费观看| 亚洲AV无码一区二区三区系列| AV无码免费永久在线观看| 日韩亚洲翔田千里在线| 亚洲乱码日产一区三区| 青青视频观看免费99| 偷自拍亚洲视频在线观看| 久久精品国产亚洲AV网站| 免费涩涩在线视频网| 久久国产免费一区| 猫咪免费观看人成网站在线| 亚洲国产精品久久久久婷婷软件| 成人免费视频88|