Activiti 用戶指南(Spring Boot集成)

Spring Boot集成

根據其網站,Spring Boot是一個應用程序框架,能夠輕鬆建立獨立的、生產級的基於Spring的應用程序,你能夠「just run」,大多數Spring Boot應用程序只須要不多的Spring配置。mysql

Spring Boot-Activiti集成目前處於試驗階段,它已經與Spring提交者一塊兒開發,可是還處於初期。web

入門

Spring Boot徹底是關於配置的約定,首先,只需將activiti-spring-boot-starter依賴項添加到你的項目中,以Maven爲例:spring

<dependency>
    <groupId>org.activiti</groupId>
    <artifactId>activiti-spring-boot-starter</artifactId>
    <version>7.0.0.SR1</version>
</dependency>

這就是全部須要的,該依賴關係將向類路徑中傳遞正確的Activiti和Spring依賴關係,你如今能夠編寫Spring Boot應用程序:sql

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan
@EnableAutoConfiguration
public class MyApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }

}

Activiti須要一個數據庫來存儲其數據,若是你運行上面的代碼,它將爲你提供一條提示性異常消息,你須要將數據庫驅動程序依賴項添加到類路徑中,如今,添加H2數據庫依賴項:數據庫

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
</dependency>

如今能夠啓動該應用程序,你將看到以下輸出:apache

.   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.2.2.RELEASE)

2019-12-19 17:19:27.564  INFO 74776 --- [           main] c.i.a.ActivitiDemoApplication            : No active profile set, falling back to default profiles: default
2019-12-19 17:19:28.929  INFO 74776 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 7000 (http)
2019-12-19 17:19:28.941  INFO 74776 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2019-12-19 17:19:28.941  INFO 74776 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.29]
2019-12-19 17:19:29.027  INFO 74776 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2019-12-19 17:19:29.027  INFO 74776 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1422 ms
2019-12-19 17:19:29.070  INFO 74776 --- [           main] .s.s.UserDetailsServiceAutoConfiguration : 
2019-12-19 17:19:33.068  INFO 74776 --- [           main] o.a.engine.impl.ProcessEngineImpl        : ProcessEngine default created
2019-12-19 17:19:33.069  INFO 74776 --- [           main] o.a.e.i.a.DefaultAsyncJobExecutor        : Starting up the default async job executor [org.activiti.spring.SpringAsyncExecutor].
2019-12-19 17:19:33.069  INFO 74776 --- [      Thread-13] o.a.e.i.a.AcquireAsyncJobsDueRunnable    : {} starting to acquire async jobs due
2019-12-19 17:19:33.069  INFO 74776 --- [      Thread-14] o.a.e.i.a.AcquireTimerJobsRunnable       : {} starting to acquire async jobs due
2019-12-19 17:19:33.070  INFO 74776 --- [      Thread-15] o.a.e.i.a.ResetExpiredJobsRunnable       : {} starting to reset expired jobs
2019-12-19 17:19:34.049  INFO 74776 --- [           main] o.s.s.web.DefaultSecurityFilterChain     : Creating filter chain: any request, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@66e341e9, org.springframework.security.web.context.SecurityContextPersistenceFilter@28d739f1, org.springframework.security.web.header.HeaderWriterFilter@448462f0, org.springframework.security.web.csrf.CsrfFilter@55877274, org.springframework.security.web.authentication.logout.LogoutFilter@5ec9eefa, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@5d1bdd4a, org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@5fb3111a, org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter@5b48f0f4, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@682e422c, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@7e3d2ebd, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@6f50d55c, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@546ed2a0, org.springframework.security.web.session.SessionManagementFilter@132e3594, org.springframework.security.web.access.ExceptionTranslationFilter@138f0661, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@32ae8f27]
2019-12-19 17:19:34.098  INFO 74776 --- [           main] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 2 endpoint(s) beneath base path '/actuator'
2019-12-19 17:19:34.169  INFO 74776 --- [           main] o.a.s.AbstractActivitiSmartLifeCycle     : Starting...
2019-12-19 17:19:34.193  INFO 74776 --- [           main] o.a.s.AbstractActivitiSmartLifeCycle     : Started.
2019-12-19 17:19:34.193  INFO 74776 --- [           main] o.a.s.AbstractActivitiSmartLifeCycle     : Starting...
2019-12-19 17:19:34.195  INFO 74776 --- [           main] o.a.s.AbstractActivitiSmartLifeCycle     : Started.
2019-12-19 17:19:34.248  INFO 74776 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 7000 (http) with context path ''
2019-12-19 17:19:34.251  INFO 74776 --- [           main] c.i.a.ActivitiDemoApplication            : Started ActivitiDemoApplication in 7.2 seconds (JVM running for 7.818)

所以,僅將依賴項添加到類路徑並使用@EnableAutoConfiguration註解,在幕後發生了不少事情:api

  • 自動建立內存中的數據源(由於H2驅動程序在類路徑中),並傳遞給Activiti流程引擎配置。
  • 建立並公開了一個Activiti ProcessEngine bean。
  • 全部Activiti服務都做爲Spring Bean公開。
  • Spring Job Executor已建立。

另外,processes文件夾中的任何BPMN 2.0流程定義都將自動部署,建立一個文件夾processes,而後向該文件夾添加一個虛擬流程定義(名爲one-task-process.bpmn20.xml)。tomcat

