最近在調查activiti工做流的事。項目上打算作一個工做流服務,給微服務中的一些須要流程定義的服務用。因此我嘗試用spring boot集成activiti。如下是我調查中遇到的一些問題和一些調查到的結果。php
activity cloud 不知道怎麼使用,可是看官方解釋比較適合雲服務(spring cloud)便於擴展,可是activity cloud 貌似是雲平臺。由於不會搭建,因此就放棄了。activity7 與 activity6 相比,7 多了processruntime與taskruntime 兩個類。這兩個類須要與security 一塊兒使用,官方里對於TaskRuntime API 有這樣一段話:mysql
Something important to notice here, is that in order to interact with the TaskRuntime API as a user, you need to have the role: ACTIVITI_USER (Granted Authority: ROLE_ACTIVITI_USER) .
由於我項目還沒和spring security 集成起來,因此就只好不用這兩個類了。個人作法是用activity7 的core,可是仍是用 6.0使用方式。git
繼承方式很簡單,在pom裏引入就OK了spring
<activiti-dependencies.version>7.0.0.SR1</activiti-dependencies.version> ... ... <!--activiti starter--> <dependency> <groupId>org.activiti</groupId> <artifactId>activiti-spring-boot-starter</artifactId> </dependency> <!-- Activiti生成流程圖 --> <dependency> <groupId>org.activiti</groupId> <artifactId>activiti-image-generator</artifactId> </dependency>
首先是基本25張表sql
ACT_GE_* : 「GE」表明「General」(通用)
ACT_HI_* : 「HI」表明「History」(歷史) 這些表中保存的都是歷史數據,好比執行過的流程實例、變量、任務,等等
ACT_ID_* : 「ID」表明「Identity」(身份)這些表中保存的都是身份信息,如用戶和組以及二者之間的關係。若是Activiti被集成在某一系統當中的話,這些表能夠不用,能夠直接使用現有系統中的用戶或組信息
ACT_RE_* : 「RE」表明「Repository」(倉庫) 這些表中保存一些‘靜態’信息,如流程定義和流程資源(如圖片、規則等)
ACT_RU_* : 「RU」表明「Runtime」(運行時)這些表中保存一些流程實例、用戶任務、變量等的運行時數據。Activiti只保存流程實例在執行過程當中的運行時數據,而且當流程結束後會當即移除這些數據,這是爲了保證運行時表儘可能的小並運行的足夠快;
其中 history-level: full 這個參數關係着是否會生成ACT_HI_*的系列表。ACT_ID_* 這個系列的表在7裏已經沒有了。數據庫
none:不保存任何的歷史數據,所以,在流程執行過程當中,這是最高效的。
activity:級別高於none,保存流程實例與流程行爲,其餘數據不保存。
audit:除activity級別會保存的數據外,還會保存所有的流程任務及其屬性。audit爲history的默認值。
full:保存歷史數據的最高級別,除了會保存audit級別的數據外,還會保存其餘所有流程相關的細節數據,包括一些流程參數等。
參照: activiti學習筆記(十八) History
其次,若是使用的是mysql數據庫,在通一個mysql服務器上不能有兩個用於activiti的基礎數據庫。例如,數據庫A已經有一套表結構了,若是打算將schema 切換到b想再生成一套新的表結構,這樣是會生成失敗的。下面鏈接裏樓主說的就是這種狀況,我debug代碼追蹤的結果也和樓主講的同樣,只要刪除掉其中一個,就能正常運行了。參照:一個MySql實例自動建立多個Activiti數據庫問題服務器
若是是想在yml下配置,用這樣的方式就能正常生成表 並啓動。restful
spring: activiti: db-history-used: true database-schema: activity #指定數據庫schema history-level: full async-executor-activate: true #開啓異步,定時任務 database-schema-update: true
關於 database-schema-update:
flase: 默認值。activiti在啓動時,會對比數據庫表中保存的版本,若是沒有表或者版本不匹配,將拋出異常。
true: activiti會對數據庫中全部表進行更新操做。若是表不存在,則自動建立。
create_drop: 在activiti啓動時建立表,在關閉時刪除表(必須手動關閉引擎,才能刪除表)。
drop-create: 在activiti啓動時刪除原來的舊錶,而後在建立新表(不須要手動關閉引擎)。
若是是想用bean本身配置,參考ProcessEngineAutoConfiguration 中的配置方法。 我第一次用bean配置的時候,出現了表沒法生成的狀況。一開始沒有使用SpringProcessEngineConfiguration,而且調用configuration.buildProcessEngine() 生成ProcessEngine,不知道爲何就是沒法將HistoryLevel的值設進去,後來修改了寫法後就成功了。app
@Bean public SpringProcessEngineConfiguration processEngineConfiguration(DataSource dataSource, PlatformTransactionManager manager){ SpringProcessEngineConfiguration configuration = new SpringProcessEngineConfiguration(); configuration.setDataSource(dataSource); configuration.setTransactionManager(manager); configuration.setAsyncExecutorActivate(true); configuration.setHistoryLevel(HistoryLevel.FULL); configuration.setDatabaseSchema("activity"); configuration.setDbHistoryUsed(true); configuration.setDatabaseSchemaUpdate(DB_SCHEMA_UPDATE_TRUE); configuration.setEnableDatabaseEventLogging(true); //是否開啓dblog //讀取流程配置文件 Resource[] resources = null; try { resources = resourcePatternResolver.getResources(ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX+"/processes/*.xml"); } catch (IOException e) { e.printStackTrace(); } if (resources != null && resources.length != 0) { configuration.setDeploymentResources(resources); configuration.setDeploymentName("ActivitiService"); } return configuration; }
實際上在7裏, IdentifyService, FormService 已經沒有了。基本上剩下的service對應的就是數據庫裏每一個類別的表的操做。異步
使用serviceTask,經過實現JavaDelegate 來實現調用外部restful接口
<serviceTask id="vacation_service" name="假期處理" activiti:delegateExpression="${jumpService}"> <extensionElements> <activiti:field name="restUrl"> <activiti:string><![CDATA[http://stores/decreaseDay]]></activiti:string> </activiti:field> <activiti:field name="param"> <activiti:string><![CDATA[day,businessKey,action]]></activiti:string> </activiti:field> </extensionElements> </serviceTask>
@Service public class JumpService implements JavaDelegate { private final static Logger logger = LoggerFactory.getLogger(JobServiceImpl.class); //restTemplate 配置了ribbon @Autowired RestTemplate restTemplate; //調用地址 private Expression restUrl; // 參數 private Expression param; public void setRestUrl(Expression restUrl) { this.restUrl = restUrl; } public void setParam(Expression param) { this.param = param; } @Override public void execute(DelegateExecution delegateExecution) { //取得從xml中傳過來的參數列表 String params = (String) param.getValue(delegateExecution); //取得從xml中傳過來的地址 String strUrl = (String) restUrl.getValue(delegateExecution); //TODO:經過調用restTemplate來調用其餘微服務接口,或者暴露的restful接口 } }
若是要使用groovy 腳本,須要引入jar包到pom中
<dependency> <groupId>org.codehaus.groovy</groupId> <artifactId>groovy-all</artifactId> <version>2.5.7</version> <type>pom</type> </dependency>
編寫一個獲取spring bean的工具類
@Component public class SpringContextUtil implements ApplicationContextAware { private static ApplicationContext applicationContext; public static Object getBean(String name){ return applicationContext.getBean(name); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { SpringContextUtil.applicationContext = applicationContext; } public static ApplicationContext getApplicationContext() { return applicationContext; } }
而後就能夠在腳本中引入工具類後,在腳本中使用這些bean來完成業務了
<scriptTask id="cancel_claim" name="取消認領" scriptFormat="groovy"> <script> import org.activity.util.SpringContextUtil import org.activiti.engine.TaskService import org.activiti.engine.task.Task def taskService = SpringContextUtil.getBean("taskServiceBean"); def task = taskService.createTaskQuery().taskId(taskId).singleResult(); if (task == null) { println("審覈任務ID:"+ taskId+"查詢到任務爲空!"); }else if(task.getAssignee()){ taskService.unclaim(taskId); println("審覈任務ID:"+ taskId+"取消認領完成"); }else{ println("審覈任務ID:"+ taskId+"未被認領"); } </script> </scriptTask>
值得注意的是,生成activiti的五大類的bean的地方是在AbstractProcessEngineConfiguration這個類中。因此向要使用什麼類,在這個類中查看具體的類名。
以上就是到目前爲止的調查結果。若是還有新的內容會在後面更新~