Allow usage of RedisTemplate without serialization
DATAREDIS-227 Add "enableDefaultSerializer" property on RedisTemplate. If false, serializers can be null and no serialization will be performed if they are.
This commit is contained in:
@@ -91,7 +91,8 @@ class RedisCache implements Cache {
|
||||
public ValueWrapper doInRedis(RedisConnection connection) throws DataAccessException {
|
||||
waitForLock(connection);
|
||||
byte[] bs = connection.get(computeKey(key));
|
||||
return (bs == null ? null : new SimpleValueWrapper(template.getValueSerializer().deserialize(bs)));
|
||||
Object value = template.getValueSerializer() != null ? template.getValueSerializer().deserialize(bs) : bs;
|
||||
return (bs == null ? null : new SimpleValueWrapper(value));
|
||||
}
|
||||
}, true);
|
||||
}
|
||||
@@ -104,7 +105,13 @@ class RedisCache implements Cache {
|
||||
public Object doInRedis(RedisConnection connection) throws DataAccessException {
|
||||
waitForLock(connection);
|
||||
connection.multi();
|
||||
connection.set(k, template.getValueSerializer().serialize(value));
|
||||
byte[] v;
|
||||
if(template.getValueSerializer() == null && value instanceof byte[]) {
|
||||
v = (byte[])value;
|
||||
} else {
|
||||
v = template.getValueSerializer().serialize(value);
|
||||
}
|
||||
connection.set(k, v);
|
||||
connection.zAdd(setName, 0, k);
|
||||
|
||||
if (expiration > 0) {
|
||||
@@ -171,6 +178,9 @@ class RedisCache implements Cache {
|
||||
}
|
||||
|
||||
private byte[] computeKey(Object key) {
|
||||
if(template.getKeySerializer() == null && key instanceof byte[]) {
|
||||
return (byte[])key;
|
||||
}
|
||||
byte[] k = template.getKeySerializer().serialize(key);
|
||||
|
||||
if (prefix == null || prefix.length == 0)
|
||||
|
||||
@@ -91,6 +91,9 @@ abstract class AbstractOperations<K, V> {
|
||||
@SuppressWarnings("unchecked")
|
||||
byte[] rawKey(Object key) {
|
||||
Assert.notNull(key, "non null key required");
|
||||
if(keySerializer() == null && key instanceof byte[]) {
|
||||
return (byte[])key;
|
||||
}
|
||||
return keySerializer().serialize(key);
|
||||
}
|
||||
|
||||
@@ -100,17 +103,26 @@ abstract class AbstractOperations<K, V> {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
byte[] rawValue(Object value) {
|
||||
if(valueSerializer() == null && value instanceof byte[]) {
|
||||
return (byte[])value;
|
||||
}
|
||||
return valueSerializer().serialize(value);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
<HK> byte[] rawHashKey(HK hashKey) {
|
||||
Assert.notNull(hashKey, "non null hash key required");
|
||||
if(hashKeySerializer() == null && hashKey instanceof byte[]) {
|
||||
return (byte[])hashKey;
|
||||
}
|
||||
return hashKeySerializer().serialize(hashKey);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
<HV> byte[] rawHashValue(HV value) {
|
||||
if(hashValueSerializer() == null & value instanceof byte[]) {
|
||||
return (byte[])value;
|
||||
}
|
||||
return hashValueSerializer().serialize(value);
|
||||
}
|
||||
|
||||
@@ -145,6 +157,9 @@ abstract class AbstractOperations<K, V> {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Set<V> deserializeValues(Set<byte[]> rawValues) {
|
||||
if(valueSerializer() == null) {
|
||||
return (Set<V>)rawValues;
|
||||
}
|
||||
return SerializationUtils.deserialize(rawValues, valueSerializer());
|
||||
}
|
||||
|
||||
@@ -155,23 +170,36 @@ abstract class AbstractOperations<K, V> {
|
||||
}
|
||||
Set<TypedTuple<V>> set = new LinkedHashSet<TypedTuple<V>>(rawValues.size());
|
||||
for (Tuple rawValue : rawValues) {
|
||||
set.add(new DefaultTypedTuple(valueSerializer().deserialize(rawValue.getValue()), rawValue.getScore()));
|
||||
Object value = rawValue.getValue();
|
||||
if(valueSerializer() != null) {
|
||||
value = valueSerializer().deserialize(rawValue.getValue());
|
||||
}
|
||||
set.add(new DefaultTypedTuple(value, rawValue.getScore()));
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
List<V> deserializeValues(List<byte[]> rawValues) {
|
||||
if(valueSerializer() == null) {
|
||||
return (List<V>)rawValues;
|
||||
}
|
||||
return SerializationUtils.deserialize(rawValues, valueSerializer());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
<T> Set<T> deserializeHashKeys(Set<byte[]> rawKeys) {
|
||||
if(hashKeySerializer() == null) {
|
||||
return (Set<T>)rawKeys;
|
||||
}
|
||||
return SerializationUtils.deserialize(rawKeys, hashKeySerializer());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
<T> List<T> deserializeHashValues(List<byte[]> rawValues) {
|
||||
if(hashValueSerializer() == null) {
|
||||
return (List<T>)rawValues;
|
||||
}
|
||||
return SerializationUtils.deserialize(rawValues, hashValueSerializer());
|
||||
}
|
||||
|
||||
@@ -193,11 +221,17 @@ abstract class AbstractOperations<K, V> {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
K deserializeKey(byte[] value) {
|
||||
if(keySerializer() == null) {
|
||||
return (K) value;
|
||||
}
|
||||
return (K) keySerializer().deserialize(value);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
V deserializeValue(byte[] value) {
|
||||
if(valueSerializer() == null) {
|
||||
return (V)value;
|
||||
}
|
||||
return (V) valueSerializer().deserialize(value);
|
||||
}
|
||||
|
||||
@@ -207,11 +241,17 @@ abstract class AbstractOperations<K, V> {
|
||||
|
||||
@SuppressWarnings( { "unchecked" })
|
||||
<HK> HK deserializeHashKey(byte[] value) {
|
||||
if(hashKeySerializer() == null) {
|
||||
return (HK)value;
|
||||
}
|
||||
return (HK) hashKeySerializer().deserialize(value);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
<HV> HV deserializeHashValue(byte[] value) {
|
||||
if(hashValueSerializer() == null) {
|
||||
return (HV)value;
|
||||
}
|
||||
return (HV) hashValueSerializer().deserialize(value);
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.redis.core;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.springframework.data.redis.core.ZSetOperations.TypedTuple;
|
||||
|
||||
/**
|
||||
@@ -76,7 +78,12 @@ class DefaultTypedTuple<V> implements TypedTuple<V> {
|
||||
if (other.value != null)
|
||||
return false;
|
||||
}
|
||||
else if (!value.equals(other.value))
|
||||
else if(value instanceof byte[]) {
|
||||
if(!(other.value instanceof byte[])) {
|
||||
return false;
|
||||
}
|
||||
return Arrays.equals((byte[])value, (byte[])other.value);
|
||||
} else if (!value.equals(other.value))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -74,6 +74,7 @@ public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperation
|
||||
|
||||
private boolean exposeConnection = false;
|
||||
private boolean initialized = false;
|
||||
private boolean enableDefaultSerializer = true;
|
||||
private RedisSerializer<?> defaultSerializer = new JdkSerializationRedisSerializer();
|
||||
|
||||
private RedisSerializer keySerializer = null;
|
||||
@@ -100,26 +101,26 @@ public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperation
|
||||
super.afterPropertiesSet();
|
||||
boolean defaultUsed = false;
|
||||
|
||||
if (keySerializer == null) {
|
||||
keySerializer = defaultSerializer;
|
||||
defaultUsed = true;
|
||||
}
|
||||
if (valueSerializer == null) {
|
||||
valueSerializer = defaultSerializer;
|
||||
defaultUsed = true;
|
||||
if(enableDefaultSerializer) {
|
||||
if (keySerializer == null) {
|
||||
keySerializer = defaultSerializer;
|
||||
defaultUsed = true;
|
||||
}
|
||||
if (valueSerializer == null) {
|
||||
valueSerializer = defaultSerializer;
|
||||
defaultUsed = true;
|
||||
}
|
||||
if (hashKeySerializer == null) {
|
||||
hashKeySerializer = defaultSerializer;
|
||||
defaultUsed = true;
|
||||
}
|
||||
if (hashValueSerializer == null) {
|
||||
hashValueSerializer = defaultSerializer;
|
||||
defaultUsed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (hashKeySerializer == null) {
|
||||
hashKeySerializer = defaultSerializer;
|
||||
defaultUsed = true;
|
||||
}
|
||||
|
||||
if (hashValueSerializer == null) {
|
||||
hashValueSerializer = defaultSerializer;
|
||||
defaultUsed = true;
|
||||
}
|
||||
|
||||
if (defaultUsed) {
|
||||
if (enableDefaultSerializer && defaultUsed) {
|
||||
Assert.notNull(defaultSerializer, "default serializer null and not all serializers initialized");
|
||||
}
|
||||
|
||||
@@ -311,6 +312,24 @@ public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperation
|
||||
this.exposeConnection = exposeConnection;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Whether or not the default serializer should be used. If not, any serializers not explicilty set
|
||||
* will remain null and values will not be serialized or deserialized.
|
||||
*/
|
||||
public boolean isEnableDefaultSerializer() {
|
||||
return enableDefaultSerializer;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param enableDefaultSerializer Whether or not the default serializer should be used. If not,
|
||||
* any serializers not explicilty set will remain null and values will not be serialized or deserialized.
|
||||
*/
|
||||
public void setEnableDefaultSerializer(boolean enableDefaultSerializer) {
|
||||
this.enableDefaultSerializer = enableDefaultSerializer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default serializer used by this template.
|
||||
*
|
||||
@@ -425,6 +444,9 @@ public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperation
|
||||
@SuppressWarnings("unchecked")
|
||||
private byte[] rawKey(Object key) {
|
||||
Assert.notNull(key, "non null key required");
|
||||
if(keySerializer == null && key instanceof byte[]) {
|
||||
return (byte[]) key;
|
||||
}
|
||||
return keySerializer.serialize(key);
|
||||
}
|
||||
|
||||
@@ -434,6 +456,9 @@ public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperation
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private byte[] rawValue(Object value) {
|
||||
if(valueSerializer == null && value instanceof byte[]) {
|
||||
return (byte[]) value;
|
||||
}
|
||||
return valueSerializer.serialize(value);
|
||||
}
|
||||
|
||||
@@ -450,7 +475,7 @@ public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperation
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private K deserializeKey(byte[] value) {
|
||||
return (K) keySerializer.deserialize(value);
|
||||
return keySerializer != null ? (K) keySerializer.deserialize(value) : (K) value;
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@@ -461,7 +486,7 @@ public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperation
|
||||
}
|
||||
List<Object> values = new ArrayList<Object>();
|
||||
for(Object rawValue: rawValues) {
|
||||
if(rawValue instanceof byte[]) {
|
||||
if(rawValue instanceof byte[] && valueSerializer != null) {
|
||||
values.add(valueSerializer.deserialize((byte[])rawValue));
|
||||
} else if(rawValue instanceof List) {
|
||||
// Lists are the only potential Collections of mixed values....
|
||||
@@ -484,20 +509,24 @@ public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperation
|
||||
return rawSet;
|
||||
}
|
||||
Object setValue = rawSet.iterator().next();
|
||||
if(setValue instanceof byte[]) {
|
||||
if(setValue instanceof byte[] && valueSerializer != null) {
|
||||
return (SerializationUtils.deserialize((Set)rawSet, valueSerializer));
|
||||
}else if(setValue instanceof Tuple) {
|
||||
return deserializeTupleValues(rawSet, valueSerializer);
|
||||
return convertTupleValues(rawSet, valueSerializer);
|
||||
} else {
|
||||
return rawSet;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
private Set<TypedTuple<V>> deserializeTupleValues(Set<Tuple> rawValues, RedisSerializer valueSerializer) {
|
||||
private Set<TypedTuple<V>> convertTupleValues(Set<Tuple> rawValues, RedisSerializer valueSerializer) {
|
||||
Set<TypedTuple<V>> set = new LinkedHashSet<TypedTuple<V>>(rawValues.size());
|
||||
for (Tuple rawValue : rawValues) {
|
||||
set.add(new DefaultTypedTuple(valueSerializer.deserialize(rawValue.getValue()), rawValue.getScore()));
|
||||
Object value = rawValue.getValue();
|
||||
if(valueSerializer != null) {
|
||||
value = valueSerializer.deserialize(rawValue.getValue());
|
||||
}
|
||||
set.add(new DefaultTypedTuple(value, rawValue.getScore()));
|
||||
}
|
||||
return set;
|
||||
}
|
||||
@@ -652,7 +681,8 @@ public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperation
|
||||
}
|
||||
}, true);
|
||||
|
||||
return SerializationUtils.deserialize(rawKeys, keySerializer);
|
||||
return keySerializer != null ? SerializationUtils.deserialize(rawKeys, keySerializer) :
|
||||
rawKeys;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -81,6 +81,7 @@ public abstract class SerializationUtils {
|
||||
return ret;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <HK,HV> Map<HK, HV> deserialize(Map<byte[], byte[]> rawValues,
|
||||
RedisSerializer<HK> hashKeySerializer, RedisSerializer<HV> hashValueSerializer) {
|
||||
if (rawValues == null) {
|
||||
@@ -88,8 +89,12 @@ public abstract class SerializationUtils {
|
||||
}
|
||||
Map<HK, HV> map = new LinkedHashMap<HK, HV>(rawValues.size());
|
||||
for (Map.Entry<byte[], byte[]> entry : rawValues.entrySet()) {
|
||||
map.put((HK) hashKeySerializer.deserialize(entry.getKey()),
|
||||
(HV) hashValueSerializer.deserialize(entry.getValue()));
|
||||
// May want to deserialize only key or value
|
||||
HK key = hashKeySerializer != null ? (HK) hashKeySerializer.deserialize(entry.getKey()) :
|
||||
(HK) entry.getKey();
|
||||
HV value = hashValueSerializer != null ? (HV) hashValueSerializer.deserialize(entry.getValue()) :
|
||||
(HV) entry.getValue();
|
||||
map.put(key, value);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user