根據其網站,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
ProcessEngine
bean。另外,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能夠)。
一般,嵌入式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"}]