activiti源碼分析學習導語
目前項目中用activiti來做工作流的相關工作,最近遇到一些情況下,公司二次開發的流程圖渲染出現了問題,會造成流程圖出不來的情況。初步分析數據庫中記錄以及簡單的代碼跟蹤,發現繪制流程路線圖時,是按to_number(id_)來進行排序,預期是先發生的行為它的id_字段一定小。
select * from act_hi_actinst order by to_number(id_);
但是跟蹤時候,發現明明后發生的行為,但是id_字段值卻還更小:
於是覺得是IdGenerator那邊生成記錄主鍵的時候出問題了,但是還不確定,於是決定去看看源碼。沒想到,一看源碼才知道,人家根本就不是實施入庫,而是對每個command,進行session緩存,之后flush()一起入庫。由此,有了更進一步探知它的內部實現的欲望。
源碼分析
首先推薦網上文章:activiti-engine源碼分析。
作者的水平很好,在講解內容的時候加入了對於面向對象編程、對於設計模式、對於團隊工作等的理解,內容解說圖文結合,感覺比較到位。
后續的內容只是一些細節的補充。
CommandIntercepter命令攔截器鏈
命令攔截器,它實際上扮演的是“命令模式”中的Invoker-即請求者角色。
對使用StandaloneProcessEngineConfiguration配置實現的情況,默認生成以下的攔截器鏈:
LogInterceptor >> CommandContextInterceptor >> CommandInvoker
其中:
- LogInterceptor就是簡單的記錄日志;
- CommandContextInterceptor事前添加命令上下文,事后控制關閉session;
- CommandInvoker負責執行具體命令;
對使用JtaProcessEngineConfiguration配置實現的情況,默認會添加事物攔截器:
LogInterceptor >> CommandContextInterceptor >> JtaTransactionInterceptor >> CommandInvoker
其中,JtaTransactionInterceptor用於實現JTA事物,依賴於JTA的具體實現。
持久層mybatis的statement規則
1.持久層的實體必須以Entity結尾,它的命名在后續會有使用到;
2.mybatis中對statement命名遵循以下命名約束(假定對Property對象):
- insertModelName 插入一條記錄
- updateModelName 更新一條記錄
- selectModelName 選擇一條記錄
- selectModelNameCountsByCriteria 對單表進行過濾查詢,返回記錄數
- selectModelNamesByCriteria對單邊進行過濾查詢,返回詳細記錄
在持久層構造SQL過程中,用到一些內容的說明:
- ModelNameEntity 模型對象;
- ModelNameEntityManager 封裝對模型的數據庫操作;
- ModelNameQueryImpl不一定存在,如果存在,則是對查詢的條件過濾;它的設計上類似JQuery的連續命名模式,目前crateria基本上都是這種實現。
- DbSqlSessionFactory用於獲取DbSqlSession,維護所有statement並提供獲取statement的實現;
- DbSqlSession執行具體的操作。