activiti工作学习之spring整合activiti

Spring Boot整合Activiti工作流详解 通过Spring Boot与Activiti的整合,可以快速构建基于工作流的业务系统,大大提高开发效率和系统灵活性。 阅读详情

       前言:博主之前对于工作流这一块的知识是空白的,也是因为前段时间公司的一个项目,然后其中有个审核环节需要用到工作流来开发比较简单,所以就各种找资料恶补了一番。现阶段博主也仅仅停留在会用,用过,有点校验的阶段,写这篇博客也是想把自己的经验写下来(ps:博主有个习惯,就是一些工作上的难点,或者是自己以前没有接触过的东西,博主就会自己用过之后会把它写下来,这样的话有助于自己巩固这个知识点),如果能帮助到那些正需要的童鞋的话,那是再好不过了~~

 

1.eclipse安装插件

    1)打开 Help -> Install New Software. 在如下面板中:

2)然后点击右上角的Add按钮,添加配置插件的地址,如下图:

3)对应的填入下面的值即可(下面的值我也是从网上找来的)

Name: Activiti BPMN 2.0 designer

Location: http://activiti.org/designer/update/

4)点击OK之后,勾选对应的选项即可:

5)然后新建工程的时候,如果有activiti相关的东西就证明插件安装成功

2.准备activiti的开发环境搭建----springmvc整合activiti

1)pom文件添加activiti相关jar包和spring整合包

                <!--工作流activiti  -->
  		<dependency>  
		    <groupId>org.activiti</groupId>  
		    <artifactId>activiti-engine</artifactId>  
		    <version>${activiti.version}</version>  
		</dependency>  
		<dependency>  
		    <groupId>org.activiti</groupId>  
		    <artifactId>activiti-spring</artifactId>  
		    <version>${activiti.version}</version>  
		</dependency>
<activiti.version>5.22.0</activiti.version>

2)xml中的相关配置

<!--    Activiti相关配置         -->
    <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
    	<property name="processEngineConfiguration" ref="processEngineConfiguration"></property>
    </bean>
    
    <bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
    	<!--注入数据源  -->
    	<property name="dataSource" ref="dataSource"></property>
    	<!--配置事物管理  -->
    	<property name="transactionManager" ref="transactionManager"></property>
    	<!--没有表创建表  -->
    	<property name="databaseSchemaUpdate" value="true"></property>
		<property name="jobExecutorActivate" value="false"></property>
		
		<!--自动部署  -->
		<property name="deploymentResources">
			<list>
				<value>classpath*:activiti/OrderCheck.bpmn</value>
			</list>
		</property>
    </bean>
    
    <!--activiti的各种服务接口  -->
    <!-- 工作流仓储服务 -->
    <bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService" />
    <!--工作流运行服务  -->
    <bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService" />
    <!--工作流任务服务  -->
    <bean id="taskService" factory-bean="processEngine" factory-method="getTaskService" />
    <!--工作流历史数据服务  -->
    <bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService" />
    <!--工作流管理服务  -->
    <bean id="managementService" factory-bean="processEngine" factory-method="getManagementService" />
    <!--工作流唯一服务  -->
    <bean id="identityService" factory-bean="processEngine" factory-method="getIdentityService" />
    <bean id="formService" factory-bean="processEngine" factory-method="getFormService" />

以上配置配置完,启动你的服务时,就会去你配置的自动部署的路径下面去找bpmn结尾的activiti文件去自动创建核心流程引擎对象,也就是processEngine

3.activiti流程图的一些属性

上图就是我当时项目里的一个审核的流程,逻辑上来讲并不是很复杂,运用到的activiti知识点也不是很多,只有一个排他网关,接下来我就讲一下我认为学会用activiti必需要知道的一些东西(本人也不是很熟悉,只是了解)

1)首先要给你的流程processEngine设置一个id和name,这个id就是你的processEngine唯一标识,开启这个流程实例就需要用得到你的id作为key(因为用id开启流程实例activiti会根据你的最新版本的流程来开启),具体设置如下:

2)然后就是根据你的实际业务逻辑给你自己设计的流程的每个task设置一个当前task的待办人或者待办组,如下:

Assignee:当前task的待办人,只有这个人才有权限看到当前任务,也只有这个人才能操作

