redisTemplate和stringRedisTemplate对比
RedisTemplate使用的是 JdkSerializationRedisSerializer 序列化对象
可以用来存储对象,但是要实现Serializable接口。
以二进制数组方式存储,内容没有可读性。
StringRedisTemplate使用的是 StringRedisSerializer 序列化String
主要用来存储字符串,StringRedisSerializer的泛型指定的是String。当存入对象时,会报错 :can not cast into String。
优点:
可见性强,更易维护。如果都是字符串存储可考虑用StringRedisTemplate。对象可以转换成json字符串存入就不报错
setNX方法
redisTemplate本身有没通过valueOperation实现分布式锁
RedisConnection实现分布锁的方式,采用redisTemplate操作redisConnection实现setnx和setex两个命令
由于redisTemplate存储的是二进制,所以需要序列化成字符串
public boolean lock(String key,Long expire){
/*
* RedisConnection实现分布锁的方式,采用redisTemplate操作redisConnection实现setnx和setex两个命令
* redisTemplate本身有没通过valueOperation实现分布式锁
*/
RedisConnection redisConnection=redisTemplate.getConnectionFactory().getConnection();
//设置序列化
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());
if(redisConnection.setNX(key.getBytes(),new byte[]{1})){
redisTemplate.expire(key,expire,TimeUnit.SECONDS);
redisConnection.close();
return true;
}else{
redisConnection.close();
return false;
}
}
@Resource(name = "stringRedisTemplate")
ValueOperations<String, String> valOpsStr;
/**
* 这一步等于将redisTemplate.opsForValue()直接注入
*
* 问题:
* redisTemplate并不是ValueOperations的实现类,那么是怎么注入进来的呢?
*
* 如果你要实例化的对象和你的引用对象并不是同一种类型,也就是如redisTemplate和ValueOperations
* 一般不是父子关系或接口实现关系,那么spring就会进行转换。
*用什么转换呢?Spring的editor。
*spring会去加载 ValueOperations+Editor,即ValueOperationsEditor的类。且此类必须要实现PropertyEditor接口。
*而我们在ValueOperations的包目录下确实会找到ValueOperationsEditor。
*这个类非常简单,它重写了setValue方法,将redisTemplate中的opsForValue()返回值set进去,而opsForValue()返回值
* 就是继承了ValueOperations的DefaultValueOperations。
*这样我们用editor get value的时候就能获取到DefaultValueOperations了。就可以将DefaultValueOperations注入到
* ValueOperations中去了。
*/