SpringBoot整合redis并使用缓存注解
直接上代码
- 添加Redis依赖,在pom.xml文件中添加以下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
- application.yml 配置Redis连接信息
spring:
cache:
type: redis
redis:
host: 127.0.0.1 # Redis服务器地址
database: 1 # Redis数据库索引(默认为0)
port: 6379 # Redis服务器连接端口
password: # Redis服务器连接密码(默认为空)
指定缓存类型
redis
3.配置缓存管理器
@Configuration
@EnableCaching
public class RedisTemplateConfiguration {
/**
* 默认过期时长,单位:秒
*/
@Getter
private long expire = 60 * 60 * 24;
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setKeySerializer(RedisSerializer.string());
redisTemplate.setHashKeySerializer(RedisSerializer.string());
redisTemplate.setValueSerializer(RedisSerializer.java());
redisTemplate.setHashValueSerializer(RedisSerializer.java());
redisTemplate.setConnectionFactory(factory);
return redisTemplate;
}
@Bean
public HashOperations<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForHash();
}
@Bean
public ValueOperations<String, String> valueOperations(RedisTemplate<String, String> redisTemplate) {
return redisTemplate.opsForValue();
}
@Bean
public ListOperations<String, Object> listOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForList();
}
@Bean
public SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForSet();
}
@Bean
public ZSetOperations<String, Object> zSetOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForZSet();
}
}
总之,通过@EnableCaching注解,我们可以方便地启用缓存功能,并结合Redis作为缓存实现。同时,通过@Cacheable注解,我们可以指定缓存名称和键值,实现缓存功能。
如果你需要补充EnableCaching相关知识点,请查看:@EnableCaching,@Cacheable, @CachePut,@CacheEvict详解。
在使用@EnableCaching注解后,我们可以在需要缓存的方法上添加@Cacheable注解,以启用缓存功能。例如:
@ApiOperation("dictType => 全局 根据字典类型查询字典详情数据信息")
@GetMapping(value = "/dictType/{dictType}")
@Cacheable(value = CacheConstants.DICT_DETAILS, key = "#dictType")
public R<List<SysDictDetail>> dictType(@PathVariable String dictType) {
return R.success(sysDictDetailService.selectDictDataByType(dictType));
}
redis保存格式如下:
为了方便大家更清晰的理解,我本地跑起一个程序验证一下,可以看一下打印的日志信息,第一次请求的时候是从数据库中加载出来的数据,再次请求的时候直接从缓存里面读取了。
常见问题:
1、缓存的值没有实现Serializable接口
Cannot serialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to serialize object using DefaultSerializer; nested exception is java.lang.IllegalArgumentException: DefaultSerializer requires a Serializable payload but received an object of type [cn.harry.common.api.R]
这个错误通常是因为在使用Spring Cache时,缓存的值没有实现Serializable接口,导致无法序列化。解决这个问题的方法是让缓存的值实现Serializable接口,以便在序列化时能够正确地将对象转换为字节流。下面是一个示例:
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Override
@Cacheable(value = "user_details", key = "#id")
public Serializable getUserById(Long id) {
User user = userDao.getUserById(id);
return (Serializable) user;
}
}
在上面的示例中,我们在getUserById()方法上添加了@Cacheable注解,并指定了缓存名称为"user_details",缓存键为方法参数id。同时,我们将返回值类型改为Serializable,并将User对象强制转换为Serializable类型,以便在序列化时能够正确地将对象转换为字节流。
总之,让缓存的值实现Serializable接口是解决这个问题的关键。如果缓存的值无法实现Serializable接口,可以考虑使用其他的缓存实现方式,例如使用JSON格式存储缓存值。