Spring Boot + Activiti Service Task Example


In this tutorial, we will discuss Spring Boot + Activiti Service Task example. Service task is used to invoke an external Java class. A service task is visualized as a rounded rectangle with a small gear icon in the top-left corner.

Spring Boot + Activiti Service Task Example

Activiti is an open-source workflow engine that can execute business processes described in BPMN 2.0 and in our previous example on Spring Boot + Activiti, we had discussed the basic fundamental of Activiti workflow engine and create a user task, assigned the task to a user and user will complete it.

BPMN 2.0 introduced many sub-tasks under task category like user task, service task, script task, camel task, etc for different purposes and workflow process engine execute them. On this page, we will execute the Service Task using Activiti workflow engine.

What we’ll build

Today, we are going to design a Service Task using the Activiti Designer plugin and execute them via Activiti workflow engine. Our service task will print some message on the console.

1. Technologies Used

Find the list of all technologies used in this application.

  1. STS 3
  2. JDK 8
  3. Spring Boot 1.5.3.RELEASE
  4. Activiti 5.22.0
  5. H2 Database

2. Dependencies Required

Add the following to your pom.xml.

<properties>
	<java.version>1.8</java.version>
	<activiti.version>5.22.0</activiti.version>
</properties>
<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</dependency>
	<dependency>
		<groupId>org.activiti</groupId>
		<artifactId>activiti-spring-boot-starter-basic</artifactId>
		<version>${activiti.version}</version>
	</dependency>
	<dependency>
		<groupId>com.h2database</groupId>
		<artifactId>h2</artifactId>
	</dependency>
</dependencies>

3. Invoking Java Logic

There are 4 ways of declaring how to invoke Java logic in service task:

  1. Specifying a class that implements JavaDelegate or ActivityBehavior
  2. Evaluating an expression that resolves to a delegation object
  3. Invoking a method expression
  4. Evaluating a value expression

In our demonstration, we are going to use only Java Delegate (first) and Method Expression (third) to execute our Java logic in service task.

3.1.1 Class that implements JavaDelegate

Create a JavaDelegateService class which implements JavaDelegate interface of package org.activiti.engine.delegate. Override it’s execute() method and put your Java logic to be executed by service task.

JavaDelegateService.java
package org.websparrow.activiti.service;

import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.JavaDelegate;
import org.springframework.stereotype.Service;

@Service
public class JavaDelegateService implements JavaDelegate {

	@Override
	public void execute(DelegateExecution execution) throws Exception {

		System.out.println("Java Delegate Service Task executed successfully.");

		System.out.println("And the Sum of 2 + 2= " + (2 + 2));

	}
}

3.1.2 JavaDelegate BPMN Process Definition

Drop the BPMN 2.0 process definition into the src/main/resources/processes folder. To specify a class that is called during the process execution, the fully qualified class name needs to be provided by the activiti:class attribute.

<serviceTask id="javadeletegateservicetask" name="Java Delegate Service Task"
			activiti:class="org.websparrow.activiti.service.JavaDelegateService">
</serviceTask>

See the complete process definition.

delegate-service-process.bpmn
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
	xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
	xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI"
	typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath"
	targetNamespace="Examples">
	<process id="java-delegate-service-task-process" name="Activiti Service Task using Java Delegates"
		isExecutable="true">
		<startEvent id="startevent1" name="Start"></startEvent>
		<serviceTask id="javadeletegateservicetask" name="Java Delegate Service Task"
			activiti:class="org.websparrow.activiti.service.JavaDelegateService"></serviceTask>
		<sequenceFlow id="flow1" sourceRef="startevent1"
			targetRef="javadeletegateservicetask"></sequenceFlow>
		<endEvent id="endevent1" name="End"></endEvent>
		<sequenceFlow id="flow2" sourceRef="javadeletegateservicetask"
			targetRef="endevent1"></sequenceFlow>
	</process>
</definitions>

