由于需要提升Activiti7性能,所有需要将Activiti的默认缓存更换为Redis,但由于Activiti中的缓存对象ProcessDefinitionCacheEntity中的BpmnModel没有实现序列化,更重要的一点是ProcessDefinitionCacheEntity有有参的构造函数没有无参的构造函数。Redis对对象的操序列化和反序列化又极为严格。你又不想改源码?那只好兼容序列化和反序列化的方式。当然Jackson和Gson也支持,有的需要在原来的类上打注解。有的需要重新用有参构造函数生成instance。
网上查了很多资料没有很合适的解决方案。推荐使用Kyro去做序列化,在它的基础上做扩展还是比较哇塞的,代码更优雅。基本思路就是通过反射来去搞定无参构造函数实例。
package com.octopus.test;
import com.esotericsoftware.kryo.Kryo;
import sun.reflect.ReflectionFactory;
import java.lang.reflect.Constructor;
import java.util.concurrent.ConcurrentHashMap;
public class Kryox extends Kryo {
private final ReflectionFactory REFLECTION_FACTORY = ReflectionFactory.getReflectionFactory();
private final ConcurrentHashMap<Class<?>, Constructor<?>> _constructors = new ConcurrentHashMap<Class<?>, Constructor<?>>();
@Override
public <T> T newInstance(Class<T> type) {
try {
return super.newInstance(type);
} catch (Exception e) {
return (T) newInstanceFromReflectionFactory(type);
}
}
@SuppressWarnings("unchecked")
public <T> T newInstanceFromReflectionFactory(Class<T> type) {
Constructor<?> constructor = _constructors.get(type);
if (constructor == null) {
constructor = newConstructorForSerialization(type);
Constructor<?> saved = _constructors.putIfAbsent(type, constructor);
if (saved != null)
constructor = saved;
}
return (T) newInstanceFrom(constructor);
}
private Object newInstanceFrom(Constructor<?> constructor) {
try {
return constructor.newInstance();
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
private <T> Constructor<?> newConstructorForSerialization(Class<T> type) {
try {
Constructor<?> constructor = REFLECTION_FACTORY.newConstructorForSerialization(type, Object.class.getDeclaredConstructor());
constructor.setAccessible(true);
return constructor;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
Activiti性能与容量优化的一些思路:
今天母亲节,想到初中语文老师教我们的诗句:没有太阳,花朵不会开放;没有爱便没有幸福;没有妇女也没有爱,没有母亲,既不会有诗人,也不会有英雄。