天天看點

Activiti工作流學習分享一:什麼是Activiti二:為什麼需要引入Activiti工作流三:如何使用Activiti四.Activiti架構

一:什麼是Activiti

Activiti是一個開源的工作流引擎,它實作了BPMN 2.0規範,可以釋出設計好的流程定義,并通過api進行流程排程。

業務流程模型注解(Business Process Modeling Notation - BPMN)是 業務流程模型的一種标準圖形注解。包括使用者任務,定時任務都有統一的模型規範。

Activiti 作為一個遵從 Apache 許可的工作流和業務流程管理開源平台,其核心是基于Java的超快速、超穩定的 BPMN2.0 流程引擎,強調流程服務的可嵌入性和可擴充性,同時更加強調面向業務人員。

在項目中,Activiti實際上相當于一個第三方插件幫助原本系統業務更好的執行,Activiti本身并沒有任何業務邏輯。

二:為什麼需要引入Activiti工作流

舉個例子:

如果我們要開發一套請假流程,具體流程如下:

Activiti工作流學習分享一:什麼是Activiti二:為什麼需要引入Activiti工作流三:如何使用Activiti四.Activiti架構

在沒有Activiti工作流引擎幫助下,我們會怎麼設計表結構?預設模式下,應該會設計兩張表,一張來存請假内容,一張來存請假審批過程。隻有總經理和HR人力能夠批改。假設當我們設計好表後,需求改變了,經理審批這個節點改成組長審批,那這個時候,我們是不是又要修改代碼或者表結構?

這個時候Activiti引擎起作用。我們不會把具體節點人寫死,而是可以在流程過程中指定。

三:如何使用Activiti

Activiti使用時注意的概念

1.儲存流程圖—>相當于将流程圖存到activiti資料庫中,此時是靜态資源。

2.釋出流程---->相當java中的類,如果開始節點部署的普通的開始事件,則不會自動啟動流程,如果裡面開始節點使用定時事件,則到時間便會自動啟動流程執行個體(可以内置定時事件應用到TCL電子的點檢任務)。

3.啟動流程執行個體—>相當java中的對象

1.每個節點的任務都指定具體人

Activiti工作流學習分享一:什麼是Activiti二:為什麼需要引入Activiti工作流三:如何使用Activiti四.Activiti架構
Activiti工作流學習分享一:什麼是Activiti二:為什麼需要引入Activiti工作流三:如何使用Activiti四.Activiti架構

@RequestMapping(value="/model/{modelId}/save", method = RequestMethod.PUT)

@ResponseStatus(value = HttpStatus.OK)

public void saveModel(@PathVariable String modelId

, String name, String description

, String json_xml, String svg_xml) {

try {

Model model = repositoryService.getModel(modelId);

ObjectNode modelJson = (ObjectNode) objectMapper.readTree(model.getMetaInfo());

modelJson.put(MODEL_NAME, name);

modelJson.put(MODEL_DESCRIPTION, description);

model.setMetaInfo(modelJson.toString());

model.setName(name);

repositoryService.saveModel(model);

repositoryService.addModelEditorSource(model.getId(), json_xml.getBytes(“utf-8”));

InputStream svgStream = new ByteArrayInputStream(svg_xml.getBytes(“utf-8”));

TranscoderInput input = new TranscoderInput(svgStream);

PNGTranscoder transcoder = new PNGTranscoder();

// Setup output

ByteArrayOutputStream outStream = new ByteArrayOutputStream();

TranscoderOutput output = new TranscoderOutput(outStream);

// Do the transformation

transcoder.transcode(input, output);

final byte[] result = outStream.toByteArray();

repositoryService.addModelEditorSourceExtra(model.getId(), result);

outStream.close();

} catch (Exception e) {

LOGGER.error(“Error saving model”, e);

throw new ActivitiException(“Error saving model”, e);

}

}

@ResponseBody

@RequestMapping("/publish")

public Object publish(String modelId){

logger.info(“流程部署入參modelId:{}”,modelId);

Map<String, String> map = new HashMap<String, String>();

try {

Model modelData = repositoryService.getModel(modelId);

byte[] bytes = repositoryService.getModelEditorSource(modelData.getId());

if (bytes == null) {

logger.info(“部署ID:{}的模型資料為空,請先設計流程并成功儲存,再進行釋出”,modelId);

map.put(“code”, “FAILURE”);

return map;

}

JsonNode modelNode = new ObjectMapper().readTree(bytes);

BpmnModel model = new BpmnJsonConverter().convertToBpmnModel(modelNode);

Deployment deployment = repositoryService.createDeployment()

.name(modelData.getName())

.addBpmnModel(modelData.getKey()+".bpmn20.xml", model)

.deploy();

modelData.setDeploymentId(deployment.getId());

repositoryService.saveModel(modelData);

map.put(“code”, “SUCCESS”);

} catch (Exception e) {

logger.info(“部署modelId:{}模型服務異常:{}”,modelId,e);

map.put(“code”, “FAILURE”);

}

logger.info(“流程部署出參map:{}”,map);

return map;

}

Activiti工作流學習分享一:什麼是Activiti二:為什麼需要引入Activiti工作流三:如何使用Activiti四.Activiti架構

@Test

public void completeTask() {

List list = taskService.createTaskQuery().taskAssignee(“張三”).list();

for (Task task : list) {

taskService.complete(task.getId());

}

}

2.節點代理人是動态的

Activiti工作流學習分享一:什麼是Activiti二:為什麼需要引入Activiti工作流三:如何使用Activiti四.Activiti架構

流程變量概念:相當于局部變量,使用範圍在目前執行個體内有效

@Test

