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

Guava Cache 本地项目缓存

  1. 添加依赖

在 Spring Boot 项目中,Guava Cache 是 Google Guava 库的一部分,因此需要添加 Guava 的依赖。

在 pom.xml(Maven)中添加以下依赖:

xml

<dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>33.3.1-jre</version>
</dependency>

注意: 请根据需要选择最新版本,检查 Maven Central 获取最新版本号。

如果使用 Gradle,可以在 build.gradle 中添加:

gradle

implementation 'com.google.guava:guava:33.3.1-jre'

  1. 创建 Guava Cache 配置

Guava Cache 需要手动配置缓存实例,包括缓存大小、过期策略等。以下是一个简单的配置类,展示如何在 Spring Boot 中定义 Guava Cache。

java

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.concurrent.TimeUnit;@Configuration
public class GuavaCacheConfig {@Beanpublic LoadingCache<String, String> guavaCache() {return CacheBuilder.newBuilder().maximumSize(1000) // 最大缓存条目数.expireAfterWrite(10, TimeUnit.MINUTES) // 写入后10分钟过期.expireAfterAccess(5, TimeUnit.MINUTES) // 访问后5分钟过期.recordStats() // 开启统计信息(如命中率).build(new CacheLoader<String, String>() {@Overridepublic String load(String key) throws Exception {// 当缓存未命中时,调用此方法加载数据return loadDataFromSource(key);}});}// 模拟从数据源加载数据private String loadDataFromSource(String key) {// 实际场景中,这里可能从数据库或外部服务加载数据return "Value for " + key;}
}

说明:

  • maximumSize: 设置缓存最大条目数,超出时按 LRU(最近最少使用)策略淘汰。
  • expireAfterWrite: 写入后指定时间过期。
  • expireAfterAccess: 最后访问后指定时间过期。
  • recordStats: 开启统计功能,可用于监控缓存命中率。
  • CacheLoader: 定义未命中时的加载逻辑(例如从数据库查询)。

