posts - 193,  comments - 520,  trackbacks - 0
            整體來說實現的非常清晰:
            1、引擎解析流程定義xml時,給相應的事件掛接上create-timer 和 cancel-timer動作
            2、流程實例實際運轉時,create-timer動作在相應事件觸發時執行
            3、create-timer在job表里插入相應時間job記錄,給該job記錄附上計算完畢的執行時間
            4、JobExecutorServlet在后臺啟動一到多個JobExecutorThread線程
            5、JobExecutorThread線程不停的每隔一段時間對job表掃描一次,找出需要執行的job記錄,執行之
            6、只執行一次的job記錄,執行完畢后刪除之;重復執行的job記錄,寫入新的執行時間,更新之
            7、相應事件觸發cancel-timer動作,將對應job記錄從job表里刪除
            下面具體用代碼來說話(掛接到node節點):
            1、引擎解析流程定義xml 
            JpdlXmlReader.java 
            
          protected void readNodeTimer(Element timerElement, Node node) {
              String name 
          = timerElement.attributeValue("name", node.getName());
             
              CreateTimerAction createTimerAction 
          = new CreateTimerAction();
              createTimerAction.read(timerElement, 
          this);
              createTimerAction.setTimerName(name);
              createTimerAction.setTimerAction(readSingleAction(timerElement));
              addAction(node, Event.EVENTTYPE_NODE_ENTER, createTimerAction);
             
              CancelTimerAction cancelTimerAction 
          = new CancelTimerAction();
              cancelTimerAction.setTimerName(name);
              addAction(node, Event.EVENTTYPE_NODE_LEAVE, cancelTimerAction);
            }

            可以看到,引擎把xml中timer節點解析成了兩個ACTION:CreateTimerAction和CancelTimerAction
            CreateTimerAction會在進入該節點時觸發,而CancelTimerAction會在令牌離開該節點時觸發。
            2、看看CreateTimerAction和CancelTimerAction究竟在做些什么
            CreateTimerAction.java
             
          public void execute(ExecutionContext executionContext) throws Exception {
              Timer timer 
          = createTimer(executionContext);
              SchedulerService schedulerService 
          = (SchedulerService) Services.getCurrentService(Services.SERVICENAME_SCHEDULER);
              schedulerService.createTimer(timer);
            }

            很明顯,是通過一個職責集中的schedulerService向job表中插入了一條job記錄,注意到這個方法:
            protected Timer createTimer(ExecutionContext executionContext) {
              Timer timer 
          = new Timer(executionContext.getToken());
              .
              
          if (dueDate!=null) {
                Duration duration 
          = new Duration(dueDate);
                Date dueDateDate 
          = businessCalendar.add( new Date(), duration );
                timer.setDueDate(dueDateDate);
              }
              .
             
              
          return timer;
            }

            這里利用JBPM提供的工作時間計算組件計算了job的執行時間。
            CancelTimerAction就很簡單了,刪除相應的job記錄。
            CancelTimerAction.java
            
          public void execute(ExecutionContext executionContext) throws Exception {
              SchedulerService schedulerService 
          = (SchedulerService) Services.getCurrentService(Services.SERVICENAME_SCHEDULER);
              schedulerService.deleteTimersByName(timerName, executionContext.getToken());
            }

            3、JobExecutorServlet是干什么的
            啟動線程
            public void init() throws ServletException {
              .
              jbpmConfiguration.startJobExecutor();
            }

            4、線程是如何工作
            public void run() {
              
          try {
                currentIdleInterval 
          = idleInterval;
                
          while (isActive) {
                  
          try {
                    Collection acquiredJobs 
          = acquireJobs();   //從job表里獲得將要執行的job記錄

                    
          if (! acquiredJobs.isEmpty()) {    //如果記錄不為空,則開始執行
                      Iterator iter = acquiredJobs.iterator();
                      
          while (iter.hasNext() && isActive) {
                        Job job 
          = (Job) iter.next();
                        executeJob(job);             
          //執行
                      }

                    } 
          else { // no jobs acquired     //如果沒有可執行的job,則等待一段時間
                      if (isActive) {
                        
          long waitPeriod = getWaitPeriod();  //等待的時間是找出即將執行的job離現在最近的時間間隔
                        if (waitPeriod>0) {
                          
          synchronized(jobExecutor) {
                            jobExecutor.wait(waitPeriod);
                          }
                        }
                      }
                    }
                   
                   .
              } 
          catch (Throwable t) {
                t.printStackTrace();
              } 
          finally {
                log.info(getName()
          +" leaves cyberspace");
              }
            }

            看看實際執行的方法
            protected void executeJob(Job job) {
              JbpmContext jbpmContext 
          = jbpmConfiguration.createJbpmContext();
              
          try {
                JobSession jobSession 
          = jbpmContext.getJobSession();
                job 
          = jobSession.loadJob(job.getId());

                
          try {
                  log.debug(
          "executing job "+job);
                  
          if (job.execute(jbpmContext)) {    //交由Job對象本身去完成執行的邏輯,并決定是否刪除job記錄
                    jobSession.deleteJob(job);
                  }
                      .
            }

            5、著重關注Time對象
            在上面我們看到實際執行的代碼是job.execute(jbpmContext);
            Time 是Job的子類,看看它的實現:
            public boolean execute(JbpmContext jbpmContext) throws Exception {
              
          boolean deleteThisJob = true;       //執行完畢后是否刪除job記錄

              ExecutionContext executionContext 
          = new ExecutionContext(token);
              executionContext.setTimer(
          this);

              
          if (taskInstance!=null) {
                executionContext.setTaskInstance(taskInstance);
              }

              
          // 觸發timer事件
              if (graphElement!=null) {
                graphElement.fireAndPropagateEvent(Event.EVENTTYPE_TIMER, executionContext);
              }

              
          // 如果timer節點上掛有action則執行之
              if (action!=null) {
                
          try {
                  log.debug(
          "executing timer '"+this+"'");
                  action.execute(executionContext);
                } 
          catch (Exception actionException) {
                .
                  }

              
          // 如果定義了transition屬性,則流程順著定義的路徑流轉
              if ( (transitionName!=null)
                   
          && (exception==null// and if no unhandled exception occurred during the action 
                 ) {
                
          if (token.getNode().hasLeavingTransition(transitionName)) {
                  token.signal(transitionName);
                }
              }
             
              
          // 如果定義了repeat屬性則job記錄不容許刪除,同時計算新的執行時間
              if (repeat!=null) {
                deleteThisJob 
          = false;

                
          while (dueDate.getTime()<=System.currentTimeMillis()) {
                  dueDate 
          = businessCalendar
                        .add(dueDate,
                          
          new Duration(repeat));
                }
                log.debug(
          "updated timer for repetition '"+this+"' in '"+(dueDate.getTime()-System.currentTimeMillis())+"' millis");
              }
             
              
          return deleteThisJob;
            }




          http://www.aygfsteel.com/ronghao 榮浩原創,轉載請注明出處:)
          posted on 2007-06-22 17:13 ronghao 閱讀(1950) 評論(0)  編輯  收藏 所屬分類: 工作流jbpm3
          <2007年6月>
          272829303112
          3456789
          10111213141516
          17181920212223
          24252627282930
          1234567

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

          常用鏈接

          留言簿(38)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          常去的網站

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 崇信县| 乌鲁木齐市| 鹤峰县| 万全县| 临城县| 清水县| 洛阳市| 措勤县| 安庆市| 沈丘县| 闸北区| 松溪县| 天祝| 屏东市| 青神县| 昭通市| 肥西县| 新密市| 海口市| 博爱县| 茂名市| 雷波县| 梧州市| 松潘县| 恩平市| 明光市| 垣曲县| 班戈县| 自治县| 绿春县| 健康| 区。| 武陟县| 涞水县| 于都县| 宾川县| 友谊县| 西安市| 和田市| 海兴县| 长治市|