JBPM与设计模式之职责链模式

JBPM与设计模式之职责链模式
    上篇我们了解并学习了JBPM的长事务实现,其中用到了设计模式中的职责链模式和命令模式;这块还是很有厚重感的,我们可以从中学到很多的东西;今天我们先来学习一下职责链模式。

       职责链模式定义
       使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系;将这些对象连成一条链,并沿这条链传递该请求,直到有一个对象处理该请求。

       职责链模式的优点
       1.客户提交一个请求,其沿着这条链传递直到得到处理;
       2. 发送者和接受者都没有对方的明确信息信息;
       3. 链中对象也不知道链的结构,简化了链中对象的链接关系,它仅需要维持其后继者的引
用,而不用持有它所有的候选者;
    职责链模式UML图

   

        

      JBPM职责链模式UML图

       下面结合JBPM的拦截器代码简单介绍一下这个模式

     Client:

客户端定制拦截器装配策略通过jbpm.tx.*.cfg.xml(本文结合hibernate讲解)中定义

       解析配置策略形成职责链是在流程引擎初始化时完成,JBPM中定义了两种拦截器装配策略

       同一个线程的命令嵌套调用的命令共用环境资源

    

View Code

1 <command-service name="txRequiredCommandService">
2       <skip-interceptor />
3       <retry-interceptor />
4       <environment-interceptor />
5       <standard-transaction-interceptor />
6 </command-service>
7 每个命令调用都新建环境资源
8 <command-service name="newTxRequiredCommandService">
9       <retry-interceptor />
10       <environment-interceptor policy="requiresNew" />
11       <standard-transaction-interceptor />
12 </command-service>
   客户端的请求就是完成一定业务功能的脚本命令

  

View Code

1 public interface Command<T> extends Serializable {
2  
3   T execute(Environment environment) throws Exception;
4 }
5
6 public class SaveTaskCmd extends AbstractCommand<String> {
7
8   private static final long serialVersionUID = 1L;
9  
10   protected TaskImpl task;
11
12   public SaveTaskCmd(TaskImpl task) {
13     this.task = task;
14   }
15
16   public String execute(Environment environment) throws Exception {
17     DbSession dbSession = environment.get(DbSession.class);
18
19     if (task.isNew()) {
20       if (task.getSuperTaskDbid()!=null) {
21         TaskImpl parentTask = dbSession.get(TaskImpl.class, task.getSuperTaskDbid());
22         parentTask.addSubTask(task);
23         task.setSuperTaskDbid(null);
24       }
25      
26       dbSession.save(task);
27      
28       HistoryEvent.fire(new TaskCreated(task));
29
30     } else {
31       dbSession.update(task);
32
33       HistoryEvent.fire(new TaskUpdated(task));
34     }
35
36     return task.getId();
37   }
38 }
  
   客户端调用
   taskService. assignTask(task.getId(),userId); 

  ChainHandle:
JBPM并没用完全照搬职责链的定义, 虽然在每个拦截器中都可以处理请求,但是JBPM设计的只能在DefaultCommandService里处理请求,然后再拦截器中处理环境资源初始化和长事务的管理等。
根据以上分析,职责链ChainHandler实现如下
   执行处理请求



View Code

1 public interface CommandService {
2  
3   String NAME_TX_REQUIRED_COMMAND_SERVICE = "txRequiredCommandService";
4   String NAME_NEW_TX_REQUIRED_COMMAND_SERVICE = "newTxRequiredCommandService";
5
6   /**
7    * @throws JbpmException if command throws an exception.
8    */
9   <T> T execute(Command<T> command);
10 }
11
12 public class DefaultCommandService implements CommandService {
13
14   private static final Log log = Log.getLog(DefaultCommandService.class.getName());
15
16   public <T> T execute(Command<T> command) {
17     EnvironmentImpl environment = EnvironmentImpl.getCurrent();
18    
19     try {
20       return command.execute(environment);
21      
22     } catch (RuntimeException e) {
23       log.info("exception while executing command "+command, e);
24       throw e;
25      
26     } catch (Exception e) {
27       log.info("exception while executing command "+command, e);
28       throw new JbpmException("exception while executing command "+command, e);
29     }
30   }
31 }
    职责链流传控制
   

View Code

1 public abstract class Interceptor implements CommandService {
2
3   protected CommandService next;
4
5   public CommandService getNext() {
6     return next;
7   }
8   public void setNext(CommandService next) {
9     this.next = next;
10   }
11 }
12
13 public class SkipInterceptor extends Interceptor {
14  
15   static DefaultCommandService defaultCommandService = new DefaultCommandService();
16
17   public <T> T execute(Command<T> command) {
18     EnvironmentImpl environment = EnvironmentImpl.getCurrent();
19     // if there is an environment active
20     if (environment!=null) {
21       // skip the rest of the interceptor stack and just execute the command
22       return defaultCommandService.execute(command);
23     }
24
25     return next.execute(command);
26   }
27
28 }
     JBPM职责链执行流程




猜你喜欢

转载自sunsteven.iteye.com/blog/1688951
今日推荐