  1. 在 Service 层中使用 Guava Cache

将配置好的 Guava Cache 注入到业务逻辑中,并在需要的地方使用缓存。

以下是一个简单的 Service 示例:

java

import com.google.common.cache.LoadingCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class DataService {@Autowiredprivate LoadingCache<String, String> guavaCache;public String getData(String key) {try {// 从缓存中获取数据,如果未命中则通过 CacheLoader 加载return guavaCache.get(key);} catch (Exception e) {// 处理异常return "Error retrieving data for key: " + key;}}public void putData(String key, String value) {// 手动放入缓存guavaCache.put(key, value);}public void invalidate(String key) {// 移除缓存中的键guavaCache.invalidate(key);}public void printCacheStats() {// 打印缓存统计信息System.out.println("Cache Stats: " + guavaCache.stats());}
}

说明:

  • guavaCache.get(key): 尝试从缓存中获取数据,未命中时会触发 CacheLoader 的 load 方法。
  • guavaCache.put(key, value): 手动将数据放入缓存。
  • guavaCache.invalidate(key): 移除指定键的缓存。
  • guavaCache.stats(): 查看缓存的命中率、加载时间等统计信息。

  1. 在 Controller 中调用

创建一个简单的 REST Controller 来测试缓存功能。

java

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;@RestController
@RequestMapping("/cache")
public class CacheController {@Autowiredprivate DataService dataService;@GetMapping("/get/{key}")public String getData(@PathVariable String key) {return dataService.getData(key);}@PostMapping("/put")public String putData(@RequestParam String key, @RequestParam String value) {dataService.putData(key, value);return "Data stored in cache";}@DeleteMapping("/invalidate/{key}")public String invalidate(@PathVariable String key) {dataService.invalidate(key);return "Cache invalidated for key: " + key;}@GetMapping("/stats")public String getStats() {dataService.printCacheStats();return "Check server logs for cache stats";}
}

说明:

  • /get/{key}: 获取缓存数据。
  • /put: 手动存入缓存。
  • /invalidate/{key}: 移除缓存。
  • /stats: 查看缓存统计信息(输出到日志)。

  1. 测试缓存功能

运行 Spring Boot 应用后,可以通过以下方式测试:

  1. 启动应用: 确保 Spring Boot 应用已启动(默认端口 8080)。
  2. 测试接口: 使用 curl 或 Postman 进行测试:
    • 获取数据:curl http://localhost:8080/cache/get/key1
      • 第一次请求会触发 loadDataFromSource,后续请求直接从缓存返回。
    • 存入数据:curl -X POST “http://localhost:8080/cache/put?key=key1&value=Hello”
    • 清除缓存:curl -X DELETE http://localhost:8080/cache/invalidate/key1
    • 查看统计:curl http://localhost:8080/cache/stats
  3. 验证缓存行为:
    • 检查缓存是否按配置的过期时间(如 10 分钟)失效。
    • 使用 guavaCache.stats() 查看命中率等信息。

  1. 集成 Spring Cache(可选)

如果希望结合 Spring 的缓存抽象(@Cacheable 等注解),可以创建一个自定义 CacheManager 来使用 Guava Cache。

java

import com.google.common.cache.CacheBuilder;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.guava.GuavaCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.concurrent.TimeUnit;@Configuration
@EnableCaching
public class SpringCacheConfig {@Beanpublic CacheManager cacheManager() {GuavaCacheManager cacheManager = new GuavaCacheManager("myCache");cacheManager.setCacheBuilder(CacheBuilder.newBuilder().maximumSize(1000).expireAfterWrite(10, TimeUnit.MINUTES));return cacheManager;}
}

然后在 Service 中使用注解:

java

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;@Service
public class DataService {@Cacheable(value = "myCache", key = "#key")public String getData(String key) {// 模拟从数据库加载return "Value for " + key;}
}

说明:

  • @Cacheable: 自动缓存方法结果,缓存名为 myCache。
  • Spring Cache 抽象简化了开发,但需要额外配置 CacheManager。

  1. 项目实践中的注意事项

  2. 缓存淘汰策略:

    • 根据业务需求调整 maximumSize 和过期时间。
    • 如果数据量较大,考虑 expireAfterAccess 以避免内存溢出。
  3. 线程安全:

    • Guava Cache 是线程安全的,无需额外同步。
  4. 监控缓存性能:

    • 使用 cache.stats() 监控命中率和加载时间,优化缓存配置。
  5. 异常处理:

    • 在 CacheLoader.load 中处理数据源异常,避免缓存失败影响业务。
  6. 分布式场景的局限:

    • Guava Cache 是本地缓存,数据不共享。如果需要分布式缓存,考虑 Redis 或 J2Cache。
  7. 日志和调试:

    • 开启 Guava 的统计功能,记录缓存命中率、加载时间等,分析性能瓶颈。

  1. 示例项目结构
src
├── main
│   ├── java
│   │   ├── com.example.demo
│   │   │   ├── config
│   │   │   │   ├── GuavaCacheConfig.java
│   │   │   │   ├── SpringCacheConfig.java (可选)
│   │   │   ├── controller
│   │   │   │   ├── CacheController.java
│   │   │   ├── service
│   │   │   │   ├── DataService.java
│   │   │   ├── DemoApplication.java
│   ├── resources
│   │   ├── application.properties

  1. 扩展:与数据库结合的实践

假设你有一个用户查询场景,需要缓存数据库查询结果:

java

@Service
public class UserService {@Autowiredprivate LoadingCache<String, User> userCache;@Autowiredprivate UserRepository userRepository; // Spring Data JPA@Beanpublic LoadingCache<String, User> userCache() {return CacheBuilder.newBuilder().maximumSize(1000).expireAfterWrite(1, TimeUnit.HOURS).build(new CacheLoader<String, User>() {@Overridepublic User load(String userId) throws Exception {return userRepository.findById(userId).orElseThrow(() -> new RuntimeException("User not found"));}});}public User getUser(String userId) {try {return userCache.get(userId);} catch (Exception e) {throw new RuntimeException("Failed to get user", e);}}
}

说明:

  • 缓存 User 对象,load 方法从数据库查询。
  • 缓存命中时直接返回,减少数据库访问。

  1. 性能优化建议
  • 调整缓存大小: 根据 JVM 内存和数据规模设置 maximumSize。
  • 异步加载: 使用 CacheBuilder.buildAsync 实现异步加载,提升性能。
  • 监控命中率: 定期检查 cache.stats().hitRate(),优化缓存策略。
  • 避免缓存穿透: 在 load 方法中处理空值(如返回默认值或抛异常)。
http://www.lqws.cn/news/542467.html

相关文章:

  • JDBC 工具类:1.0到3.0版本
  • leetcode 295. 数据流的中位数
  • element-plus限制日期可选范围(这里以7天为例)
  • Unity 脚本自动添加头部注释
  • Qwen VLo :一个多模态统一理解与生成模型
  • 在shell中直接调用使用R
  • 【容器】容器平台初探 - k8s整体架构
  • RJ45 以太网与 5G 的原理解析及区别
  • swagger访问不了的解决方案 http://localhost:8080/swagger-ui/index.html
  • 可编辑37页PPT | 数字化转型咨询规划方案
  • Mysql Mybatis批量插入和批量更新数据
  • 设计模式 | 适配器模式
  • LaTeX下载与实践入门指南
  • 在 Dev Container 中实现 GUI 开发的解决方案
  • 报表控件stimulsoft教程:在报表、仪表板和 PDF 表单自动生成缩略图
  • SQL Server 中 GO 的作用
  • mPaaS 客户端诊断概述
  • CSS3实现同心圆效果
  • Go 语言中的 package 和 go modules
  • (二)YOLOV12部署训练
  • 人工智能-基础篇-1-人工智能介绍(发展史,技术体系,技术基础,主要领域,前景和挑战)
  • macOS,切换 space 失效,向右切换space(move right a space) 失效
  • Django导入错误:`from django.conf.urls import url` 的终极解决方案
  • 【机器学习深度学习】线性回归(基本模型训练流程)
  • 【AS32系列MCU调试教程】SPI调试的常见问题解析
  • 【AI助手】释放双手,基于Cursor Agent与Playwright MCP的浏览器自动化实战
  • Windows家庭版安装docker
  • 【Pandas】pandas DataFrame last_valid_index
  • 校企协同育人,智慧养老实训基地助力人才就业无忧
  • 【中文核心期刊推荐】《计算机工程与科学 》