users和groups:待办组,可以设置一组当前task的待办人,这里就可以集合role来做权限控制,只有某个role才能看到和操作当前任务

3)当前task默认执行的flow和flow的一些属性:每个task都有一个default flow属性设置,可有可无,但是如果有存在task提交之后会产生多个结果的情况下,最好需要设置,比如我在合同领取task设置了default flow为flow20,那么当当前task提交的时候,默认就会直接走flow,走到下一task

如果我想它走flow33,那么我就得需要再flow的main config属性里面设置condition的值,这里可以用表达式来做一个判断

当我在代码里设置的流程变量满足这个表达式,那么当提交当前task的时候,就会走flow33这条线。

4.activiti实战

1)开启一个流程:开启流程是通过runtimeService来实现的,activiti提供了各种service来满足用户的需求,在这里有一个很关键的点,流程关联业务。怎么样让流程和业务关联起来,其实activiti已经考虑到了 ,所以设计了一个businessKey,这个key就是流程关联业务的核心。

String processKey = "OrderCheck";
String businessTable = FtCustomerRecordOrder.class.getSimpleName();
//设置下一个任务办理人,也就是预约流程的办理人就是当前登录用户
Map<String,Object> vars = new HashMap<String, Object>();
vars.put("openUser", lud.getUid());
vars.put("checkType", 0);
String ObjId = businessTable + "." + orderNo;
//设置流程变量 让流程关联业务
vars.put("ObjId", ObjId);
//流程实例ID
String processInstanceId = actTaskService.startProcess(processKey, businessTable, orderNo, vars);
@Override
public String startProcess(String processKey,String businessTable,String businessId,Map<String, Object> vars) {
	 processInstanceByKey = 
			runtimeService.startProcessInstanceByKey(processKey,businessTable+"."+businessId,vars);
	//返回流程实例ID
	return processInstanceByKey.getProcessInstanceId();
}

开启流程的时候,我是用订单表实体类名.orderNo订单编号的形式拼接成一个businessKey,这样的话我开启的这个流程实例就跟我的这条orderNo绑定在一起了,等到我需要知道我这个流程实例是属于哪条订单的时候,取出businessKey就知道了

2)提交当前task。提交task的时候需要设置参数,参数包括下一个任务办理人,以及流程变量,判断走哪一条flow

@Override
public void complete(String taskId, Integer uid, String procInsId,String comment, String title, Map<String, Object> vars) {
	if (StringUtils.isNotBlank(procInsId) && StringUtils.isNotBlank(comment)){
		taskService.addComment(taskId, procInsId, comment);
	}
	// 设置流程变量
	if (vars == null){
		vars = new HashMap<String, Object>();
	}
	if(uid != null){
		taskService.setAssignee(taskId, String.valueOf(uid));
	}
		
	// 设置流程标题
	if (StringUtils.isNotBlank(title)){
		vars.put("title", title);
	}
	//taskService.setVariablesLocal(taskId, vars);
	// 提交任务
	taskService.complete(taskId,vars);
}

3)获取当前待办任务总条数

        @Override
	public int todoCount(Activiti act) {
		// TODO Auto-generated method stub
		// =============== 等待签收的任务  ===============
		TaskQuery toClaimQuery = taskService.createTaskQuery()
				.includeProcessVariables().active().orderByTaskCreateTime().desc();
		
		// 设置查询条件
		if (StringUtils.isNotBlank(act.getAssignee())) {
			toClaimQuery.taskAssignee(act.getAssignee());
		}
		if (StringUtils.isNotBlank(act.getTaskName())) {
			toClaimQuery.taskName(act.getTaskName());
		}
		if (StringUtils.isNotBlank(act.getCandidateUser())){
			toClaimQuery.taskCandidateUser(act.getCandidateUser());
		}
		if (StringUtils.isNotBlank(act.getCandidateGroup())){
			toClaimQuery.taskCandidateGroup(act.getCandidateGroup());
		}
		if (StringUtils.isNotBlank(act.getProcDefKey())){
			toClaimQuery.processDefinitionKey(act.getProcDefKey());
		}
		if (StringUtils.isNotBlank(act.getProcDefId())){
			toClaimQuery.processDefinitionId(act.getProcDefId());
		}
		if (act.getBeginDate() != null){
			toClaimQuery.taskCreatedAfter(act.getBeginDate());
		}
		if (act.getEndDate() != null){
			toClaimQuery.taskCreatedBefore(act.getEndDate());
		}
		// 根据流程变量查询
		Map<String,Object> vars = act.getVars();
		if (vars != null){
			for(Map.Entry<String, Object> entry : vars.entrySet()){
				Object v = entry.getValue();
				if(null != v && !v.equals("")){
					toClaimQuery.processVariableValueEquals(
							entry.getKey(), v);
				}
			}
		}
		return (int)toClaimQuery.count();
	}

