2.Spring Boot中集成Guava Cache或者Caffeine
文章目录
- 一、在Spring Boot(1.x版本)中集成Guava Cache
- 1. 添加依赖
- 2. 启用缓存支持
- 3. 配置Guava缓存管理器
- 4. 使用缓存注解
- 5. 验证缓存效果
- 高级配置
- 常见问题
- 二、Spring Boot 2.x及以上版本(推荐使用Caffeine)
- 1. **添加依赖**
- 2. **启用缓存支持**
- 3. **配置Caffeine缓存**
- **方式一:通过配置文件**
- **方式二:通过Java Config类**
- 4. **使用缓存注解**
- 5. **高级配置**
- **刷新策略(RefreshAfterWrite)**
- **统计与监控**
- 6. **验证缓存效果**
- 常见问题
- 三、Caffeine使用场景
- 1. **高并发请求缓存**
- 2. **数据库查询缓存**
- 3. **复杂计算结果缓存**
- 4. **多级缓存架构(L1缓存)**
- 5. **需要高灵活性和统计监控的场景**
- 注意事项
- 总结
- 更多用法:
一、在Spring Boot(1.x版本)中集成Guava Cache
- 注意: Spring Boot 2.x+用户:优先使用Caffeine,性能更优且维护活跃。
1. 添加依赖
在pom.xml中添加Guava依赖:
com.google.guava guava 31.0.1-jre
2. 启用缓存支持
在启动类上添加@EnableCaching注解:
@SpringBootApplication @EnableCaching public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
3. 配置Guava缓存管理器
创建配置类定义CacheManager Bean:
@Configuration public class CacheConfig { @Bean public CacheManager cacheManager() { GuavaCacheManager cacheManager = new GuavaCacheManager(); cacheManager.setCacheBuilder(CacheBuilder.newBuilder() .expireAfterWrite(10, TimeUnit.MINUTES) // 写入10分钟后过期 .maximumSize(100) // 最大缓存数量 .recordStats()); // 开启统计信息 return cacheManager; } }
4. 使用缓存注解
在Service层使用@Cacheable、@CacheEvict等注解:
@Service public class UserService { // 缓存查询结果,key为id @Cacheable(value = "USER_CACHE", key = "#id") public User getUserById(Long id) { return userRepository.findById(id).orElse(null); } // 更新缓存 @CachePut(value = "USER_CACHE", key = "#user.id") public User updateUser(User user) { return userRepository.save(user); } // 删除缓存 @CacheEvict(value = "USER_CACHE", key = "#id") public void deleteUser(Long id) { // 删除用户逻辑 userRepository.deleteById(id); } }
5. 验证缓存效果
编写测试类或调用接口验证缓存是否生效:
@SpringBootTest public class UserServiceTest { @Autowired private UserService userService; @Test public void testCache() { // 第一次调用,执行方法 User user1 = userService.getUserById("123"); // 第二次调用,从缓存获取 User user2 = userService.getUserById("123"); // 验证是否为同一对象(缓存生效) assertThat(user1).isSameAs(user2); } }
高级配置
-
多缓存配置:为不同缓存设置不同策略:
@Bean public CacheManager cacheManager() { GuavaCacheManager cacheManager = new GuavaCacheManager(); cacheManager.setCacheBuilder(CacheBuilder.newBuilder() .expireAfterWrite(30, TimeUnit.MINUTES) .maximumSize(500)); cacheManager.setCacheBuilder("userCache", CacheBuilder.newBuilder() .expireAfterWrite(10, TimeUnit.MINUTES) .maximumSize(100)); return cacheManager; }
-
刷新策略:使用refreshAfterWrite定时刷新(需配合LoadingCache):
CacheBuilder.newBuilder() .refreshAfterWrite(5, TimeUnit.MINUTES) .build(CacheLoader.from(key -> loadData(key)));
-
统计信息:通过recordStats()启用统计,使用cache.getStatistics()获取命中率等信息。
常见问题
-
缓存未生效:
- 确保启动类有@EnableCaching。
- 检查方法是否为public(注解在私有方法上无效)。
-
配置未应用:
- 确认CacheManager Bean正确注册。
- 检查缓存名称是否匹配@Cacheable(value = "cacheName")。
-
内存溢出:
- 合理设置maximumSize或expireAfterAccess/Write。
通过以上步骤,即可在Spring Boot中高效使用Guava Cache实现本地缓存,提升应用性能。
二、Spring Boot 2.x及以上版本(推荐使用Caffeine)
在Spring Boot 2.x及以上版本中,Caffeine作为默认的本地缓存组件,取代了Guava Cache,提供了更高的性能和更灵活的配置。
1. 添加依赖
需引入spring-boot-starter-cache和caffeine依赖:
org.springframework.boot spring-boot-starter-cache com.github.ben-manes.caffeine caffeine 3.1.8
2. 启用缓存支持
在启动类添加@EnableCaching注解:
(图片来源网络,侵删)@SpringBootApplication @EnableCaching public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
3. 配置Caffeine缓存
方式一:通过配置文件
在application.yml中定义全局缓存参数:
spring: cache: type: caffeine caffeine: spec: maximumSize=500,expireAfterWrite=600s,initialCapacity=100 cache-names: userCache, productCache # 定义缓存名称
- 常用参数:
- maximumSize:最大缓存条目数
- expireAfterWrite:写入后过期时间
- initialCapacity:初始容量。
方式二:通过Java Config类
为不同缓存设置独立策略(推荐多缓存场景):
(图片来源网络,侵删)@Configuration @EnableCaching public class CacheConfig { public enum Caches { USER_CACHE(600, 1000), // 有效期600秒,最大容量1000 PRODUCT_CACHE(3600); private final int ttl; private final int maxSize; Caches(int ttl, int maxSize) { this.ttl = ttl; this.maxSize = maxSize; } public int getTtl() { return ttl; } public int getMaxSize() { return maxSize; } } @Bean public CacheManager cacheManager() { SimpleCacheManager manager = new SimpleCacheManager(); List caches = Arrays.stream(Caches.values()) .map(c -> new CaffeineCache(c.name(), Caffeine.newBuilder() .expireAfterWrite(c.getTtl(), TimeUnit.SECONDS) .maximumSize(c.getMaxSize()) .build())) .collect(Collectors.toList()); manager.setCaches(caches); return manager; } }
此方式支持为每个缓存单独配置过期时间和容量。
4. 使用缓存注解
在Service层通过注解操作缓存:
(图片来源网络,侵删)@Service public class UserService { // 缓存查询结果,key为id @Cacheable(value = "USER_CACHE", key = "#id") public User getUserById(Long id) { return userRepository.findById(id).orElse(null); } // 更新缓存 @CachePut(value = "USER_CACHE", key = "#user.id") public User updateUser(User user) { return userRepository.save(user); } // 删除缓存 @CacheEvict(value = "USER_CACHE", key = "#id") public void deleteUser(Long id) { userRepository.deleteById(id); } }
- 注解说明:
- @Cacheable:查询时优先从缓存读取
- @CachePut:更新数据并刷新缓存
- @CacheEvict:删除数据时移除缓存。
5. 高级配置
刷新策略(RefreshAfterWrite)
需定义CacheLoader以支持自动刷新:
@Bean public CacheLoader cacheLoader() { return new CacheLoader() { @Override public Object load(Object key) { return loadDataFromDB(key); // 初始加载数据 } @Override public Object reload(Object key, Object oldValue) { return oldValue; // 刷新时保留旧值,异步加载新值 } }; }
配置文件中需添加refreshAfterWrite=5s,并关联此Bean。
统计与监控
启用统计功能:
Caffeine.newBuilder() .recordStats() .build();
通过cache.stats()获取命中率、回收数量等指标。
6. 验证缓存效果
通过测试类验证缓存是否生效:
@SpringBootTest public class CacheTest { @Autowired private UserService userService; @Test public void testCache() { User user1 = userService.getUserById(1L); // 首次查询,存入缓存 User user2 = userService.getUserById(1L); // 二次查询,命中缓存 assertThat(user1).isSameAs(user2); } }
常见问题
-
缓存未命中:
- 检查方法是否为public(注解在私有方法无效)
- 确认缓存名称与配置一致。
-
配置冲突:
- 避免同时配置maximumSize和maximumWeight
- expireAfterWrite优先级高于expireAfterAccess。
通过以上步骤,可在Spring Boot 2.x中高效集成Caffeine,实现高性能本地缓存,适用于高频访问但更新较少的数据场景(如配置信息、静态数据)。
三、Caffeine使用场景
Caffeine 作为高性能本地缓存库,适用于多种需要快速数据访问和高效内存管理的场景。以下是其主要使用场景及对应的技术优势分析:
1. 高并发请求缓存
- 场景描述:适用于高频访问的接口或热点数据,例如用户信息查询、商品详情展示等。Caffeine 通过无锁并发设计和 Window TinyLFU 算法,显著提升缓存命中率,减少数据库压力。
- 技术优势:
- 高性能:在高并发环境下,Caffeine 的吞吐量远超 Guava Cache,其分段锁机制避免了锁竞争问题。
- 高命中率:Window TinyLFU 算法结合 LRU 和 LFU 优点,有效保留高频访问数据,命中率比 Guava 提升 10%~20%。
- 典型应用:Web 应用的 API 接口缓存,如电商平台的商品详情页。
2. 数据库查询缓存
- 场景描述:用于缓存频繁查询的数据库结果,如用户常用配置、热门商品库存等,减少重复数据库访问。
- 技术优势:
- 自动过期策略:支持 expireAfterWrite(写入后过期)和 expireAfterAccess(访问后过期),防止数据过时。
- 内存管理:通过 maximumSize 限制缓存条目数,避免内存溢出,结合惰性删除和定时清理机制优化内存使用。
- 典型应用:用户登录信息缓存、商品库存实时查询缓存。
3. 复杂计算结果缓存
- 场景描述:缓存计算密集型操作的结果,如图像处理、大数据聚合分析等,避免重复计算消耗资源。
- 技术优势:
- 异步加载:通过 AsyncLoadingCache 异步加载数据,减少主线程阻塞,提升系统响应速度。
- 刷新机制:使用 refreshAfterWrite 定时刷新缓存,保证数据更新后的及时性,同时保留旧数据直至新数据加载完成。
- 典型应用:推荐系统的实时计算结果缓存、图像处理后的缩略图缓存。
4. 多级缓存架构(L1缓存)
- 场景描述:在分布式系统中作为一级本地缓存(L1),结合 Redis(L2)和数据库(L3)形成三级缓存,减少跨服务或跨节点的网络延迟。
- 技术优势:
- 低延迟访问:本地内存访问速度极快,适合对延迟敏感的场景。
- 灵活集成:通过 CacheLoader 和 Writer 接口,可无缝与 Redis 等外部缓存联动,实现数据回源和同步。
- 典型应用:秒杀系统的库存缓存、分布式服务中的配置信息缓存。
5. 需要高灵活性和统计监控的场景
- 场景描述:对缓存策略有定制化需求(如动态调整过期时间、监听缓存事件)或需监控缓存命中率的场景。
- 技术优势:
- 灵活配置:支持基于大小、时间、引用等多种淘汰策略,并可自定义过期逻辑。
- 统计功能:通过 recordStats() 启用统计,获取命中率、淘汰次数等指标,便于性能调优。
- 典型应用:实时监控系统的缓存健康状态、需要动态调整缓存策略的业务场景。
注意事项
- 非分布式场景:Caffeine 仅适用于本地缓存,跨节点数据需结合 Redis 等分布式缓存。
- 内存限制:需根据应用内存合理设置 maximumSize 或权重,避免 OOM 问题。
- 数据一致性:本地缓存可能导致多实例间数据不一致,需通过过期时间或事件通知机制解决。
总结
Caffeine 凭借其高性能、高命中率和灵活的配置,成为高并发、低延迟场景下的首选本地缓存库。尤其适合作为一级缓存与 Redis 等组成多级缓存架构,或用于需要快速响应和复杂策略管理的业务场景。实际应用中需结合具体需求调整淘汰策略和内存配置,以最大化其优势。
更多用法:
SpringBoot:第五篇 集成Guava(本地缓存+分布式缓存)
-
- 注解说明:
-
-
- 注意: Spring Boot 2.x+用户:优先使用Caffeine,性能更优且维护活跃。