本篇文章介绍的是RedisTemplate在实际开发中如何使用,从SpringBoot自动装配RedisTemplate出发,介绍如何定义自己的RedisTemplate,到RedisTemplate的封装,老司机不必再浪费时间,O(∩_∩)O
一、SpringBoot中集成RedisTemplate
二、RedisTemplate自动装配
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration这个类为RedisTemplate自动装配的类,我们不妨打开看一眼:
1)这个带@Bean注解的就是SpringBoot默认为我们装配的RedisTemplate,我们可以看到装配类型是RedisTemplate<Object, Object>,所以默认情况下我们只能自动注入<Object, Object>或者<String, String>泛型的RedisTemplate(上一篇博客记录了踩过的这个坑)
2)我们可以看到方法上带有@ConditionalOnMissingBean(name = "redisTemplate"),这个注解的作用就是如果我们自己定义了RedisTemplate并放入了IoC,那SpringBoot的这个RedisTemplate就不生效了,我们用@Autowired注入的RedisTemplate就是我们自己写的那个了
3)默认的这个RedisTemplate使用的序列化方式是jdk的,所以我们存入的Object要实现序列化接口,不然会报错,但在实际开发中我们并不想用这种序列化方式,我们都会采用JSON方式的序列化
三、自定义RedisTemplate
在实际开发中,我们用的RedisTemplate通常是<String, Object>这种泛型,所以我们自定义的RedisTemplate采用这种泛型,并用@Configuration和@Bean注解将我们自己定义的RedisTemplate放入IoC容器,使默认RedisTemplate失效:
@Configuration
public class RedisConfig {
@Bean
@SuppressWarnings("all")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
//设置连接工厂,包含一些Redis连接信息
redisTemplate.setConnectionFactory(factory);
// Json序列化配置
Jackson2JsonRedisSerializer jsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jsonRedisSerializer.setObjectMapper(objectMapper);
// String的序列化
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key均采用String序列化方式
redisTemplate.setKeySerializer(stringRedisSerializer);
// hsah的key也采用String序列化的方式
redisTemplate.setHashKeySerializer(stringRedisSerializer);
// value采用json的序列化方式
redisTemplate.setValueSerializer(jsonRedisSerializer);
// hash的value也采用json的序列化方式
redisTemplate.setHashKeySerializer(jsonRedisSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
四、RedisTemplate的工具类RedisUtil
上篇博客的案例提到过RedisTemplate的使用,例如往Redis中存值、取值、设置失效时间:
// 存
redisTemplate.opsForValue().set(id, blogTemp);
// 取
redisTemplate.opsForValue().get(id);
// 设置失效时间
redisTemplate.expire(id, 30, TimeUnit.SECONDS)
我们可以发现每次都要写很长,所以在实际开发中不仅会定义自己的RedisTemplate,而且还会给写一个工具类,目的就是为了方便,下面用代码简单举例说明,大家可以按照如此思路定义方便自己的使用Utils:
@Component
public final class RedisUtil {
// 此处自动注入参数是上述自己定义的RedisTemplate,而非默认的
@Autowired
private RedisTemplate<String, Object> redisTemplate;
/**
* 取
* @param key 键
* @return
*/
public Object get(String key) {
return key == null ? null : redisTemplate.opsForValue().get(key);
}
/**
* 普通缓存放入
* @param key 键
* @param value 值
* @return true成功 false失败
*/
public boolean set(String key, Object value) {
try {
redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 指定缓存失效时间
* @param key 键
* @param time 时间(秒)
* @return
*/
public boolean expire(String key, long time) {
try {
if (time > 0) {
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 根据key 获取过期时间
* @param key 键 不能为null
* @return 时间(秒) 返回0代表为永久有效
*/
public long getExpire(String key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
}
这样我们存值就可以这么写:
public class PaymentServiceImpl implements PaymentService {
@Autowired
private RedisUtil redisUtil;
@Override
public ResultVO getByPrimaryKey(Integer id) {
// 取值
redisUtil.get(id.toString());
return ResultVO.success();
}
}
大家理解这个思想就可以,网上有一大堆这种工具类,当然如果你有时间,也可以自己写一套自己用着舒服的Util。