4)获取当前待办任务分页数据

        @Override
	public List<Activiti> todoList(int firstResult, int maxResults, Activiti act) {
		// TODO Auto-generated method stub
		List<Activiti> result = new ArrayList<Activiti>();
		// =============== 等待签收的任务  ===============
		TaskQuery toClaimQuery = taskService.createTaskQuery()
				.includeProcessVariables().active().orderByTaskCreateTime().desc();
		// 设置查询条件
		if (StringUtils.isNotBlank(act.getAssignee())) {
			toClaimQuery.taskAssignee(act.getAssignee());
		}
		if (StringUtils.isNotBlank(act.getTaskName())) {
			toClaimQuery.taskName(act.getTaskName());
		}
		if (StringUtils.isNotBlank(act.getCandidateUser())){
			toClaimQuery.taskCandidateUser(act.getCandidateUser());
		}
		if (StringUtils.isNotBlank(act.getCandidateGroup())){
			toClaimQuery.taskCandidateGroup(act.getCandidateGroup());
		}
		if (StringUtils.isNotBlank(act.getProcDefKey())){
			toClaimQuery.processDefinitionKey(act.getProcDefKey());
		}
		if (StringUtils.isNotBlank(act.getProcDefId())){
			toClaimQuery.processDefinitionId(act.getProcDefId());
		}
		if (act.getBeginDate() != null){
			toClaimQuery.taskCreatedAfter(act.getBeginDate());
		}
		if (act.getEndDate() != null){
			toClaimQuery.taskCreatedBefore(act.getEndDate());
		}
		// 根据流程变量查询
		Map<String,Object> vars = act.getVars();
		if (vars != null){
			for(Map.Entry<String, Object> entry : vars.entrySet()){
				Object v = entry.getValue();
				if(null != v && !v.equals("")){
					toClaimQuery.processVariableValueEquals(
							entry.getKey(), v);
				}
			}
		}
		// 查询列表
		List<Task> toClaimList = toClaimQuery.listPage(firstResult, maxResults);
		for (Task task : toClaimList) {
			Activiti e = new Activiti();
			e.setTaskId(task.getId());
			e.setTaskName(task.getName());
			e.setProcInsId(task.getProcessInstanceId());
			e.setTaskName(task.getName());
			e.setVars(task.getProcessVariables());
			e.setStatus("claim");
			e.setBeginDate(task.getCreateTime());
			result.add(e);
		}
		return result;
	}

