商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > SpringBoot整合缓存方式(Caffeine、Redis)

SpringBoot整合缓存方式(Caffeine、Redis)

  发布于2026-07-08 阅读(0)

扫一扫,手机访问

SpringBoot整合缓存

在实际项目中,缓存几乎是绕不开的一环。SpringBoot对缓存的支持非常友好,**注解驱动**的方式让你在几分钟内就能跑起来一个本地缓存或分布式缓存。本篇重点梳理两种常用方案:Caffeine(本地缓存)和 Redis(分布式缓存),顺便聊聊它们的适用场景和坑点。

注解介绍

Spring 缓存相关的核心注解有四个,理解它们各自的职责就好办了。

@EnableCaching

这个注解一般打在**缓存管理器配置类**上,配合 `@Configuration` 使用。它相当于告诉 Spring:“我要用缓存了,请开启自动袋里”。

@Cacheable

顾名思义,用于**查询**场景。当方法被调用时,Spring 会先根据 key 去缓存中找数据,找到就直接返回,不执行方法体;找不到就执行方法,并把结果存入缓存。注意:这里的 key 默认是方法参数组合,你也可以自定义。

@CachePut

这个注解用于**更新**操作。它**无论如何都会执行方法逻辑**,然后把返回结果更新到缓存中。适合那种即使缓存里有数据,也要强制刷新的场景。

@CacheEvict

用于**删除**操作。执行方法后,Spring 会直接清除对应的缓存条目。注意:它不会阻止方法执行,只是负责清缓存。

优缺点

- **优点**:零侵入、配置简单。不需要引入专业的缓存中间件也可以跑起来(比如直接用 Caffeine),非常适合快速集成。 - **缺点**:无法精细控制缓存行为。比如你想在 Redis 里做带业务逻辑的过期策略、或者针对不同缓存做不同的序列化方式,靠注解就不够灵活了,得自己写 `CacheManager` 的定制逻辑。

依赖

需要引入 Spring Boot、Caffeine 和 Redis 的相关依赖,下面是核心的 Ma ven 配置:


    org.springframework.boot
    spring-boot-starter-web
    2.6.8



    com.github.ben-manes.caffeine
    caffeine
    2.5.5



    org.springframework.boot
    spring-boot-starter-data-redis
    2.6.8


    redis.clients
    jedis
    3.7.1

配置文件yml

基本配置只需要指定 Redis 地址和端口,本地测试用默认的即可:
spring:
  redis:
    host: 127.0.0.1
    port: 6379
---

整合Caffeine

Caffeine 是 Gua va Cache 的升级版,性能优秀,适合做单机本地缓存。下面按步骤说明。

步骤

1. 配置 CacheManager

先创建一个配置类 `CachesConfig`,在里面声明一个 `CaffeineCacheManager` 的 `@Bean`,并指定缓存名称和过期策略。

SpringBoot整合缓存方式(Caffeine、Redis)

2. 在实现类中使用 @Cacheable

在 Service 实现类中,用 `@Cacheable` 注解指定 value(缓存名)和 cacheManager(指向上面定义的 Bean 名称)。这里有个关键点:如果你的配置类中定义了多个不同的 `CacheManager`,必须明确指定要用哪一个,否则 Spring 会报 Bean 冲突。解决办法有两个:要么用 `@Primary` 标记默认的那个,要么像下面这样在注解里写死 cacheManager。

SpringBoot整合缓存方式(Caffeine、Redis)

  • 其中 `value` 对应配置类中创建的缓存名称(如 `demoCache`),`cacheManager` 必填,指定注入的 `@Bean` 名字。
  • 之所以要这样,是因为如果 `CachesConfig` 中同时存在多个缓存引擎的 Bean(都实现了 `CacheManager` 接口),就必须要用 `@Primary` 或显式指定才能避免冲突。

3. 验证缓存效果

启动项目后,调用接口看看控制台输出。第一次会打印“模拟去db查询”,第二次就不会了,说明命中缓存。然后等缓存过期(本例设置 5 秒),再次调用,又会重新查询。

