根据其网站,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"}]