Activiti结合Spring自动部署流程资源

Activiti 整合spring的时候,提供了一个自动部署的特性:


  ...
  


这样当每次启动web容器的时候就会把指定路径的流程资源文件部署到Activiti DB上。不过这样会产生一个问题,资源文件在没经过任何改动的情况下,特别是我们在做Testing的时候,还是会重新部署一个新的版本到DB上,这样会造成不别要的重复部署。我们在部署之前,应该先判断资源文件是否有改动过,如果有,才部署新版本到DB上。

实现这个功能很简单,只需要建立一个实现了 InitializingBean 接口的 spring bean,在afterPropertiesSet()方法里面进行判断和部署就可以了。

/**
 * 
 */
package com.highcolu.dms.workflow;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

import org.activiti.engine.ActivitiException;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.FatalBeanException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.io.Resource;

/**
 * @Description:结合Spring自动部署Activit流程定义文件
 * @version:2012-12-20
 * @author: 周文滔
 */
public class WorkflowDeployer implements InitializingBean,
		ApplicationContextAware {

	private static final Log LOGGER = LogFactory.getLog(WorkflowDeployer.class);
	private Resource[] deploymentResources;
	private String category;
	ApplicationContext appCtx;

	public void setDeploymentResources(Resource[] resources) {
		this.deploymentResources = resources;
	}

	public void setCategory(String category) {
		this.category = category;
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext)
			throws BeansException {
		this.appCtx = applicationContext;
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		if (category == null) {
			throw new FatalBeanException("缺失属性 : category");
		}
		if (deploymentResources != null) {
			RepositoryService repositoryService = appCtx
					.getBean(RepositoryService.class);
			for (Resource r : deploymentResources) {
				String deploymentName = category + "_" + r.getFilename();
				String resourceName = r.getFilename();
				boolean doDeploy = true;
				List deployments = repositoryService
						.createDeploymentQuery().deploymentName(deploymentName)
						.orderByDeploymenTime().desc().list();
				if (!deployments.isEmpty()) {
					Deployment existing = deployments.get(0);
					try {
						InputStream in = repositoryService.getResourceAsStream(
								existing.getId(), resourceName);
						if (in != null) {
							File f = File.createTempFile(
									"deployment",
									"xml",
									new File(System
											.getProperty("java.io.tmpdir")));
							f.deleteOnExit();
							OutputStream out = new FileOutputStream(f);
							IOUtils.copy(in, out);
							in.close();
							out.close();
							doDeploy = (FileUtils.checksumCRC32(f) != FileUtils
									.checksumCRC32(r.getFile()));
						} else
							throw new ActivitiException("不能读取资源 "
									+ resourceName + ", 输入流为空");
					} catch (ActivitiException ex) {
						LOGGER.error("Unable to read " + resourceName
								+ " of deployment " + existing.getName()
								+ ", id: " + existing.getId()
								+ ", will re-deploy");
					}
				}
				if (doDeploy) {
					repositoryService.createDeployment().name(deploymentName)
							.addInputStream(resourceName, r.getInputStream())
							.deploy();
					LOGGER.warn("文件部署成功 : " + r.getFilename());
				}
			}
		}
	}

}

然后在spring的配置文件里面配置好这个bean就可以了.

	
		
		
	

 

你可能感兴趣的:(activiti)