SpringBoot整合缓存方式(Caffeine、Redis)

SpringBoot整合缓存方式(Caffeine、Redis)

代码

**CachesConfig 配置类**
@Configuration
@EnableCaching
public class CachesConfig {
    @Bean(value = "getCaffeineCacheManager")
    public CaffeineCacheManager cacheManager() {
        CaffeineCacheManager cacheManager = new CaffeineCacheManager();
        Cache cache = Caffeine.newBuilder()
                .expireAfterWrite(5, TimeUnit.SECONDS)
                .maximumSize(10_000)
                .build();
        cacheManager.registerCustomCache("demoCache", cache);
        return cacheManager;
    }
}
**CachesController 控制层**
@RestController
@RequestMapping(value = "cachesController")
public class CachesController {
    @Autowired
    private CachesService cachesService;
    @Autowired
    @Qualifier("getCaffeineCacheManager")
    private CaffeineCacheManager caffeineCacheManager;

    @GetMapping("playCaffeineCaches")
    public  T playCaffeineCaches() throws InterruptedException {
        System.out.println(cachesService.getFromDB(1));
        System.out.println(cachesService.getFromDB(1));

        // 校验缓存里的内容
        Cache demoCache = Objects.requireNonNull(caffeineCacheManager.getCache("demoCache"));
        String s = demoCache.get(1, String.class);
        System.out.println(s);
        // 由于设定Caffeine的过期时间为5s,检验超时后缓存是否失效
        TimeUnit.SECONDS.sleep(10);
        s = demoCache.get(1, String.class);
        System.out.println(s);
        return (T) s;
    }
}
**CacheServiceImpl 实现类**
@Service
@CacheConfig(cacheNames = {"com.devilvan.config.CachesConfig"})
public class CacheServiceImpl implements CachesService {
    @Cacheable(value = {"demoCache"}, cacheManager = "getCaffeineCacheManager", key = "#id")
    @Override
    public Object getFromDB(Integer id) {
        System.out.println("模拟去db查询~~~" + id);
        return "hello cache...";
    }
}
---

整合Redis缓存

Redis 作为分布式缓存,适合多实例共享的场景。整合方式和 Caffeine 类似,但需要多配置一个 `RedisTemplate` 和自定义的 `RedisCacheManager`。

步骤

1. 定义 RedisTemplate 的 Bean

虽然直接用 `RedisTemplate` 的默认配置也能跑,但通常我们会自定义序列化方式。下面是一个常见的配置。

SpringBoot整合缓存方式(Caffeine、Redis)

2. 配置 RedisCacheManager

在配置类中注入上面定义的 `RedisTemplate`,然后构造 `RedisCacheManager`。这里可以针对不同的缓存名称(`cacheNames`)指定不同的过期时间,非常灵活。

SpringBoot整合缓存方式(Caffeine、Redis)

3. 在实现类中使用注解

分别用 `@Cacheable`(查询)、`@CachePut`(更新)、`@CacheEvict`(删除)来标记对应的操作方法,并指定 cacheManager 为上面定义的 Bean。

SpringBoot整合缓存方式(Caffeine、Redis)

参数说明

cacheManager

指的是配置类中定义的 `CacheManager` 实现类 Bean 的名字。这里我们用的是 `empRedisCacheManager`。

cacheNames

就是缓存区域的名字。如果这个名字与配置类中 `withCacheConfiguration()` 方法里设置的名字匹配,就会使用该方法指定的独立配置(比如过期时间 60 秒 vs 120 秒)。

key

通常绑定方法参数,作为缓存的唯一标识。当 key 对应值不存在时,执行方法逻辑并写入缓存;存在则直接返回。

代码

**CachesConfig 配置类(Redis部分)**
/**
 * 自定义redisTemplate
 */
@Bean
public RedisTemplate empRedisTemplate(
        RedisConnectionFactory redisConnectionFactory) {
    RedisTemplate template = new RedisTemplate<>();
    template.setConnectionFactory(redisConnectionFactory);
    // 转换 格式
    template.setKeySerializer(new StringRedisSerializer());
    template.setValueSerializer(new StringRedisSerializer());
    template.setHashKeySerializer(new StringRedisSerializer());
    template.setHashValueSerializer(new StringRedisSerializer());
    return template;
}

