我在我们的一个项目中使用Redis
。虽然我意识到redis需要序列化对象才能持久化,但我想了解如何处理一些引用外部库类的类{{1 }}就我而言,它没有实现(StandardServletEnvironment)
并且我们也不能对其进行修改?在这些情况下,我得到serializable
。
序列化外部库
•
问答
wutian000523 回答:序列化外部库
如果要在Redis中存储用户定义的Java对象,则序列化是合适的选项。但是,当您使用Java本机序列化时,它会带来一些缺点,就像您遇到的一样,而且它太慢了。我也遇到了同样的问题,经过长时间的搜索,我想到了使用kryo serialization的解决方案。Kryo不需要序列化实现,并且比Java本机序列化还快。
P.S:如果您不想使用kryo并使用Java内置的序列化,请创建可序列化的类,并将您的对象传递给该类并进行处理。
我希望这会对您有所帮助。
,正如Praga所述,kyro是对未实现Serializable接口的对象进行(反序列化)的一个很好的解决方案。这是使用kyro进行序列化的示例代码,希望对您有所帮助:
Kryo kryo = new Kryo();
private byte[] encode(Object obj) {
ByteArrayOutputStream objStream = new ByteArrayOutputStream();
Output objOutput = new Output(objStream);
kryo.writeClassAndObject(objOutput,obj);
objOutput.close();
return objStream.toByteArray();
}
private <T> T decode(byte[] bytes) {
return (T) kryo.readClassAndObject(new Input(bytes));
}
Maven依赖项:
<dependency>
<groupId>com.esotericsoftware</groupId>
<artifactId>kryo</artifactId>
<version>4.0.1</version>
</dependency>
Redis集成的完整实现:
RedisInterface :
public class RedisInterface {
static final Logger logger = LoggerFactory.getLogger(RedisInterface.class);
private static RedisInterface instance =null;
public static RedisInterface getInstance ()
{
if(instance ==null)
createInstance();
return instance ;
}
private static synchronized void createInstance()
{
if(instance ==null)//in case of multi thread instances
instance =new RedisInterface();
}
JedisConfig jedis = new JedisConfig();
public boolean setAttribute(String key,Object value)
{
return this.setAttribute(key,key,value);
}
public boolean setAttribute(String key,Object value,int expireSeconds)
{
return this.setAttribute(key,value,expireSeconds);
}
public boolean setAttribute(String key,String field,Object value)
{
int expireSeconds = 20 *60; //20 minutes
return this.setAttribute(key,field,int expireSeconds)
{
try
{
if(key==null || "".equals(key) || field==null || "".equals(field))
return false;
byte[]keyBytes = key.getBytes();
byte[]fieldBytes = field.getBytes();
byte []valueBytes = encode(value);
long start = new Date().getTime();
jedis.set(keyBytes,fieldBytes,valueBytes,expireSeconds);
long end = new Date().getTime();
long waitTime =end-start;
logger.info("{} key saved to redis in {} milliseconds with timeout: {} seconds",new Object[] {key,waitTime,expireSeconds} );
return true;
}
catch(Exception e)
{
logger.error( "error on saving object to redis. key: " + key,e);
return false;
}
}
public <T> T getAttribute(String key)
{
return this.getAttribute(key,key);
}
public <T> T getAttribute(String key,String field)
{
try
{
if(key==null || "".equals(key) || field==null || "".equals(field)) return null;
byte[]keyBytes = key.getBytes();
byte[]fieldBytes = field.getBytes();
long start = new Date().getTime();
byte[] valueBytes = jedis.get(keyBytes,fieldBytes);
T o =null;
if(valueBytes!=null && valueBytes.length>0)
o = decode(valueBytes);
long end = new Date().getTime();
long waitTime =end-start;
logger.info("{} key read operation from redis in {} milliseconds. key found?: {}",(o!=null)});
return o;
}
catch (Exception e)
{
logger.error( "error on getting object from redis. key: "+ key,e);
return null;
}
}
Kryo kryo = new Kryo();
private byte[] encode(Object obj) {
ByteArrayOutputStream objStream = new ByteArrayOutputStream();
Output objOutput = new Output(objStream);
kryo.writeClassAndObject(objOutput,obj);
objOutput.close();
return objStream.toByteArray();
}
private <T> T decode(byte[] bytes) {
return (T) kryo.readClassAndObject(new Input(bytes));
}
}
JedisConfig :
public class JedisConfig implements Closeable
{
private Pool<Jedis> jedisPool = null;
private synchronized void initializePool()
{
if(jedisPool!=null) return;
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxTotal(Integer.parseInt(Config.REDIS_MAX_ACTIVE_CONN)); // maximum active connections
poolConfig.setMaxIdle(Integer.parseInt(Config.REDIS_MAX_IDLE_CONN)); // maximum idle connections
poolConfig.setMaxWaitMillis(Long.parseLong(Config.REDIS_MAX_WAIT_MILLIS)); // max wait time for new connection (before throwing an exception)
if("true".equals(Config.REDIS_SENTINEL_ACTIVE))
{
String [] sentinelsArray = Config.REDIS_SENTINEL_HOST_LIST.split(",");
Set<String> sentinels = new HashSet();
for(String sentinel : sentinelsArray)
{
sentinels.add(sentinel);
}
String masterName = Config.REDIS_SENTINEL_MASTER_NAME;
jedisPool = new JedisSentinelPool(masterName,sentinels,poolConfig,Integer.parseInt(Config.REDIS_CONN_TIMEOUT));
}
else
{
jedisPool = new JedisPool(poolConfig,Config.REDIS_IP,Integer.parseInt(Config.REDIS_PORT),Integer.parseInt(Config.REDIS_CONN_TIMEOUT));
}
}
protected Jedis getJedis()
{
if(jedisPool==null)
initializePool();
Jedis jedis = jedisPool.getResource();
return jedis;
}
public Long set(final byte[] key,final byte[] field,final byte[] value,int expireSeconds)
{
Jedis redis = null;
Long ret =0L;
try
{
redis = getJedis();
ret = redis.hset(key,value);
redis.expire(key,expireSeconds);
}
finally
{
if(redis!=null)
redis.close();
}
return ret;
}
public byte[] get(final byte[] key,final byte[] field) {
Jedis redis = null ;
byte[] valueBytes = null;
try
{
redis = getJedis();
valueBytes = redis.hget(key,field);
}
finally
{
if(redis!=null)
redis.close();
}
return valueBytes;
}
@Override
public void close() throws IOException {
if(jedisPool!=null)
jedisPool.close();
}
}