The above BPMN process definition gives you the below-visualized diagram:

Spring Boot + Activiti Service Task Example

3.1.3 JavaDelegate Controller

Create DelegateServiceTaskController class which autowired the RuntimeService and execute the process by its process instance key.

DelegateServiceTaskController.java
package org.websparrow.activiti.controller;

import org.activiti.engine.RuntimeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("activiti")
public class DelegateServiceTaskController {

	@Autowired
	private RuntimeService runtimeService;

	@GetMapping("service/delegate")
	public String startTheProcess() {

		runtimeService.startProcessInstanceByKey("java-delegate-service-task-process");

		return "Check the console log...";
	}
}

Output: Now everything is all set, hit the http://localhost:8080/activiti/service/delegate URL in your web browser and check your IDE console log. You will get the:

Java Delegate Service Task executed successfully.
And the Sum of 2 + 2= 4

3.2.1 Invoking a method expression

Invoking the Java classes using method expression is another great way to execute your business logic in the workflow diagram. Create a MethodExpressionService class where the business logic will be executed inside the myService() method.

MethodExpressionService.java
package org.websparrow.activiti.service;

import org.springframework.stereotype.Service;

@Service
public class MethodExpressionService {

	public void myService() {

		System.out.println("Method Expression Service Task executed successfully.");

		System.out.println("And the Multiply of 2 * 2= " + (2 * 2));
	}
}

3.2.2 Method Expression BPMN Process Definition

Drop the BPMN 2.0 process definition into the src/main/resources/processes folder. To specify a class method that is called during the process execution, method expression uses the Spring bean which is implemented with attribute activiti:expression.

<serviceTask id="methodExpressionServiceTask" name="Method Expression Service Task"
			activiti:expression="${methodExpressionService.myService()}">
</serviceTask>

See the complete process definition.

expression-service-process.bpmn
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
	xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
	xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI"
	typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath"
	targetNamespace="Examples">
	<process id="method-expression-service-task-process" name="Activiti Service Task using Method Expression"
		isExecutable="true">
		<startEvent id="startevent1" name="Start"></startEvent>
		<serviceTask id="methodExpressionServiceTask" name="Method Expression Service Task"
			activiti:expression="${methodExpressionService.myService()}"></serviceTask>
		<sequenceFlow id="flow1" sourceRef="startevent1"
			targetRef="methodExpressionServiceTask"></sequenceFlow>
		<endEvent id="endevent1" name="End"></endEvent>
		<sequenceFlow id="flow2" sourceRef="methodExpressionServiceTask"
			targetRef="endevent1"></sequenceFlow>
	</process>
</definitions>

The above BPMN process definition gives you the below-visualized diagram:

Spring Boot + Activiti Service Task Example

3.2.3 Method Expression Controller

Create ExpressionServiceTaskController class which autowired the RuntimeService and execute the process by its process instance key.

ExpressionServiceTaskController.java
package org.websparrow.activiti.controller;

import org.activiti.engine.RuntimeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("activiti")
public class ExpressionServiceTaskController {

	@Autowired
	private RuntimeService runtimeService;

	@GetMapping("service/expression")
	public String startTheProcess() {

		runtimeService.startProcessInstanceByKey("method-expression-service-task-process");

		return "Check the console log...";
	}
}

Output: Hit the http://localhost:8080/activiti/service/expression  URL in your web browser and check the console log. You will get the:

Method Expression Service Task executed successfully.
And the Multiply of 2 * 2= 4

4. Project Structure

Final project structure of our application in STS ide will look like as follows:

Spring Boot + Activiti Service Task Example

References

  1. Spring Boot + Activiti Example
  2. Java Service Task- Activiti User Guide
  3. Getting started with Activiti and Spring Boot

Similar Posts

About the Author

Atul Rai
I love sharing my experiments and ideas with everyone by writing articles on the latest technological trends. Read all published posts by Atul Rai.