阿里巴巴网站的搜索引擎优化案例,七台河建设网站,wordpress栏目图标,网络推广岗位职责和任职要求文章目录 版本依赖配置文件需要注意的问题画流程图activiti服务类进行编写流程部署流程定义启动流程流程实例 测试流程启动流程完成任务受理任务 版本依赖
开发工具 IDEASpringBoot 2.4.5#xff08;这里我试过SpringBoot 3.1.1版本#xff0c;Activiti没有启动#xff0c;… 文章目录 版本依赖配置文件需要注意的问题画流程图activiti服务类进行编写流程部署流程定义启动流程流程实例 测试流程启动流程完成任务受理任务 版本依赖
开发工具 IDEASpringBoot 2.4.5这里我试过SpringBoot 3.1.1版本Activiti没有启动应该是依赖冲突了后改成了2.4.5版本Activiti 7.1.0.M6 父项目pom.xml dependencyManagementdependencies!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-parent --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion2.4.5/versiontypepom/typescopeimport/scope/dependency!-- https://mvnrepository.com/artifact/org.activiti.dependencies/activiti-dependencies --dependencygroupIdorg.activiti.dependencies/groupIdartifactIdactiviti-dependencies/artifactIdversion7.1.0.M6/versiontypepom/typescopeimport/scope/dependency/dependencies/dependencyManagement子项目pom.xml dependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependencydependencygroupIdorg.activiti/groupIdartifactIdactiviti-spring-boot-starter/artifactId/dependencydependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-jdbc/artifactId/dependency/dependencies配置文件
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Drivertype: com.zaxxer.hikari.HikariDataSourceusername: rootpassword: 111111url: jdbc:mysql://127.0.0.1:3306/activiti?useUnicodetruecharacterEncodingUTF-8serverTimezoneGMT%2B8useSSLfalseuseInformationSchematruehikari:#连接池做大连接数maximum-pool-size: 30#连接池空闲连接最小数量#minimum-idle: 10#允许连接在连接池中闲置最长时间#idle-timeout: 30000#池中连接最长生命周期max-lifetime: 120000#等待来自池的连接的最大毫秒数connection-timeout: 30000activiti:#自动更新数据库结构#1.flase默认值。activiti在启动时对比数据库表中保存的版本如果没有表或者版本不匹配将抛出异常#2.true activiti会对数据库中所有表进行更新操作。如果表不存在则自动创建#3.create_drop 在activiti启动时创建表在关闭时删除表必须手动关闭引擎才能删除表#4.drop-create 在activiti启动时删除原来的旧表然后在创建新表不需要手动关闭引擎database-schema-update: true#activiti7默认不生成历史信息表开启历史表db-history-used: true#记录历史等级 可配置的历史级别有none, activity, audit, full#none不保存任何的历史数据因此在流程执行过程中这是最高效的。#activity级别高于none保存流程实例与流程行为其他数据不保存。#audit除activity级别会保存的数据外还会保存全部的流程任务及其属性。audit为history的默认值。#full保存历史数据的最高级别除了会保存audit级别的数据外还会保存其他全部流程相关的细节数据包括一些流程参数等。history-level: full#自动检查、部署流程定义文件check-process-definitions: false# asyncExecutorActivate是指activiti在流程引擎启动就激活AsyncExecutor,异步true-开启默认、false-关闭async-executor-activate: true
配置文件这里注意要设置 database-sechema-update的属性为true才会自动创建表。
需要注意的问题
在初次启动时可能会报错报错如下
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type org.springframework.security.core.userdetails.UserDetailsService available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1790)at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1346)at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300)at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887)at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791)... 142 more
这里是需要一个UserDetailsService的Bean需要创建一个类去实现UserDetailsService接口 UserDetailsServiceImpl.class package org.example.config;import org.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;Component
public class UserDetailsServiceImpl implements UserDetailsService {AutowiredUserService userService;Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {return userService.findOneUserByName(username);}
}UserService.class package org.example.service;import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Service;import java.util.List;Service
public class UserService {public User findOneUserByName(String username){ListGrantedAuthority authorities AuthorityUtils.commaSeparatedStringToAuthorityList(admin);return new User(username,,authorities);}
}启动成功后数据库会生成25张表
画流程图
在使用IDEA时需要下载一个插件 当这个插件安装好以后新建文件会多一个选项 新建的xml文件可以通过view BPMN Diagram转化为图表操作 如何通过图表操作画流程这里就不说了可以自己摸索看看。
activiti服务类进行编写
package org.example.service;import org.activiti.engine.*;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.DeploymentQuery;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;Service
public class ActivitiService {AutowiredRepositoryService repositoryService;AutowiredRuntimeService runtimeService;AutowiredTaskService taskService;AutowiredHistoryService historyService;/*** 部署流程服务*/public void deployProcess(){String file bpmn/test.bpmn20.xml;Deployment deployment repositoryService.createDeployment().addClasspathResource(file).name(流程部署测试).deploy();System.out.println(流程部署名称deployment.getName());}/*** 查询所有部署的流程定义* return*/public ListProcessDefinition getAllProcessDefinition(){ProcessDefinitionQuery query repositoryService.createProcessDefinitionQuery();return query.orderByProcessDefinitionVersion().desc().list();}/*** 查询所有的部署* return*/public ListDeployment getAllDeployment(){DeploymentQuery query repositoryService.createDeploymentQuery();return query.list();}/*** 查询所有流程实例* return*/public ListProcessInstance getAllProcessInstance(){ListProcessInstance list runtimeService.createProcessInstanceQuery().list();return list;}public ListTask getAllProcessTask(){ListTask list taskService.createTaskQuery().list();return list;}/*** 查询用户待完成和待认领的任务* param username* return*/public ListTask getAllProcessTaskByCandidateOrAssigned(String username){ListTask list taskService.createTaskQuery().taskCandidateOrAssigned(username).list();return list;}public ListTask getAllProcessTaskByCandidate(String username){ListTask list taskService.createTaskQuery().taskCandidateUser(username).list();return list;}/*** 查询用户的待完成任务* param username* return*/public ListTask getAllProcessTaskByAssigned(String username){ListTask list taskService.createTaskQuery().taskAssignee(username).list();return list;}public void complateTask(Task task, MapString, Object map){taskService.complete(task.getId(),map);}public void complateTask(Task task){taskService.complete(task.getId());}public void claimTask(Task task,String username){taskService.claim(task.getId(),username);}public ProcessInstance startProcess(String processDefinitionKey,String businessKey,MapString,Object map){return runtimeService.startProcessInstanceById(processDefinitionKey,businessKey,map);}public String getProcessDefinitionXml(String processDefinitionId) {ProcessDefinition processDefinition repositoryService.getProcessDefinition(processDefinitionId);String resourceName processDefinition.getResourceName();InputStream resourceAsStream repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), resourceName);try {return IOUtils.toString(resourceAsStream, StandardCharsets.UTF_8);} catch (IOException e) {// handle exception}return null;}public ListHistoricProcessInstance getHistoryByBusinessKey(String businessKey){ListHistoricProcessInstance list historyService.createHistoricProcessInstanceQuery().processInstanceBusinessKey(businessKey).list();return list;}
} 上图是如果需要使用activiti中提供的服务类直接注入即可。即springboot整合activiti启动过程中已经在容器中自动装配了对应的服务类需要的时候仅仅需要取来用即可。如果启动以后报错容器没有自动装配对应的服务类那很有可能是依赖冲突activiti没有正常启动。
流程部署
流程部署有多种方式这是通过资源路径部署的也可以通过压缩包的形式部署流程。那就需要用到DeploymentBuilder的addZipInputStream方法这里也是用到了设计模式中的建造者模式。 流程定义
这是一个查询所有部署的流程定义的方法 当一个流程部署以后就会生成一个流程定义流程图的xml信息也会存入数据库。每次部署流程图都会生成一个新的流程定义。
启动流程
启动流程可以通过流程定义的id或者key如果想通过流程定义的id启动一个流程可以使用startProcessInstanceById方法如果想通过流程定义的key启动一个流程可以使用startProcessInstanceByKey方法。 这里要明白流程定义id和key的区别流程定义的key是在画流程的时候可以设置的通过设置流程的id这个就是流程的key。 那流程的id呢这是部署以后在数据库表的id。可以根据需要自行选择启动流程的方法。
流程实例
查询所有启动的流程实例 每次开始一个流程以后就会生成一个流程实例。通过这个方法可以查看所有的流程实例。
测试流程
package org.example;import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.assertj.core.util.DateUtil;
import org.example.common.PrintUtil;
import org.example.entity.User;
import org.example.service.ActivitiService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import javax.annotation.Resource;
import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.*;SpringBootTest
public class SpringBootApplicationTest {ResourceDataSource dataSource;AutowiredActivitiService activitiService;Testvoid context() throws SQLException {System.out.println(dataSource.getConnection());}Testpublic void deployProcess(){activitiService.deployProcess();}Testpublic void TestStartProcess(){ProcessDefinition processDefinition activitiService.getAllProcessDefinition().get(0);String bussinessKey this.getClass().getSimpleName();MapString , Object map new HashMapString , Object();map.put(creator,Echo);activitiService.startProcess(processDefinition.getId(),bussinessKey,map);}Testpublic void findAllDeployment(){ListDeployment list activitiService.getAllDeployment();PrintUtil.printTable(list);}Testpublic void findAllProcessDefinition(){ListProcessDefinition list activitiService.getAllProcessDefinition();PrintUtil.printTable(list);}Testpublic void findAllProcessInstance(){ListProcessInstance list activitiService.getAllProcessInstance();PrintUtil.printTable(list);}Testpublic void findAllProcessTask(){ListTask list activitiService.getAllProcessTask();PrintUtil.printTable(list);}Testpublic void findTaskByUserId(){String userId keaizp;ListTask list activitiService.getAllProcessTaskByCandidateOrAssigned(userId);PrintUtil.printTable(list);}Testpublic void claimTask(){String userIdkeaizp;ListTask list activitiService.getAllProcessTaskByCandidate(userId);PrintUtil.printTable(list);activitiService.claimTask(list.get(0),userId);list activitiService.getAllProcessTaskByCandidate(zengpei);PrintUtil.printTable(list);}Testpublic void complateUserTask(){String userId Echo;ListTask list activitiService.getAllProcessTaskByAssigned(userId);ListString candidateUsers new ArrayListString();candidateUsers.add(keaizp);candidateUsers.add(zengpei);MapString,Object map new HashMapString,Object();map.put(approver,candidateUsers);activitiService.complateTask(list.get(0),map);}Testpublic void processDefinitionXml(){ListProcessDefinition list activitiService.getAllProcessDefinition();String xmlStr activitiService.getProcessDefinitionXml(list.get(0).getId());System.out.println(xmlStr);}Testpublic void findHistoryByBusinessKey(){ListHistoricProcessInstance list activitiService.getHistoryByBusinessKey(2023-07-02T22:45:45);PrintUtil.printTable(list);}Testpublic void printTest(){ListUser users new ArrayList();users.add(new User(keaizpeeeeeeeee,24,male));users.add(new User(Echo,24,male));users.add(new User(nick,24,male));users.add(new User(amy,24,male));PrintUtil.printTableFixed(users,16);}
}
启动流程 这里我用的是一个格式化的日期做bussinessKey实际业务中最好使用 流程作业类型 一个业务台账id比如请假申请要走审批流程 离职申请也要走审批流程如果只用id作为bussinessKey的话bussinessKey就无法满足唯一性。所以最好 前面加上作业类型。这里的map传入的是流程图里面的参数。 传入受理人这里就会产生一个Task就是用户的代办任务。
完成任务 当用户登录系统的时候应该给用户提示用户有未完成的代办事项然后给出用户代办事项列表做完一切以后就是完成用户任务这个时候可以传入下一流程节点参与任务的人当然你也可以传入几个候选人candidate Users就是 候选人。可以传入一个用户id的列表然后这几个人就会收到可以受理的任务可以选择是否接受该任务。只要接受了任务其他候选人就无法再接受此任务同时这个任务的Assignee就会设置成受理人的id
受理任务 因为用户“keaizp”成为了候选者他就可以看到自己可以受理的这个任务用claim方法就可以受理该任务当受理任务完成以后再去看看另外一名候选者的受理任务会发现已经没有待受理的任务了。