流程结合业务封装数据

        @Override
	public List<FtOrderCheckDetailDto> queryTODOList(Map<String, Object> param) {
		Activiti act = new Activiti();
		if (param.get("role") != null) {
			act.setCandidateGroup(String.valueOf(param.get("role")));
		}
		if (param.get("openUser") != null) {
			act.setAssignee(String.valueOf(param.get("openUser")));
		}
		act.setProcDefKey("OrderCheck");
		act.setTaskName(String.valueOf(param.get("taskName")));
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
		try {
			String startTime = String.valueOf(param.get("startTime"));
			String endTime = String.valueOf(param.get("endTime"));
			if (startTime != "null" || startTime.length() > 0) {
				act.setBeginDate(sf.parse(startTime));
			}
			if (endTime != "null" || endTime.length() > 0) {
				act.setEndDate(sf.parse(endTime));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		int firstResult = (int)param.get("firstResult");
		int maxResults = (int)param.get("pageSize");
		List<Activiti> activitis = actTaskService.todoList(firstResult,maxResults,act);
		List<FtOrderCheckDetailDto> tasks = new ArrayList<FtOrderCheckDetailDto>();
		if (!activitis.isEmpty()) {
			for (Activiti acti : activitis) {
				FtOrderCheckDetailDto task = new FtOrderCheckDetailDto();
				task.setTaskId(acti.getTaskId());
				task.setTaskName(acti.getTaskName());
				task.setProcessInstanceId(acti.getProcInsId());
				task.setStartTime(acti.getBeginDate());
				task.setEndTime(acti.getEndDate());
				
				ProcessInstance pi = runtimeService.createProcessInstanceQuery()
								.processInstanceId(acti.getProcInsId())
								.singleResult();
				//获取business_key 获取orderNo
				String businessKey = pi.getBusinessKey();
				if (StringUtils.isNotBlank(businessKey)) {
					//截取字符串,查询投资记录表信息
					int index = businessKey.indexOf(".");
					String orderNo = businessKey.substring(index+1);
					task.setOrderNo(orderNo);
					FtCustomerRecordOrder order = 
							customerRecordOrderMapper.queryByOrderNo(orderNo);
					if (order != null) {
						task.setCustomerId(order.getCustomerId());
						task.setOrderRemark(order.getRemark());
						FtMembers members = membersMapper.getMembersByUid(order.getUid());
						FtCustomer customer = customerMapper.selectFtCustomerByCustomerId(order.getCustomerId());
						FtProductMaster productMaster = 
								productMasterMapper.queryByProductCode(order.getProductCode());
						FtProductEarningsRule productEarningsRule = 
								productEarningsRuleMapper.selectByPrimaryKey(order.getProductEarningsRuleId());
						FtProductSeparateDetail productSeparateDetail 
								= productSeparateDetailMapper.selectByPrimaryKey(order.getProductSeparateId());
						task.setApplyAt(order.getCreateTime());
						task.setInvestmentAmount(order.getInvestmentAmount());
						task.setActualAmount(order.getActualAmount());
						task.setCheckStatus(order.getCheckStatus());
						if (members != null) {
							task.setUserNmae(members.getUserName());
						}
						if (customer != null) {
							task.setCustomerName(customer.getCustomerName());
							
						}
						if (productMaster != null) {
							task.setProductName(productMaster.getProductName());
							task.setProductCode(productMaster.getProductCode());
						}
						if (productEarningsRule != null) {
							task.setPerformanceBenchmark(productEarningsRule.getPerformanceBenchmark());
						}
						Calendar c = Calendar.getInstance();
						if (productSeparateDetail != null) {
							if (productSeparateDetail.getSeparateInterestAt() != null) {
								task.setSeparateInterestAt(productSeparateDetail.getSeparateInterestAt());
								//计算到期时间 =产品成立时间 + 期限
								c.setTime(productSeparateDetail.getSeparateInterestAt());
								c.add(Calendar.MONTH, productMaster.getInvestmentDeadline());
								Date endTime = c.getTime();
								task.setProductEndTime(endTime);
							}
						} 
					}
				}
				tasks.add(task);
			}
		}
		return tasks;
	}

获取待办任务的数据都是用的是runtimeService,如果是获取待办历史那么用的就是historyService

5)获取历史审核任务总数

        @Override
	public int historicCount(Activiti act) {
		HistoricTaskInstanceQuery histTaskQuery = historyService.createHistoricTaskInstanceQuery().finished()
				.includeProcessVariables().orderByHistoricTaskInstanceEndTime().desc();
		// 设置查询条件
		if (StringUtils.isNotBlank(act.getTaskName())) {
			histTaskQuery.taskName(act.getTaskName());
		}
		if(StringUtils.isNotBlank(act.getAssignee())){
			histTaskQuery.taskAssignee(act.getAssignee());
		}
		if (StringUtils.isNotBlank(act.getProcDefKey())){
			histTaskQuery.processDefinitionKey(act.getProcDefKey());
		}
		if (StringUtils.isNotBlank(act.getProcDefId())){
			histTaskQuery.processDefinitionId(act.getProcDefId());
		}
		if (act.getBeginDate() != null){
			histTaskQuery.taskCompletedAfter(act.getBeginDate());
		}
		if (act.getEndDate() != null){
			histTaskQuery.taskCompletedBefore(act.getEndDate());
		}
		// 根据流程变量查询
		Map<String,Object> vars = act.getVars();
		if (vars != null){
			for(Map.Entry<String, Object> entry : vars.entrySet()){
				Object v = entry.getValue();
				if(null != v && !v.equals("")){
					histTaskQuery.processVariableValueEquals(
							entry.getKey(), v);
				}
			}
		}
		return (int) histTaskQuery.count();
	}

6)获取历史审核任务分页数据

        @Override
	public List<Activiti> historicList(int firstResult, int maxResults,
			Activiti act) {
		HistoricTaskInstanceQuery histTaskQuery = historyService.createHistoricTaskInstanceQuery().finished()
				.includeProcessVariables().includeTaskLocalVariables().orderByHistoricTaskInstanceEndTime().desc();
		// 设置查询条件
		if (StringUtils.isNotBlank(act.getTaskName())) {
			histTaskQuery.taskName(act.getTaskName());
		}
		if(StringUtils.isNotBlank(act.getAssignee())){
			histTaskQuery.taskAssignee(act.getAssignee());
		}
		if(StringUtils.isNotBlank(act.getProcInsId())){
			histTaskQuery.processInstanceId(act.getProcInsId());
		}
		if (StringUtils.isNotBlank(act.getProcDefKey())){
			histTaskQuery.processDefinitionKey(act.getProcDefKey());
		}
		if (StringUtils.isNotBlank(act.getProcDefId())){
			histTaskQuery.processDefinitionId(act.getProcDefId());
		}
		if (act.getBeginDate() != null){
			histTaskQuery.taskCompletedAfter(act.getBeginDate());
		}
		if (act.getEndDate() != null){
			histTaskQuery.taskCompletedBefore(act.getEndDate());
		}
		// 根据流程变量查询
		Map<String,Object> vars = act.getVars();
		if (vars != null){
			for(Map.Entry<String, Object> entry : vars.entrySet()){
				Object v = entry.getValue();
				if(null != v && !v.equals("")){
					histTaskQuery.processVariableValueEquals(
							entry.getKey(), v);
				}
			}
		}
		// 查询列表
		List<HistoricTaskInstance> histList = histTaskQuery.listPage(firstResult, maxResults);
		//处理分页问题
		List<Activiti> actList = new ArrayList<Activiti>();
		for (HistoricTaskInstance histTask : histList) {
			Activiti e = new Activiti();
			e.setTaskId(histTask.getId());
			e.setTaskName(histTask.getName());
			e.setAssignee(histTask.getAssignee());
			e.setProcInsId(histTask.getProcessInstanceId());
			e.setStatus("finish");
			e.setBeginDate(histTask.getStartTime());
			e.setEndDate(histTask.getEndTime());
			
			// 审批批注
			List<Comment> comment = taskService.getTaskComments(histTask.getId());
			if(!comment.isEmpty()){
				e.setComment(comment.get(0).getFullMessage());
			}
			
			// 流程变量
			e.setVars(histTask.getProcessVariables());
			
			// 任务变量
			List<HistoricVariableInstance> taskVars = historyService
					.createHistoricVariableInstanceQuery().taskId(histTask.getId()).list();
			Map<String,Object> mTaskVars = new HashMap<String, Object>();
			for(HistoricVariableInstance var : taskVars){
				mTaskVars.put(var.getVariableName(), var.getValue());
			}
			e.setTaskVars(mTaskVars);
			
			actList.add(e);
		}
		return actList;
	}

