1.概述
Activiti5.x在流程发起和审批过程中,都需要通过流程定义的XML进行,但是这份XML较大,如果每次都从数据库中获取,性能较差。所以Activiti添加了缓存的机制来缓存这份XML,但是其默认实现为LinkedHashMap
:
/**
* Default cache: keep everything in memory, unless a limit is set.
*
* @author Joram Barrez
*/
public class DefaultDeploymentCache<T> implements DeploymentCache<T> {
private static final Logger logger = LoggerFactory.getLogger(DefaultDeploymentCache.class);
protected Map<String, T> cache;
/** Cache with no limit */
public DefaultDeploymentCache() {
this(-1);
}
/** Cache which has a hard limit: no more elements will be cached than the limit. */
public DefaultDeploymentCache(final int limit) {
if (limit > 0) {
this.cache = Collections.synchronizedMap(new LinkedHashMap<String, T>(limit + 1, 0.75f, true) {
// +1 is needed, because the entry is inserted first, before it is removed
// 0.75 is the default (see javadocs)
// true will keep the 'access-order', which is needed to have a real LRU cache
private static final long serialVersionUID = 1L;
protected boolean removeEldestEntry(Map.Entry<String, T> eldest) {
boolean removeEldest = size() > limit;
if (removeEldest) {
logger.trace("Cache limit is reached, {} will be evicted", eldest.getKey());
}
return removeEldest;
}
});
} else {
this.cache = Collections.synchronizedMap(new HashMap<String, T>());
}
}
public T get(String id) {
return cache.get(id);
}
public void add(String id, T obj) {
cache.put(id, obj);
}
public void remove(String id) {
cache.remove(id);
}
public void clear() {
cache.clear();
}
// For testing purposes only
public int size() {
return cache.size();
}
}
接下来我们要将这个默认实现更换为Redis以支持activiti的集群部署。
2.添加DeploymentCache接口的实现类
/**
* 流程引擎的自定义缓存接口,可以配置到activiti的配置文件中。
* 支持集群部署,如果集群部署的情况可以使用到memcached、redis等作为缓存的实现。
*
* @company 广州宏天软件股份有限公司
* @author heyifan
* @email heyf@jee-soft.cn
* @date 2017年6月20日
*/
public class ActivitiDefCache implements DeploymentCache<ProcessDefinitionEntity> {
@Resource
ICache<ProcessDefinitionEntity> iCache;
private ThreadLocal<Map<String,ProcessDefinitionEntity>> processDefinitionCacheLocal = new ThreadLocal<Map<String,ProcessDefinitionEntity>>();
/**
* 清除线程变量缓存,这个在每次请求前进行调用。
*/
public static void clearLocal(){
ActivitiDefCache cache=(ActivitiDefCache)AppUtil.getBean(ActivitiDefCache.class);
cache.clearProcessCache();
}
/**
* 根据流程定义ID清除缓存,这个在流程定义xml发生变更时进行调用。
* @param actDefId
*/
public static void clearByDefId(String actDefId<