/**
 * 基于SpringBoot2 对 RedisCacheManager 的自定义配置
 */
@Bean("empRedisCacheManager")
@Primary
public RedisCacheManager empRedisCacheManager(@Autowired @Qualifier("empRedisTemplate") RedisTemplate redisTemplate) {
    RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration
            .defaultCacheConfig()
            // 设置key为String
            .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getStringSerializer()))
            // 设置value 为自动转Json的Object
            .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getValueSerializer()))
            // 不缓存null
            .disableCachingNullValues()
            // 缓存数据保存30s
            .entryTtl(Duration.ofSeconds(30));
    // 构造一个redis缓存管理器
    RedisCacheManager redisCacheManager = RedisCacheManager
            .RedisCacheManagerBuilder
            // Redis 连接工厂
            .fromConnectionFactory(Objects.requireNonNull(redisTemplate.getConnectionFactory()))
            // 设置默认缓存配置
            .cacheDefaults(redisCacheConfiguration)
            // 设置自定义缓存配置,缓存名为cache_user,它的过期时间为60s
            .withCacheConfiguration("cache_user", redisCacheConfiguration.entryTtl(Duration.ofSeconds(60)))
            // 上面默然缓存时间是1小时,但是可以根据cacheName来设置缓存时间
            .withCacheConfiguration("cache_post", redisCacheConfiguration.entryTtl(Duration.ofSeconds(120)))
            // 配置同步修改或删除 put/evict
            .transactionAware()
            .build();
    return redisCacheManager;
}
**CachesController 控制层(Redis部分)**
@GetMapping("playRedisCaches")
public  T playRedisCaches(@RequestParam("id") Integer id) {
    System.out.println(cachesService.getDept(id));
    System.out.println(cachesService.getDept(id));
    return (T) null;
}

@PostMapping("updateRedisCaches")
public  T updateRedisCaches(@RequestParam("id") Integer id) {
    System.out.println(cachesService.updateDept(id));
    System.out.println(cachesService.getDept(id));
    return (T) null;
}

@DeleteMapping("deleteRedisCaches")
public  T deleteRedisCaches(@RequestParam("id") Integer id) {
    cachesService.deleteDept(id);
    System.out.println(cachesService.getDept(id));
    return (T) null;
}
**CachesServiceImpl 实现类(Redis部分)**
@Cacheable(cacheManager = "empRedisCacheManager", cacheNames = {"dept"}, key = "#id")
@Override
public String getDept(Integer id) {
    System.out.println("查询"+ id  +"号部门。" );
    int i = new Random().nextInt(65535);
    int hashCode = String.valueOf((id + i)).hashCode();
    return "Do you like what you see?" + "-->" +hashCode;
}

@CachePut(cacheManager = "empRedisCacheManager", cacheNames = {"dept"}, key = "#id")
@Override
public String updateDept(Integer id) {
    System.out.println("更新"+ id  +"号部门。" );
    int i = new Random().nextInt(65535);
    int hashCode = String.valueOf((id + i)).hashCode();
    return "Do you like what you see?" + "-->" +hashCode;
}

@CacheEvict(cacheManager = "empRedisCacheManager", cacheNames = {"dept"}, key = "#id")
@Override
public void deleteDept(Integer id) {
    System.out.println("删除"+ id  +"号部门。" );
}

总结

这两套方案各有侧重:Caffeine 胜在轻量、极速,适合单机毫秒级响应;Redis 则强在共享和持久化,适合集群和跨进程缓存。实际项目中可以根据业务场景混合使用(比如热点数据放 Caffeine,低频数据放 Redis)。关键还是要理解注解背后的 `CacheManager` 机制,以及如何通过配置精细化控制过期时间、序列化方式。希望这份梳理能帮你快速上手,避开常见的坑。
本文转载于:https://www.jb51.net/program/363293slc.htm 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注