package com.artfess.activiti.cache; import com.artfess.base.cache.annotation.CacheEvict; import com.artfess.base.cache.annotation.CachePut; import com.artfess.base.cache.annotation.Cacheable; import com.artfess.base.constants.CacheKeyConst; import com.artfess.base.exception.WorkFlowException; import com.artfess.base.util.AppUtil; import com.artfess.base.util.ContextThread; import com.artfess.base.util.FileUtil; import org.activiti.engine.impl.persistence.deploy.DeploymentCache; import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity; import org.apache.commons.lang.exception.ExceptionUtils; import java.util.HashMap; import java.util.Map; /** * 流程引擎的自定义缓存接口,可以配置到activiti的配置文件中 * * @author heyifan * @company 阿特菲斯信息技术有限公司 * @email heyf@jee-soft.cn * @date 2020年6月17日 */ public class ActivitiDefCache implements DeploymentCache, ContextThread { @Override public ProcessDefinitionEntity get(String id) { //首先从线程变量中获取 ProcessDefinitionEntity p = getThreadLocalDef(id); if (p == null) { ActivitiDefCache bean = AppUtil.getBean(getClass()); // 获取缓存数据时,必须通过Spring容器中获取到的bean来调用(否则缓存方法上的注解不会生效),而且缓存方法只能是protected后public方法 ProcessDefinitionEntity ent = bean.getFromCache(id); if (ent == null) { return null; } setThreadLocalDef(ent); p = getThreadLocalDef(id); } return p; } @Override public void add(String id, ProcessDefinitionEntity object) { ActivitiDefCache bean = AppUtil.getBean(getClass()); // 获取缓存数据时,必须通过Spring容器中获取到的bean来调用(否则缓存方法上的注解不会生效),而且缓存方法只能是protected后public方法 bean.putInCache(id, object); setThreadLocalDef(object); } @Cacheable(value = CacheKeyConst.EIP_BPM_PROCESS_ENTITY, key = "#id", ignoreException = false) public ProcessDefinitionEntity getFromCache(String id) { return null; } @CachePut(value = CacheKeyConst.EIP_BPM_PROCESS_ENTITY, key = "#id", ignoreException = false) public ProcessDefinitionEntity putInCache(String id, ProcessDefinitionEntity object) { return object; } @Override @CacheEvict(value = CacheKeyConst.EIP_BPM_PROCESS_ENTITY, key = "#id", ignoreException = false) public void remove(String id) { clearProcessDefinitionEntity(id); } @Override @CacheEvict(value = CacheKeyConst.EIP_BPM_PROCESS_ENTITY, allEntries = true, ignoreException = false) public void clear() { clearProcessCache(); } public void cleanAll() { clearProcessCache(); } private ThreadLocal> processDefinitionCacheLocal = new ThreadLocal>(); private void clearProcessDefinitionEntity(String defId) { processDefinitionCacheLocal.remove(); } private void clearProcessCache() { processDefinitionCacheLocal.remove(); } /** * 把传入的对象克隆一份,放入线程变量中。驳回/指定节点跳转会用到 * * @param process */ private void setThreadLocalDef(ProcessDefinitionEntity process) { ProcessDefinitionEntity cloneEnt = null; try { //克隆流程定义。 cloneEnt = (ProcessDefinitionEntity) FileUtil.cloneObject(process); } catch (Exception e) { throw new WorkFlowException(ExceptionUtils.getRootCauseMessage(e)); } if (processDefinitionCacheLocal.get() == null) { Map map = new HashMap(); map.put(cloneEnt.getId(), cloneEnt); processDefinitionCacheLocal.set(map); } else { Map map = processDefinitionCacheLocal.get(); map.put(cloneEnt.getId(), cloneEnt); } } private ProcessDefinitionEntity getThreadLocalDef(String processDefinitionId) { if (processDefinitionCacheLocal.get() == null) { return null; } Map map = processDefinitionCacheLocal.get(); if (!map.containsKey(processDefinitionId)) { return null; } return map.get(processDefinitionId); } }