当前位置: 首页 > news >正文

SpringBoot项目里,用Caffeine和Spring Cache注解搞定本地缓存(附完整代码)

SpringBoot项目中Caffeine与Spring Cache注解的深度整合实践

在构建高性能Web服务时,缓存技术是提升系统响应速度的关键组件。SpringBoot生态中,Caffeine作为新一代高性能本地缓存库,与Spring Cache抽象层的结合,能够以声明式的方式实现缓存逻辑,显著减少样板代码。本文将深入探讨如何通过@Cacheable@CachePut@CacheEvict三大核心注解,配合Caffeine的强大性能,构建优雅的缓存解决方案。

1. 环境准备与基础配置

1.1 依赖引入

首先需要在项目中添加必要的依赖。对于Maven项目,在pom.xml中加入:

<dependencies> <!-- Spring Cache抽象层 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency> <!-- Caffeine缓存实现 --> <dependency> <groupId>com.github.ben-manes.caffeine</groupId> <artifactId>caffeine</artifactId> <version>3.1.8</version> </dependency> </dependencies>

注意:Caffeine 3.x版本需要Java 11及以上运行环境,若项目使用Java 8,需选择2.9.x版本。

1.2 缓存配置类

创建缓存配置类来定义Caffeine的具体行为:

@Configuration @EnableCaching public class CacheConfig { @Bean public CacheManager cacheManager() { CaffeineCacheManager cacheManager = new CaffeineCacheManager(); cacheManager.setCaffeine(Caffeine.newBuilder() .expireAfterWrite(10, TimeUnit.MINUTES) .initialCapacity(100) .maximumSize(1000) .recordStats()); // 开启统计功能 return cacheManager; } }

关键配置参数说明:

参数类型说明推荐值
expireAfterWriteDuration写入后过期时间5-30分钟
initialCapacityint初始缓存大小100-500
maximumSizelong最大缓存条目数1000-10000
recordStats-是否记录统计信息生产环境建议开启

2. 核心注解实战应用

2.1 @Cacheable注解详解

@Cacheable是最常用的缓存注解,用于标记方法的返回值应当被缓存:

@Service public class ProductService { @Cacheable(value = "products", key = "#id", unless = "#result == null") public Product getProductById(Long id) { // 模拟数据库查询 return productRepository.findById(id).orElse(null); } }

注解参数解析:

