Spring Cache 整合 Redis 实现高效缓存
介绍
Spring Cache 是 Spring 框架提供的缓存抽象层,它简化了在应用中添加缓存功能的过程,允许开发者通过注解方式轻松实现缓存逻辑,而无需关注具体的缓存实现细节。
- 缓存抽象:Spring Cache 不直接提供缓存实现,而是定义了一套接口(如
Cache
、CacheManager
),支持多种缓存实现(如 Caffeine、EhCache、Redis 等)。 - 注解驱动:通过注解(如
@Cacheable
、@CachePut
、@CacheEvict
)声明缓存规则,无需手动编写缓存逻辑。 - 透明集成:缓存操作与业务逻辑解耦,开发者只需关注业务代码。
常用注解
-
@Cacheable
标记方法结果可被缓存。调用方法时,先检查缓存:- 若缓存存在,直接返回缓存值,不执行方法。
- 若缓存不存在,执行方法并将结果存入缓存。
@Cacheable(value = "users", key = "#id") public User getUserById(Long id) {// 从数据库查询用户return userRepository.findById(id); }
-
@CachePut
保证方法执行,并将结果更新到缓存(常用于更新操作)。@CachePut(value = "users", key = "#user.id") public User updateUser(User user) {return userRepository.save(user); }
-
@CacheEvict
移除缓存条目(常用于删除操作)。@CacheEvict(value = "users", key = "#id") public void deleteUser(Long id) {userRepository.deleteById(id); }
-
@Caching
组合多个缓存注解(如同时更新和删除缓存)。@Caching(put = @CachePut(value = "users", key = "#user.id"),evict = @CacheEvict(value = "userList", allEntries = true) ) public User saveUser(User user) {return userRepository.save(user); }
-
@CacheConfig
在类级别统一配置缓存属性(如value
、keyGenerator
),简化方法上的注解。
案例
- 添加依赖(Maven):
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId></dependency>
- 启用缓存:
在启动类添加@EnableCaching
注解。
@SpringBootApplication
@EnableTransactionManagement //开启注解方式的事务管理
@Slf4j
@EnableCaching//开启缓存功能
public class SkyApplication {public static void main(String[] args) {SpringApplication.run(SkyApplication.class, args);log.info("server started");}
}
- c端
/*** 条件查询** @param categoryId* @return*/@GetMapping("/list")@ApiOperation("根据分类id查询套餐")@Cacheable(cacheNames = "setmealCache",key = "#categoryId")//key: setmealCache::categoryIdpublic Result<List<Setmeal>> list(Long categoryId) {Setmeal setmeal = new Setmeal();setmeal.setCategoryId(categoryId);setmeal.setStatus(StatusConstant.ENABLE);List<Setmeal> list = setmealService.list(setmeal);return Result.success(list);}
- 管理端
/*** 新增套餐* @param setmealDTO* @return*/@PostMapping@ApiOperation("新增套餐")@CacheEvict(cacheNames = "setmealCache",key = "#setmealDTO.categoryId")public Result save(@RequestBody SetmealDTO setmealDTO){log.info("新增套餐:{}",setmealDTO);setmealService.saveWithDish(setmealDTO);return Result.success();}/*** 删除套餐* @param ids* @return*/@DeleteMapping@ApiOperation("批量删除套餐")@CacheEvict(cacheNames = "setmealCache",allEntries = true)public Result delete(@RequestParam List<Long> ids){log.info("批量删除套餐:{}",ids);setmealService.deleteBatch(ids);return Result.success();}/*** 修改套餐起售停售状态* @param status* @param id* @return*/@PostMapping("/status/{status}")@ApiOperation("修改套餐起售停售状态")@CacheEvict(cacheNames = "setmealCache",allEntries = true)public Result startOrStop(@PathVariable("status") Integer status, Long id){log.info("套餐起售或停售:{}",id);setmealService.startOrStop(status,id);return Result.success();}
注意事项
- 缓存键生成:默认使用方法参数生成键,可通过
key
属性自定义(SpEL 表达式),或配置KeyGenerator
。 - 缓存穿透:可通过空值缓存(
@Cacheable(unless = "#result == null")
)避免。 - 缓存更新:使用
@CachePut
确保缓存与数据源一致性,避免直接修改缓存。 - 分布式缓存:在分布式系统中,推荐使用 Redis 等集中式缓存,避免本地缓存(如 Caffeine)的一致性问题。
通过 Spring Cache,开发者可以快速为应用添加缓存能力,提升系统性能,同时保持代码简洁易维护。