flowable-責任鏈模式及其在flowable源碼中的應用

flowable中的責任鏈模式

 

如下,以RuntimeServiceImpl爲例, 在flowable源碼中很多這樣的調用,這就是典型的責任鏈模式的應用。

此處關鍵在於實現了ServiceImpl這個類,如下所示,flowable的幾大主要類都實現了該接口。

相關的類結構圖如下:

ServiceImpl類有CommandExecutor類型的成員變量,而CommandExecutor的實現類又有CommandInterceptor類型的成員變量,實現CommandInterceptor的抽象類中的成員變量next也是一個CommandInterceptor類,通過next既可以實現責任鏈模式,AbstractCommandInterceptor的如下實現類將作爲責任鏈中的節點。
那麼責任鏈的前後關係又是怎樣的呢,這裏我們就要查看ProcessEngineConfigurationImpl的源碼了,這個類的initInterceptorChain方法即爲責任鏈的初始處理邏輯,如下:
 
public CommandInterceptor initInterceptorChain(List<CommandInterceptor> chain) {
        if (chain == null || chain.isEmpty()) {
            throw new FlowableException("invalid command interceptor chain configuration: " + chain);
        }
        for (int i = 0; i < chain.size() - 1; i++) {
            chain.get(i).setNext(chain.get(i + 1));
        }
        return chain.get(0);
    }

可以看到責任鏈的前後關係是按照列表中的順序的,所以關鍵點在於傳參,找到調用這個方法的地方:

public void initCommandExecutor() {
        if (commandExecutor == null) {
            CommandInterceptor first = initInterceptorChain(commandInterceptors);
            commandExecutor = new CommandExecutorImpl(getDefaultCommandConfig(), first);
        }
    }

參數commandInterceptors是ProcessEngineConfigurationImpl類的一個成員變量,所以接下來要看看哪裏初始化這個成員變量,如下:

public void initCommandInterceptors() {
        if (commandInterceptors == null) {
            commandInterceptors = new ArrayList<CommandInterceptor>();
            if (customPreCommandInterceptors != null) {
                commandInterceptors.addAll(customPreCommandInterceptors);
            }
            commandInterceptors.addAll(getDefaultCommandInterceptors());
            if (customPostCommandInterceptors != null) {
                commandInterceptors.addAll(customPostCommandInterceptors);
            }
            commandInterceptors.add(commandInvoker);
        }
    }

    public Collection<? extends CommandInterceptor> getDefaultCommandInterceptors() {
        List<CommandInterceptor> interceptors = new ArrayList<CommandInterceptor>();
        interceptors.add(new LogInterceptor());

        CommandInterceptor transactionInterceptor = createTransactionInterceptor();
        if (transactionInterceptor != null) {
            interceptors.add(transactionInterceptor);
        }

        if (commandContextFactory != null) {
            interceptors.add(new CommandContextInterceptor(commandContextFactory, this));
        }

        if (transactionContextFactory != null) {
            interceptors.add(new TransactionContextInterceptor(transactionContextFactory));
        }

        return interceptors;
    }
先添加自定義前置節點,再添加默認節點(先是LogInterceptor, 然後createTransactionInterceptor(),接着CommandContextInterceptor,還有一個成員變量transactionContextFactory),再添加自定義後置節點,最後還加加上CommandInvoker。所以我們如果沒有特殊配置的話這條鏈依次會有LogInterceptor, TransactionContextInterceptor(和使用環境有關,在Spring下爲SpringTransactionInterceptor), CommandContextInterceptor,TransactionContextInterceptor, CommandInvoker這五個節點。通過調試源碼可以驗證我們的分析,如下:

接着runtimeService也會進行相關初始化,其中責任鏈結構如下:

查看前四個節點,如下以LogInterceptor爲例,肯定會有next.execute(config, command);, 這也是保證責任鏈能夠往下走的決定因素。

接下來再看看最後一個節點CommandInvoker的源碼,關鍵是執行了command的execute方法,沒有next.execute了。

同時可以發現getNext()返回爲null, 即獲取不到下一個節點,並且在嘗試設置下一個節點時會拋出異常,這也正是責任鏈鏈尾節點應有的特徵。

由此也可以看出所有業務邏輯的處理最終會通過comand.execute來完成,所以接下來就是要搞清楚Command的處理邏輯,具體請待下一篇分析。

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章