流程集合业务查询分页数据

        @Override
	public List<FtOrderCheckDetailDto> queryHistoryList(
			Map<String, Object> param) {
		Activiti act = new Activiti();
		act.setAssignee(String.valueOf(param.get("uid")));
		act.setProcDefKey("OrderCheck");
		act.setTaskName(String.valueOf(param.get("taskName")));
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
		try {
			String startTime = String.valueOf(param.get("startTime"));
			String endTime = String.valueOf(param.get("endTime"));
			if (startTime != "null" || startTime.length() > 0) {
				act.setBeginDate(sf.parse(startTime));
			}
			if (endTime != "null" || endTime.length() > 0) {
				act.setEndDate(sf.parse(endTime));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		int firstResult = (int)param.get("firstResult");
		int maxResults = (int)param.get("pageSize");
		List<Activiti> activitis = actTaskService.historicList(firstResult,maxResults,act);
		List<FtOrderCheckDetailDto> tasks = new ArrayList<FtOrderCheckDetailDto>();
		if (!activitis.isEmpty()) {
			for (Activiti acti : activitis) {
				FtOrderCheckDetailDto task = new FtOrderCheckDetailDto();
				task.setTaskId(acti.getTaskId());
				task.setTaskName(acti.getTaskName());
				task.setProcessInstanceId(acti.getProcInsId());
				task.setStartTime(acti.getBeginDate());
				task.setEndTime(acti.getEndDate());
				
				FtOrderCheckDetail result = mapper.queryByTaskId(acti.getTaskId());
				if (result != null) {
					task.setType(result.getType());
					task.setHandler(result.getHandler());
					task.setRemark(result.getRemark());
					task.setDisposeAt(result.getDisposeAt());
				}
				ProcessInstanceHistoryLog pi = historyService
						.createProcessInstanceHistoryLogQuery(acti.getProcInsId())
						.singleResult();
				/*ProcessInstance pi = runtimeService.createProcessInstanceQuery()
								.processInstanceId(acti.getProcInsId())
								.singleResult();*/
				//获取business_key
				if (pi != null) {
					String businessKey = pi.getBusinessKey();
					if (StringUtils.isNotBlank(businessKey)) {
						//截取字符串,查询投资记录表信息
						int index = businessKey.indexOf(".");
						String orderNo = businessKey.substring(index+1);
						task.setOrderNo(orderNo);
						FtCustomerRecordOrder order = 
								customerRecordOrderMapper.queryHistoryByOrderNo(orderNo);
						if (order != null) {
							FtMembers members = membersMapper.getMembersByUid(order.getUid());
							FtProductMaster productMaster = 
									productMasterMapper.queryHistoryByProductCode(order.getProductCode());
							task.setCustomerId(order.getCustomerId());
							task.setUserNmae(members.getUserName());
							task.setCustomerName("");
							task.setApplyAt(order.getCreateTime());
							task.setProductName(productMaster.getProductName());
							task.setInvestmentAmount(order.getInvestmentAmount());
							task.setActualAmount(order.getActualAmount());
						}
					}
				}
				tasks.add(task);
			}
		}
		return tasks;
	}

以上就是博主学习运用activiti的所有干货,希望能帮助到有需要的童鞋~~

 

 

 

 

 

 

SpringBoot 整合Activiti(二)——流程审批完整示例 前两天做了一个SpringBoot整合Activiti的完整示例,功能包括:退回/通过(节点条件)、指定办理人、生成流程图、高亮显示已办节点、查询任务列表(办理人)等,下面先简单记录(含完整代码),十六上班后再详细补充。1、画流程图:高亮生成的流程图(流程已至办理):这个流程图比较简单,这里不介绍如何画的了(记得让文件名称与id相同),下面有最终的流程图源码。2、设置业户提交、资料不全、已签发的事... 阅读详情

相关推荐

新版本大疆智图4.5 永久许可摄影测量建模软件

大疆智图支持常见格式的成果输出,包括 TIFF 正射影像和高程模型、LAS 格式点云,以及 B3DM、OSGB、OBJ 等六种常用格式的三维模型,还包括 DXF 和 SHP 等格式的等高线。大疆智图 DJI Terra是领先的三维重建软件,提供先进的技术和简单的操作,一站式解决方案,从航线规划到数据的获取,以及模型重建、数据分析等都提供独一无二的支持,优化项目工程,提供自动化优势,获得更有效智能的决策和行动,最终用户可以获得理想的结果,减轻工作压力,提高作业效率。质量报告和剖面查看功能有助于分析点云质量。

qq_62821232的博客 6896

工作流引擎选择(为何使用activiti而不是jbpm)

SuccezBI之前在选择工作流引擎时曾经在activiti和jbpm之间有过比较,当时做出的决定是使用jbpm,但实际开发过程中发现这个选择是不合适的。目前我们改为选择Activiti作为工作流模块的引擎,理由如下: 1,Activiti拥有更简洁健壮的接口 JBPM自从版本五后,便重启炉灶,完全抛弃了JBMP4的代码基础,重新基于drools进行了实现。JBPM5,JBPM6似乎缺

ClassFoo的专栏 3万+

Android双目摄像头(RGB+IR)实时预览与人脸活体检测实战指南

本文详细介绍了Android双目摄像头(RGB+IR)实时预览与人脸活体检测的实战指南。通过双摄同步预览、人脸检测与活体判断等技术实现,提升安全认证的准确性和鲁棒性。文章还提供了开发环境搭建、常见问题解决方案及性能优化建议,帮助开发者快速掌握双目摄像头在Android平台的应用。

vulkan6gpu的博客 691

Spring和Activiti工作流整合详解

Spring和Activiti工作流整合详解 一、概述 Activiti作为一个流行的开源工作流引擎,正在不断发展,其6.0版本以API形式提供服务,而之前版本基本都是要求我们的应用以JDK方式与其交互,只能将其携带到我们的应用中,而API方式则可以服务器独立运行方式,能够形成一个专网内工作流引擎资源共享的方式。 本篇activiti工作流基于5.17.0。 首发地址: 品茗IT-同步发布 品茗I...

feiyangtianyao的专栏 9153

ESP32锂电池电量检测实战:从引脚选择到低功耗优化(附完整电路图)

本文详细介绍了ESP32锂电池电量检测的实战方案,从ADC引脚选择到低功耗优化,提供完整的电路图和代码实现。通过MOS管智能开关和深度睡眠技术,显著降低静态功耗至0.5μA,提升设备续航能力。适合物联网开发者解决电量检测中的常见问题。

weixin_28731223的博客 462

手把手教你用RV1103+SC3336摄像头DIY一个离线人脸门禁原型

本文详细介绍了如何利用RV1103芯片和SC3336摄像头构建离线人脸门禁系统。从硬件选型到算法优化,再到业务逻辑实现,提供了完整的DIY指南。重点讲解了RetinaFace和FaceNet算法在嵌入式系统中的移植与调优,帮助开发者快速实现高效、隐私安全的门禁解决方案。

weixin_26905487的博客 509

Spring Boot + Activiti 完美结合,快速实现工作流~

Activiti是一个工作流引擎,Activiti可以将业务系统中复杂的业务流程抽取出来,使用专门的建模语言BPMN2.0进行定义,业务流程按照预先定义的流程进行执行,实现了系统的流程由Activiti进行管理,减少业务系统由于流程变更进行系统升级改造的工作量,从而提高系统的健壮性,同时也减少了系统开发维护成本。在使用activiti之前,首先需要编写配置文件。并且引入相关依赖。

m0_71777195的博客 9047

基于ST32 DAC7311数模转换器驱动代码及电路设计完整版

基于ST32的DAC7311模数转换器的电路设计及驱动代码完整版

qq_39626643的博客 3720

工作流Activiti的学习总结(四)Spring和Activiti的整合配置讲解

Spring和Activiti的整合: 在Spring和Activiti的整合中ProcessEngineFactoryBean成为了两者的整合点。ProcessEngineFactoryBean为org.activiti.spring.ProcessEngineFactoryBean。提供了ProcessEngine的配置和创建的功能。&lt;bean id="processEngineCon...

topMan'blog 368

u-boot-2014.10移植第22天----添加nand flash命令支持(四)

解决问题:nand0: MTD Erase failure: -5 drivers/mtd/nand/nand_bbt.c文件中初始化bbt/* * Allocate memory (2bit per block) and clear the memory bad block * table. */ this->bbt = kzalloc(len, GFP_

fulinux的博客 3632

华为OD技术面八股文_C++_01

汇总华为OD技术面C++方向八股文真题,并提供详细解答。

qq_45776114的博客 1887

spring boot 整合Activiti工作流学习笔记

一、了解工作流 刚开始接触的是工作流关于请假和审批的一些自动化流程。这里记录下以后复习备用。 工作流(Workflow),就是“业务过程的部分或整体在计算机应用环境下的自动化”,它主要解决的是“使在多个参与者之间按照某种预定义的规则传递文档、信息或任务的过程自动进行,从而实现某个预期的业务目标,或者促使此目标的实现”。 工作流管理系统(Workflow Management System, WfMS)是一个软件系统,它完成工作量的定义和管理,并按照在系统中预先定义好的工作流逻辑进行工作流实例的执行。工作流管

Wyangcsdb的博客 529

【Cesium开发实战】解决加载白膜数据位置不合适问题(地底或浮空)

解决白膜位置地底或者浮空问题。

莫言情怼的博客 569

工作流Activiti的学习总结(一)Spring和Activiti的整合配置讲解

Spring和Activiti的整合: 在Spring和Activiti的整合中ProcessEngineFactoryBean成为了两者的整合点。ProcessEngineFactoryBean为org.activiti.spring.ProcessEngineFactoryBean。提供了ProcessEngine的配置和创建的功能。 id="processEngineConfigurat

三人行,必有我师焉。 3504

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Activiti5工作流框架学习之Struts2+Hibernate+Spring整合配置

测试环境WindowsSTSMysql5Jdk1.8Tomcat8 Maven3Struts2 + Spring4 + Hibernate3 + Activiti5.17一、整合Spring与Hibernate3配置DataSourceapplication-config.xml内容:<!-- 加载数据库配置文件 --> <context:property-placeholder location=

一大三千的博客 4931

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

手把手教你如何玩转Activiti工作流

https://blog.youkuaiyun.com/cs_hnu_scw/article/details/79059965 https://blog.youkuaiyun.com/qq_38844326/article/details/80112950 Activiti学习之spring boot 与activiti整合 https://blog.youkuaiyun.com/chq1988/article/d...

程序员杂谈 470

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

工作流Activiti的学习总结- 整合spring mvc

新建一个测试类 @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:config/app-dao.xml" }) public class TestLeave { @Autowired @Qualifier("userRepository") UserRepositor

1262

工作流学习日志-(Activiti7与spring、SpringBoot整合)

工作流学习日志-(spring、springboot整合) 文章目录工作流学习日志-(spring、springboot整合)前言一、工作流Activiti7与spring整合1. 依赖注入2. 整合配置文件3. 测试代码二、使用步骤1.引入库2.读入数据总结 前言 开发OA人力资源管理系统时在人员调动时、请假审批等需要使用到工作流,以此作为学习契机。 一、工作流Activiti7与spring整合 1. 依赖注入 与spring整合时的pom.xml文件依赖。 <?xml version="1.0

weixin_46621774的博客 510

Activiti工作流框架学习六:与Spring框架整合

&amp;amp;amp;amp;amp;amp;amp;lt;!-- applicationContext.xml --&amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;lt;beans xmlns=&amp;amp;amp;amp;amp;amp;quot;http://www.springframework.org/schema/beans&amp;amp;amp;amp;amp;amp;

张育嘉的博客 985

工作流Activiti的学习总结(十一)Activiti5.6和Spring3.03整合

工作流模拟程序员面试过程情景如下:       1.开发知识面试或者笔试       2.人事面试   流程图:     流程配置: Xml代码   xml version="1.0" encoding="UTF-8"?>   definitions xmlns="http://www.omg.org/spec/BPMN/20100524

qq_31387691的博客 1173

学习笔记之-Activiti7工作流引擎,概述,环境搭建,类关系图,使用Activiti BPMN visualizer,流程变量,组任务 网关,Activiti整合Spring SpringBoot

Activiti7 1.1工作流介绍 工作流(Workflow),就是通过计算机对业务流程自动化执行管理。它主要解决的是“使在多个参与者 之间按照某种预定义的规则自动进行传递文档、信息或任务的过程,从而实现某个预期的业务目标, 或者促使此目标的实现。 2.1Activiti 介绍 BPM 介绍 Alfresco 软件在 2010 年 5 月 17 日宣布 Activiti 业务流程管理(BPM)开源项目的正式启动,其 首席架构师由业务流程管理 BPM 的专家 Tom Baeyens 担任,Tom Baeye

fushuai优快云的博客 4836

工作流Activiti的学习总结<转>

工作流Activiti的学习总结(一)安装条件以及各步骤的作用以及不同环境需要lib包 [url]http://topmanopensource.iteye.com/blog/1313865[/url] 工作流Activiti的学习总结(二)activiti中ProcessEngine的创建和数据库表命名规则 [url]http://topmanopensource.iteye.com/...

pyzheng的专栏 333
上一篇: mysql存储过程+游标循环遍历 判断 赋值 等实例二
下一篇: java实现PDF转图片
Ice166
博客等级 码龄9年 151粉丝 22原创
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值