public void startProcessInstance() {

Map<String, Object> map = new HashMap<>();

map.put(“name”, “張三”);

runtimeService.startProcessInstanceByKey(“process”,map);

}

3.流程分支控制

Activiti工作流學習分享一:什麼是Activiti二:為什麼需要引入Activiti工作流三:如何使用Activiti四.Activiti架構
Activiti工作流學習分享一:什麼是Activiti二:為什麼需要引入Activiti工作流三:如何使用Activiti四.Activiti架構

@Test

public void completeTask() {

List list = taskService.createTaskQuery().taskAssignee(“張三”).list();

for (Task task : list) {

taskService.setVariable(task.getId(),“num”,2);

taskService.complete(task.getId());

}

}

@Test

public void completeTask() {

List list = taskService.createTaskQuery().taskAssignee(“張三”).list();

for (Task task : list) {

Map<String, Object> map = new HashMap<>();

map.put(“num”, 2);

taskService.complete(task.getId(),map);

}

}

4.候選人和候選組

在實作上,候選人和候選組是一樣的

假設總經理有多個人可以審批請假流程,那我們不能把審批人固定為某個人。我們可以直接寫死候選人,也可以将候選人設定為流程變量,然後在流程執行過程中設定變量值。

Activiti工作流學習分享一:什麼是Activiti二:為什麼需要引入Activiti工作流三:如何使用Activiti四.Activiti架構
Activiti工作流學習分享一:什麼是Activiti二:為什麼需要引入Activiti工作流三:如何使用Activiti四.Activiti架構

@Test

public void claimTask() {

List list = taskService.createTaskQuery().taskCandidateUser(“劉備”).list();

for (Task task : list) {
       taskService.claim(task.getId(), "劉備");
   }
           

}

5.定時任務和腳本任務

假設總經理比較忙,太長時間忘記審批,這個時候可以設定定時任務,調用腳本進行通知

Activiti工作流學習分享一:什麼是Activiti二:為什麼需要引入Activiti工作流三:如何使用Activiti四.Activiti架構

定時任務設定

Activiti工作流學習分享一:什麼是Activiti二:為什麼需要引入Activiti工作流三:如何使用Activiti四.Activiti架構

時間格式使用ISO-8601使用方式可以參考百度百科;其中循環時間可以使用corn表達式

腳本任務設定

Activiti工作流學習分享一:什麼是Activiti二:為什麼需要引入Activiti工作流三:如何使用Activiti四.Activiti架構

腳本支援JavaScript, groovy,研究當中,使用JavaScript

腳本内容中我們可以調用java背景代碼中方法

如下callService是我們在java背景中寫的一個托管給spring的類,execution是activiti内置的對象,javascript和java代碼中都能對其進行調用,可以通過execution擷取該流程目前執行個體id,流程變量等。

Activiti工作流學習分享一:什麼是Activiti二:為什麼需要引入Activiti工作流三:如何使用Activiti四.Activiti架構

@Component

public class CallService {

public String get(DelegateExecution execution){
    System.out.println("----get----"+new Date()+"processInstanceId="+execution.getProcessInstanceId()+"--businessKey="+execution.getProcessBusinessKey());
    return null;
}
           

}

6.内置定時啟動事件

應用場景:需要定時啟動某些流程的時候,我們可以使用定時啟動事件做為開始事件。

此時隻需要将此流程部署即可,注意點:如果需要使用該定時啟動事件的流程來定時啟動任務,則部署該定時啟動事件流程時需要設定不同流程名(processDefinitonKey)。

和前端探讨:1.修改節點内容

Activiti工作流學習分享一:什麼是Activiti二:為什麼需要引入Activiti工作流三:如何使用Activiti四.Activiti架構

四.Activiti架構

Activiti工作流學習分享一:什麼是Activiti二:為什麼需要引入Activiti工作流三:如何使用Activiti四.Activiti架構

activiti.cfg.xml

activiti 的引擎配置檔案,包括:ProcessEngineConfiguration 的定義、資料源定義、事務管理器等,此檔案其實就是一個 spring 配置檔案。

ProcessEngineConfiguration

流程引擎的配置類,通過 ProcessEngineConfiguration 可以建立工作流引擎 ProceccEngine。

ProcessEngine

工作流引擎,相當于一個門面接口,通過 ProcessEngineConfiguration 建立 processEngine,通過ProcessEngine 建立各個 service 接口。

7個service,在研究當中隻看

IdentityService, FormService,ManagementService暫無研究

RepositoryService

是 activiti 的資源管理類,提供了管理和控制流程釋出包和流程定義的操作。使用工作流模組化工具設計的業務流程圖需要使用此 service 将流程定義檔案的内容部署到計算機。

除了部署流程定義以外還可以:

查詢引擎中的釋出包和流程定義。

暫停或激活釋出包,對應全部和特定流程定義。 暫停意味着它們不能再執行任何操作了,激活

是對應的反向操作。

獲得多種資源,像是包含在釋出包裡的檔案, 或引擎自動生成的流程圖。

獲得流程定義的 pojo 版本, 可以用來通過 java 解析流程,而不必通過 xml。

RuntimeService

它是 activiti 的流程運作管理類。可以從這個服務類中擷取很多關于流程執行相關的資訊

TaskService

是 activiti 的任務管理類。可以從這個類中擷取任務的資訊。

HistoryService

是 activiti 的曆史管理類,可以查詢曆史資訊,執行流程時,引擎會儲存很多資料(根據配置),比

如流程執行個體啟動時間,任務的參與者, 完成任務的時間,每個流程執行個體的執行路徑,等等。 這個

服務主要通過查詢功能來獲得這些資料。