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

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

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

    隨筆-314  評論-209  文章-0  trackbacks-0
    本文介紹怎樣把jBPM組件添加到Web應用程序中。所需要用到的資源,可以在jbpm-starters-kit-3.1.2中找到。
    一、首先安裝jBPM數據庫。jBPM是一個停止狀態的組件,需要數據庫表持久化保存:1)業務程序定義和業務程序實例及相關的工作流數據。保障工作流引擎的執行。2)異步系統使用數據庫表來模擬消息系統的功能。需要把消息到數據庫表中,由消息系統的命令執行器異步查詢和執行。不像專業的消息系統那樣是遠程的。它僅僅使用數據庫模擬消息系統。
    1,打開MySQL的命令執行工具Query Browser。
    2,當前選定應用程序的數據庫,如wcms。
    3,導入腳本文件:mysql.drop.create.sql
    4,執行該腳本。會在當前數據庫中增加jBPM的數據庫表。
     
    二、導入jBPM所需的.jar文件
    1,jbpmlib目錄中包含了jBPM所需的全部jar包。包括MySQL的jdbc包。
    2,把它整個復制到應用程序的lib目錄下。
    3,應用程序的構建器路徑的“庫”中,把這些jar都加進來。
    這些classpath下的jar包,都會被該Web應用程序的類載入器載入。
     
    三、創建config.files和processes目錄,并加入classpath的源代碼路徑
    (一)config.files目錄的功能
        這個目錄存放jBPM的各類配置文件。放在這里(就是classpath頂層)的配置文件會取代jBPM的jar包中各處的配置文件。
    這里,由于需要使用mysql,而不是內置的hsql內存數據庫。所以我們提供了一個修改過的配置文件:hibernate.cfg.xml。這里提供了Hibernate3的配置。
    hibernate.cfg.xml配置文件的部分內容
    <hibernate-configuration>
      <session-factory>
        <!-- jdbc connection properties
    原來的HSQL配置被注釋掉,使用MySQL數據庫的配置
      <property name="hibernate.dialect">org.hibernate.dialect.HSQLDialect</property>
        <property name="hibernate.connection.driver_class">org.hsqldb.jdbcDriver</property>
        <property name="hibernate.connection.url">jdbc:hsqldb:mem:.;sql.enforce_strict_size=true</property>
        <property name="hibernate.connection.username">sa</property>
        <property name="hibernate.connection.password"></property>
              -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/wcms</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">root</property>
    (二)processes目錄的功能
    這個目錄存放process流程定義。如:manageNews\內有3個文件。
    在jBPM應用程序導入.par或.xml文件時,使用相對路徑(如:withubCMS/processdefinition.xml)來定位業務程序定義資源文件。
     
    怎樣把它們放到classpath下,需要根據不同的環境進行不同的處理。
    一、一般Java程序
        1,創建config.files和processes目錄。
    2,配置構建器路徑,將這2個目錄設為到classpath的源代碼路徑。
    這樣,運行時,會把它們中的內容復制到classpath目錄下。
    二、Eclipse下的Web程序
    我們使用Eclipse自帶的功能發布Web程序。
        1,創建config.files和processes目錄。
    2,配置構建器路徑,將這2個目錄設為到classpath的源代碼路徑。
    3,配置classpath,也就是“缺省輸出文件夾”,為:
    內容管理(應用程序根路徑名)/webapps/WEB-INF/classes
    4,這樣,在Eclipse編譯時(默認是保存即編譯),把這2個文件夾中的內容復制到classpath下。
    5,然后,使用Eclipse自帶的功能,發布該Web應用程序。
    Eclipse會把/webapps/文件夾下的所有內容復制到Web服務器下,并且把webapps改名為該Web應用程序的Eclipse項目名字。
    這樣,我們的配置,對于classpath來說也是正確的!Web應用程序可以順利地運行。
    三、Ant發布的Web程序
    可以和上面一樣。把這些classpath的源文件,編譯,然后把內部的內容復制到classpath下。
    Web項目運行時的classpath是classes和lib。當然也需要把jar包都復制到lib下。
     
    最后,在內容管理\webapps\WEB-INF\jbpm\下放置那2個目錄。并把它們設為classpath的源路徑。
    目標classpath路徑是內容管理\webapps\WEB-INF\classes。
     
     
    四、測試jBPM和數據庫
    建立test源文件夾。提供一個junit測試類:org.jbpm.test.db.HelloWorldDbTest
    這個類使用字符串定義了一個簡單的業務程序,然后在數據庫上完整的執行它。
    執行該單元測試。在應用程序的數據庫中的2個表:
    SELECT * FROM jbpm_processdefinition j;
    SELECT * FROM jbpm_processinstance j;
    應該有數據。
     
        至此,jBPM組件就成功地加入到Web應用程序中了!
    附錄:HelloWorldDbTest.java源代碼
    package org.jbpm.test.db;
    import java.util.List;
    import junit.framework.TestCase;
    import org.jbpm.JbpmConfiguration;
    import org.jbpm.JbpmContext;
    import org.jbpm.db.GraphSession;
    import org.jbpm.graph.def.ProcessDefinition;
    import org.jbpm.graph.exe.ProcessInstance;
    import org.jbpm.graph.exe.Token;
    public class HelloWorldDbTest extends TestCase {
     
      static JbpmConfiguration jbpmConfiguration = null;
      static {
        // An example configuration file such as this can be found in
        // 'src/config.files'.  Typically the configuration information is in the
        // resource file 'jbpm.cfg.xml', but here we pass in the configuration
        // information as an XML string.
       
        // First we create a JbpmConfiguration statically.  One JbpmConfiguration
        // can be used for all threads in the system, that is why we can safely
        // make it static.
       /**
        *單例對象。
        *JbpmConfiguration能夠被系統中所有線程所使用。
        *jbpm.cfg.xml這個命名方式和Hibernate配置文件的命名方式一致。
        *
        */
        jbpmConfiguration = JbpmConfiguration.parseXmlString(
          "<jbpm-configuration>" +
         
          // A jbpm-context mechanism separates the jbpm core
          // engine from the services that jbpm uses from
          // the environment.
          /*jbpm-context機制在環境中把jbpm核心引擎和jbpm使用的服務分開。
           * 持久化服務是jbpm核心引擎使用的一個服務。
           *
           * */
         
          "  <jbpm-context>" +
          "    <service name='persistence' " +
          "             factory='org.jbpm.persistence.db.DbPersistenceServiceFactory' />" +
          "  </jbpm-context>" +
         
          // Also all the resource files that are used by jbpm are
          // referenced from the jbpm.cfg.xml
          /*
           *string,配置了所有jbpm使用的資源文件的路徑。
           * */
         
          "  <string name='resource.hibernate.cfg.xml' " +
          "          value='hibernate.cfg.xml' />" +
          "  <string name='resource.business.calendar' " +
          "          value='org/jbpm/calendar/jbpm.business.calendar.properties' />" +
          "  <string name='resource.default.modules' " +
          "          value='org/jbpm/graph/def/jbpm.default.modules.properties' />" +
          "  <string name='resource.converter' " +
          "          value='org/jbpm/db/hibernate/jbpm.converter.properties' />" +
          "  <string name='resource.action.types' " +
          "          value='org/jbpm/graph/action/action.types.xml' />" +
          "  <string name='resource.node.types' " +
          "          value='org/jbpm/graph/node/node.types.xml' />" +
          "  <string name='resource.varmapping' " +
          "          value='org/jbpm/context/exe/jbpm.varmapping.xml' />" +
          "</jbpm-configuration>"
        );
      }
     
      public void setUp() {
       //創建數據庫表
        //jbpmConfiguration.createSchema();
      }
     
      public void tearDown() {
       //刪除數據庫表
        //jbpmConfiguration.dropSchema();
      }
      public void testSimplePersistence() {
        // Between the 3 method calls below, all data is passed via the
        // database.  Here, in this unit test, these 3 methods are executed
        // right after each other because we want to test a complete process
        // scenario情節.  But in reality, these methods represent different
        // requests to a server.
       
        // Since we start with a clean, empty in-memory database, we have to
        // deploy the process first.  In reality, this is done once by the
        // process developer.
       /**
        *  這個方法把業務處理定義通過Hibernate保存到數據庫中。
        */
        deployProcessDefinition();
        // Suppose we want to start a process instance (=process execution)
        // when a user submits a form in a web application...
        /*假設當一個用戶提交一個表單時,我們要開始一個業務處理的實例/執行。
         * 這可以在Action中執行處理。
         */
        processInstanceIsCreatedWhenUserSubmitsWebappForm();
        // Then, later, upon the arrival of an asynchronous message the
        // execution must continue.
        /*
         * 然后,直到異步消息來到,才繼續執行業務處理實例的余下的工作流程。
         * */
        theProcessInstanceContinuesWhenAnAsyncMessageIsReceived();
      }
      public void deployProcessDefinition() {
        // This test shows a process definition and one execution
        // of the process definition.  The process definition has
        // 3 nodes: an unnamed start-state, a state 's' and an
        // end-state named 'end'.
       /*
        * 這個方法把業務處理定義通過Hibernate保存到數據庫中。
        *
        * */
        ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(
          "<process-definition name='hello world'>" +
          "  <start-state name='start'>" +
          "    <transition to='s' />" +
          "  </start-state>" +
          "  <state name='s'>" +
          "    <transition to='end' />" +
          "  </state>" +
          "  <end-state name='end' />" +
          "</process-definition>"
        );
        // Lookup the pojo persistence context-builder that is configured above
        JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
        try {
          // Deploy the process definition in the database
          jbpmContext.deployProcessDefinition(processDefinition);
        } finally {
          // Tear down the pojo persistence context.
          // This includes flush the SQL for inserting the process definition 
          // to the database.
         /*
          * 關閉jbpm上下文。刪除pojo持久化上下文。
          * 這包括刷新SQL來真正的把業務處理定義插入到數據庫中。
          * */
          jbpmContext.close();
        }
      }
      public void processInstanceIsCreatedWhenUserSubmitsWebappForm() {
        // The code in this method could be inside a struts-action
        // or a JSF managed bean.
        // Lookup the pojo persistence context-builder that is configured above
        JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
        try {
    /*
     * 圖表會話,是圖表定義/業務處理定義 相關的數據庫層面的會話。應該也是一個Hibernate會話。
     * 可以從JBpm上下文這個數據庫----業務處理定義、實例等 得到 業務處理定義會話。
     *
     * */
          GraphSession graphSession = jbpmContext.getGraphSession();
          //從數據庫中根據業務處理定義的名字得到一個業務處理定義。
          ProcessDefinition processDefinition =
              graphSession.findLatestProcessDefinition("hello world");
       
          // With the processDefinition that we retrieved from the database, we
          // can create an execution of the process definition just like in the
          // hello world example (which was without persistence).
          /*
           * 創建業務處理定義的一個實例。
           *
           * */
          ProcessInstance processInstance =
              new ProcessInstance(processDefinition);
         
          Token token = processInstance.getRootToken();
          assertEquals("start", token.getNode().getName());
          // Let's start the process execution
          token.signal();
          // Now the process is in the state 's'.
          assertEquals("s", token.getNode().getName());
         
          // Now the processInstance is saved in the database.  So the
          // current state of the execution of the process is stored in the
          // database.
          /*
           * 執行一步工作流程后,使用jbpmContext保存這個業務處理實例進數據庫。
           *    所以現在就把業務處理實例的執行狀態也保存進了數據庫。
           *  因為,業務處理定義的實例  這個類也是一個Model類,用于管理一個業務處理定義的執行的所有信息,
           *  是一個多例模式的Model。
           *
           * */
          jbpmContext.save(processInstance);
          // The method below will get the process instance back out
          // of the database and resume execution by providing another
          // external signal.
        } finally {
          // Tear down the pojo persistence context.
          jbpmContext.close();
        }
      }
      public void theProcessInstanceContinuesWhenAnAsyncMessageIsReceived() {
        // The code in this method could be the content of a message driven bean.
        //這個方法可能在消息驅動Bean這個遠程業務代理類中。
        // Lookup the pojo persistence context-builder that is configured above
        JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
        try {
          GraphSession graphSession = jbpmContext.getGraphSession();
          // First, we need to get the process instance back out of the database.
          // There are several options to know what process instance we are dealing
          // with here.  The easiest in this simple test case is just to look for
          // the full list of process instances.  That should give us only one
          // result.  So let's look up the process definition.
         
          ProcessDefinition processDefinition =
              graphSession.findLatestProcessDefinition("hello world");
          // Now, we search for all process instances of this process definition.
          /*
           * 根據業務處理定義的id得到數據庫中所有的業務處理實例。這表明,數據庫中應該存在2張表
           * 它們是  一對多  的關系。
           *
           * */
          List processInstances =
              graphSession.findProcessInstances(processDefinition.getId());
         
          // Because we know that in the context of this unit test, there is
          // only one execution.  In real life, the processInstanceId can be
          // extracted from the content of the message that arrived or from
          // the user making a choice.
          ProcessInstance processInstance =
              (ProcessInstance) processInstances.get(0);
         
          // Now we can continue the execution.  Note that the processInstance
          // delegates signals to the main path of execution (=the root token).
          processInstance.signal();
          // After this signal, we know the process execution should have
          // arrived in the end-state.
          assertTrue(processInstance.hasEnded());
         
          // Now we can update the state of the execution in the database
          jbpmContext.save(processInstance);
        } finally {
          // Tear down the pojo persistence context.
          jbpmContext.close();
        }
      }
    }
     

    Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1346877

    posted on 2006-10-24 14:18 xzc 閱讀(1008) 評論(0)  編輯  收藏 所屬分類: BPM

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 成年女人免费视频播放77777| 国产亚洲人成无码网在线观看| 亚洲最新视频在线观看| 色天使亚洲综合一区二区| 2019中文字幕免费电影在线播放| 久久国产成人精品国产成人亚洲 | 亚洲精品一卡2卡3卡四卡乱码| 久久99热精品免费观看动漫 | 亚洲国语在线视频手机在线| 中文字幕免费在线视频| 国产成人免费网站在线观看| 亚洲国产成人精品无码一区二区| a级男女仿爱免费视频| 一区二区三区亚洲视频| 亚洲砖码砖专无区2023| 亚洲免费福利视频| 亚洲av无码专区在线播放| 成人特级毛片69免费观看| 暖暖在线日本免费中文| 亚洲午夜在线一区| 日本免费大黄在线观看| 亚洲中文字幕无码爆乳AV| 免费国产在线精品一区| 日韩免费毛片视频| 亚洲AV男人的天堂在线观看| 182tv免费观看在线视频| 亚洲AV无码久久精品成人| 久久WWW免费人成—看片| 免费在线观看理论片| 亚洲AV永久无码精品一福利| 成年女人男人免费视频播放| 亚洲AV综合色区无码二区偷拍 | 亚洲手机中文字幕| 99re这里有免费视频精品| 亚洲精品国产美女久久久| 精品久久久久久国产免费了 | 亚洲伊人久久大香线蕉结合| 日本zzzzwww大片免费| 亚洲精品白色在线发布| 最近2019中文字幕免费大全5 | 亚洲精品午夜国产VA久久成人|