  • value/cacheNames:指定缓存名称,对应配置中的缓存区域
  • key:使用SpEL表达式定义缓存键
  • unless:条件表达式,当结果为true时不缓存

常见SpEL表达式示例

@Cacheable(key = "#user.id + ':' + #type") // 组合键 @Cacheable(key = "T(java.util.UUID).randomUUID().toString()") // 随机键 @Cacheable(key = "#root.methodName + ':' + #id") // 方法名作为键部分

2.2 @CachePut更新策略

当需要更新缓存时使用@CachePut注解,它总是会执行方法体,并将结果存入缓存:

@CachePut(value = "products", key = "#product.id") public Product updateProduct(Product product) { return productRepository.save(product); }

提示:@CachePut通常用于更新操作,确保缓存与数据源保持同步。

2.3 @CacheEvict清除策略

删除操作需要同步清除缓存,使用@CacheEvict

@CacheEvict(value = "products", key = "#id") public void deleteProduct(Long id) { productRepository.deleteById(id); }

清除整个缓存区域:

@CacheEvict(value = "products", allEntries = true) public void clearAllProductsCache() { // 无需实现,注解会触发缓存清除 }

3. 高级特性与性能优化

3.1 多级缓存策略

结合本地缓存与分布式缓存实现多级缓存:

public class MultiLevelCacheService { @Cacheable(cacheNames = "local", key = "#id") public Product getProductWithMultiCache(Long id) { // 先查本地缓存,未命中则查Redis Product product = redisTemplate.opsForValue().get("product:" + id); if (product == null) { product = productRepository.findById(id).orElse(null); redisTemplate.opsForValue().set("product:" + id, product); } return product; } }

3.2 缓存穿透防护

针对缓存穿透问题,可以采用以下策略:

  1. 空值缓存:缓存null结果,设置较短过期时间
  2. 布隆过滤器:前置过滤非法请求
  3. 限流措施:对高频访问进行限制

实现空值缓存示例:

@Cacheable(value = "products", key = "#id", unless = "#result == null") public Product getProductWithNullCache(Long id) { Product product = productRepository.findById(id).orElse(null); if (product == null) { // 记录不存在的信息,防止穿透 return new NullProduct(); } return product; }

3.3 缓存性能监控

Caffeine提供了丰富的统计信息,可通过配置开启:

@Bean public CacheManager cacheManager() { CaffeineCacheManager cacheManager = new CaffeineCacheManager(); cacheManager.setCaffeine(Caffeine.newBuilder() .recordStats()); return cacheManager; }

获取统计信息:

CacheStats stats = caffeineCache.stats(); System.out.println("命中率: " + stats.hitRate()); System.out.println("平均加载时间: " + stats.averageLoadPenalty() + "ns");

4. 实战案例:用户信息服务

4.1 服务层实现

完整用户服务缓存示例:

@Service @CacheConfig(cacheNames = "users") public class UserServiceImpl implements UserService { @Autowired private UserRepository userRepository; @Override @Cacheable(key = "#id", unless = "#result == null") public User getUserById(Long id) { return userRepository.findById(id).orElse(null); } @Override @CachePut(key = "#user.id") public User updateUser(User user) { return userRepository.save(user); } @Override @CacheEvict(key = "#id") public void deleteUser(Long id) { userRepository.deleteById(id); } @Override @Caching(evict = { @CacheEvict(key = "#userId"), @CacheEvict(cacheNames = "user-roles", key = "#userId") }) public void updateUserRoles(Long userId, List<Long> roleIds) { // 更新用户角色关系 } }

4.2 控制器层集成

RESTful接口示例:

@RestController @RequestMapping("/api/users") public class UserController { @Autowired private UserService userService; @GetMapping("/{id}") public ResponseEntity<User> getUser(@PathVariable Long id) { User user = userService.getUserById(id); return ResponseEntity.ok(user); } @PutMapping public ResponseEntity<User> updateUser(@RequestBody User user) { return ResponseEntity.ok(userService.updateUser(user)); } @DeleteMapping("/{id}") public ResponseEntity<Void> deleteUser(@PathVariable Long id) { userService.deleteUser(id); return ResponseEntity.noContent().build(); } }

4.3 复杂缓存策略

对于关联数据的缓存处理:

public class OrderService { @Cacheable(value = "orders", key = "#orderId") public Order getOrderWithUser(Long orderId) { Order order = orderRepository.findById(orderId).orElse(null); if (order != null) { // 触发用户缓存 User user = userService.getUserById(order.getUserId()); order.setUser(user); } return order; } }

在实际项目中,根据业务场景合理设计缓存键和过期策略,可以显著提升系统性能。Caffeine与Spring Cache的结合,既保持了代码的简洁性,又能获得接近手动缓存控制的灵活性。

http://www.jsqmd.com/news/688520/

相关文章:

  • 告别App Store!三种主流签名方式(企业签/超级签/TF签)手把手教你安装自研iOS App
  • 老年健康移动应用设计:挑战、解决方案与实践
  • #广州最推荐的一线初中有哪些?2026年增城等地市场选择前五排名 - 十大品牌榜
  • 抖音批量下载工具终极指南:三步实现高效免费下载
  • 举升机之选:五大主流品牌实力与场景适配深度测评 - 资讯焦点
  • React 性能优化的手段有哪些?
  • 曹操出行难做Robotaxi版“滴滴”
  • Windows下Python venv报错exit status 1?别急着删文件夹,试试这个--without-pip参数
  • 为什么需要专业的冷气机、工业制冷机与液冷测试机?2026年冷气机/工业制冷机/液冷测试机精选推荐公司 - 品牌推荐大师1
  • 核心零部件难在哪儿?盈诺、日立、佳航三家DSC的传感器灵敏度与热流噪声数据公开 - 品牌推荐大师1
  • 昆明诚誉名酒回收:昆明上门酒回收哪个公司好 - LYL仔仔
  • 数据防泄漏软件怎么选?26最新整理六款数据防泄漏软件,建议收藏
  • 国内翘嘴鱼水饺供应商实力TOP5 技术与品质双对标 - 资讯焦点
  • #广州最推荐的外语学校有哪些?2026年增城等地市场选择前五排名 - 十大品牌榜
  • 联想刃7000K BIOS隐藏选项解锁指南:3步开启高级性能设置
  • Phi-3.5-mini-instruct开源可部署:ModelScope镜像+GitHub源码双通道
  • 2026年贵州手提袋定制与包装辅料设计的专业选择指南 - 优质企业观察收录
  • 2026年冷气机/工业制冷机/液冷测试机厂家企业供应商对比推荐 - 品牌推荐大师1
  • 烟威不锈钢加工性价比深度实测:多维数据硬核排行与采购避坑指南 - 资讯焦点
  • 防火墙双机热备之VGMP故障切换机制深度剖析
  • 海口家长必看!发育迟缓干预机构全解析 - 品牌测评鉴赏家
  • 身份证阅读器除了读信息还能干啥?新中新SDK隐藏功能与M1卡操作指南
  • #宁夏最推荐的高处作业培训学校有哪些?2026年银川吴忠石嘴山等地市场选择前十排名 - 十大品牌榜
  • 龙鱼用品什么牌子好?马印为何成为高端玩家首选 - 观域传媒
  • 从语法到实战:COE文件在FPGA设计中的核心应用与自动化生成
  • 烟台全屋定制实测5 大主流品牌深度对比与选型指南 - 资讯焦点
  • 掌握15MW海上风电仿真:IEA-15-240-RWT完整实战指南
  • 如何用TaskbarX打造专业级Windows任务栏:终极配置完全指南
  • 2026年螺杆式冷水机/工业冷水机厂家企业供应商对比推荐 - 品牌推荐大师1
  • IK Rig编辑器