<?xml version="1.0" encoding="UTF-8"?>
<definitions
        xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
        xmlns:activiti="http://activiti.org/bpmn"
        targetNamespace="Examples">

    <process id="oneTaskProcess" name="The One Task Process">
        <startEvent id="theStart" />
        <sequenceFlow id="flow1" sourceRef="theStart" targetRef="theTask" />
        <userTask id="theTask" name="my task" activiti:assignee="kermit" />
        <sequenceFlow id="flow2" sourceRef="theTask" targetRef="theEnd" />
        <endEvent id="theEnd" />
    </process>

</definitions>

還添加如下代碼行以測試部署是否確實有效,CommandLineRunner是一種特殊的Spring bean,在應用程序啓動時執行:session

@Configuration
@ComponentScan
@EnableAutoConfiguration
public class MyApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }

    @Bean
    public CommandLineRunner init(final RepositoryService repositoryService,
                                  final RuntimeService runtimeService,
                                  final TaskService taskService) {

        return new CommandLineRunner() {
            @Override
            public void run(String... strings) throws Exception {
                System.out.println("Number of process definitions : "
                    + repositoryService.createProcessDefinitionQuery().count());
                System.out.println("Number of tasks : " + taskService.createTaskQuery().count());
                runtimeService.startProcessInstanceByKey("oneTaskProcess");
                System.out.println("Number of tasks after process start: " + taskService.createTaskQuery().count());
            }
        };

    }

}

輸出將如預期的那樣:app

Number of process definitions : 1
Number of tasks : 0
Number of tasks after process start : 1

更改數據庫和鏈接池

如上所述,Spring Boot是關於配置的約定,默認狀況下,經過僅在類路徑上使用H2,它建立了一個內存數據源,並將其傳遞給Activiti流程引擎配置。

要更改數據源,只需提供Datasource bean便可覆蓋默認值,咱們在這裏使用DataSourceBuilder類,它是Spring Boot的幫助類。若是在類路徑上有Tomcat、HikariCP或Commons DBCP,則將選擇其中之一(首先按Tomcat的順序),例如,要切換到MySQL數據庫:

@Bean
public DataSource database() {
    return DataSourceBuilder.create()
        .url("jdbc:mysql://127.0.0.1:3306/activiti-spring-boot?characterEncoding=UTF-8")
        .username("alfresco")
        .password("alfresco")
        .driverClassName("com.mysql.jdbc.Driver")
        .build();
}

從Maven依賴項中刪除H2並將MySQL驅動程序和Tomcat鏈接池添加到類路徑中:

如今啓動應用程序後,你會看到它使用MySQL做爲數據庫(和Tomcat鏈接池框架):

org.activiti.engine.impl.db.DbSqlSession   : performing create on engine with resource org/activiti/db/create/activiti.mysql.create.engine.sql
org.activiti.engine.impl.db.DbSqlSession   : performing create on history with resource org/activiti/db/create/activiti.mysql.create.history.sql
org.activiti.engine.impl.db.DbSqlSession   : performing create on identity with resource org/activiti/db/create/activiti.mysql.create.identity.sql

屢次從新啓動應用程序時,你會看到任務數量增長(H2內存數據庫沒法在關機後生存,而MySQL能夠)。

REST支持

一般,嵌入式Activiti引擎之上須要REST API(與公司中的不一樣服務進行交互),Spring Boot使這變得很是容易,將如下依賴項添加到類路徑:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

建立一個新類,一個Spring服務,並建立兩個方法:一個方法啓動咱們的流程,另外一個方法獲取給定受讓人的任務列表,這裏僅將簡單包裝Activiti調用,可是在實際狀況下,這顯然會更加複雜。

@Service
public class MyService {

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @Transactional
    public void startProcess() {
        runtimeService.startProcessInstanceByKey("oneTaskProcess");
    }

    @Transactional
    public List<Task> getTasks(String assignee) {
        return taskService.createTaskQuery().taskAssignee(assignee).list();
    }

}

如今,咱們能夠經過使用@RestController註解類來建立REST端點,在這裏,咱們僅委託給上面定義的服務。

@RestController
public class MyRestController {

    @Autowired
    private MyService myService;

    @RequestMapping(value="/process", method= RequestMethod.POST)
    public void startProcessInstance() {
        myService.startProcess();
    }

    @RequestMapping(value="/tasks", method= RequestMethod.GET, produces=MediaType.APPLICATION_JSON_VALUE)
    public List<TaskRepresentation> getTasks(@RequestParam String assignee) {
        List<Task> tasks = myService.getTasks(assignee);
        List<TaskRepresentation> dtos = new ArrayList<TaskRepresentation>();
        for (Task task : tasks) {
            dtos.add(new TaskRepresentation(task.getId(), task.getName()));
        }
        return dtos;
    }

    static class TaskRepresentation {

        private String id;
        private String name;

        public TaskRepresentation(String id, String name) {
            this.id = id;
            this.name = name;
        }

         public String getId() {
            return id;
        }
        public void setId(String id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }

    }

}

咱們添加到應用程序類中的自動組件掃描(@ComponentScan)均可以找到@Service@RestController,再次運行應用程序類,如今,咱們可使用如cURL與REST API進行交互:

curl http://localhost:8080/tasks?assignee=kermit
[]

curl -X POST  http://localhost:8080/process
curl http://localhost:8080/tasks?assignee=kermit
[{"id":"10004","name":"my task"}]
相關文章
相關標籤/搜索