activiti源碼分析(一)設計模式,activiti源碼

來源:互聯網
上載者:User

activiti源碼分析(一)設計模式,activiti源碼

  對activiti有基本瞭解的朋友都知道,activiti暴露了七個介面來提供工作流程的相關服務,這些介面具體是如何?的呢?查看源碼發現其實現的形式大體如下: 

public class RuntimeServiceImpl extends ServiceImpl implements RuntimeService {    public ProcessInstance startProcessInstanceByKey(String processDefinitionKey) {    return commandExecutor.execute(new StartProcessInstanceCmd<ProcessInstance>(processDefinitionKey, null, null, null));  }  public ProcessInstance startProcessInstanceByKey(String processDefinitionKey, String businessKey) {    return commandExecutor.execute(new StartProcessInstanceCmd<ProcessInstance>(processDefinitionKey, null, businessKey, null));  }  ...}

  service中的大部分方法都是通過調用commandExecutor.execute()完成的,然而點進去看則會發現什麼都沒有:

public class CommandExecutorImpl implements CommandExecutor {  private final CommandConfig defaultConfig;  private final CommandInterceptor first;    public CommandExecutorImpl(CommandConfig defaultConfig, CommandInterceptor first) {    this.defaultConfig = defaultConfig;    this.first = first;  }    public CommandInterceptor getFirst() {    return first;  }  @Override  public CommandConfig getDefaultConfig() {    return defaultConfig;  }    @Override  public <T> T execute(Command<T> command) {    return execute(defaultConfig, command);  }  @Override  public <T> T execute(CommandConfig config, Command<T> command) {    return first.execute(config, command);  }}

  看到這裡就會發現並不能看出這條語句究竟做了什麼,那麼究竟是如何提供服務的呢?其實activiti中大部分操作都是基於設計模式中的命令模式完成的(這裡還使用了職責鏈模式,構造了命令攔截器鏈,用於在命令真正被執行之前做一系列操作)。下面結合源碼詳細介紹一下這些設計思路:

  activiti的命令模式可能與我之前看的命令模式有所不同,命令模式的本質在於將命令進行封裝,發出命令和執行命令分離。職責鏈模式只需要將請求放入職責鏈上,其處理細節和傳遞都不需要考慮。activiti將這兩個模式整合在一起,構成了其服務主要的實現方式。其核心只有三個部分:CommandExecutor(命令執行器,用於執行命令),CommandInterceptor(命令攔截器,用於構建攔截器鏈),Command(命令自身)。這三個介面是整個核心的部分,還會涉及到其它的關鍵類,之後會一一說明,這三個類都在activiti-engine.jar這個activiti實現的核心包下,具體位置是:org.activiti.engine.impl.interceptor。下面由這三個介面逐步介紹相關的類和具體實現:

  三個介面源碼:

public interface Command <T> {  T execute(CommandContext commandContext);  }

  

/** * The command executor for internal usage. */public interface CommandExecutor {    /**   * @return the default {@link CommandConfig}, used if none is provided.   */  CommandConfig getDefaultConfig();  /**   * Execute a command with the specified {@link CommandConfig}.   */  <T> T execute(CommandConfig config, Command<T> command);  /**   * Execute a command with the default {@link CommandConfig}.   */  <T> T execute(Command<T> command);  }

  

public interface CommandInterceptor {  <T> T execute(CommandConfig config, Command<T> command);   CommandInterceptor getNext();  void setNext(CommandInterceptor next);}

  Command的介面中只有一個execute方法,這裡才是寫命令的具體實現,而CommandExecutor的實作類別在上面已經給出,其包含了一個CommandConfig和一個命令攔截器CommandInterceptor,而執行的execute(command)方法,實際上調用的就是commandInterceptor.execute(commandConfig,command)。而CommandInterceptor中包含了一個set和get方法,用於設定next(實際上就是下一個CommandInterceptor)變數。想象一下,這樣就能夠通過這種形式找到攔截器鏈的下一個攔截器鏈,就可以將命令傳遞下去。

  簡單梳理一下:Service實現服務的其中一個標準方法是在具體服務中調用commandExecutor.execute(new command())(這裡的command是具體的命令)。其執行步驟就是命令執行器commandExecutor.execute調用了其內部變數CommandInterceptor first(第一個命令攔截器)的execute方法(加上了參數commandConfig)。CommandInterceptor中包含了一個CommandInterceptor對象next,用於指向下一個CommandInterceptor,在攔截器的execute方法中,只需要完成其對應的相關操作,然後執行一下next.execute(commandConfig,command),就可以很簡單的講命令傳遞給下一個命令攔截器,然後在最後一個攔截器中執行command.execute(),調用這個命令最終要實現的內容就行了。

  未完很困,待續。

  

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.