Spring boot Caffeine缓存(三)——使用注解

本文介绍了Spring Boot中使用Caffeine缓存的注解方式,包括@Cacheable、@CacheEvict、@CachePut的使用场景和区别,并提供了简单的代码示例。此外,还提到了@Caching用于组合多个缓存操作和@CacheConfig在类级别设置缓存配置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. Spring boot Caffeine缓存(一)——CacheManager与配置文件
  2. Spring boot Caffeine缓存(二)——Cache、LoadingCache
  3. Spring boot Caffeine缓存(三)——使用注解

注解在Spring中的应用很广泛,几乎成为了其标志,这里说下使用注解来集成缓存。
cache方面的注解主要有以下5个

  • @Cacheable 触发缓存入口(这里一般放在创建和获取的方法上)
  • @CacheEvict 触发缓存的eviction(用于删除的方法上)
  • @CachePut 更新缓存且不影响方法执行(用于修改的方法上,该注解下的方法始终会被执行)
  • @Caching 将多个缓存组合在一个方法上(该注解可以允许一个方法同时设置多个注解)
  • @CacheConfig 在类级别设置一些缓存相关的共同配置(与其它缓存配合使用)

上边5个注解中目前我学习的时候使用了前三个,所以这里主要针对前三个来展开,后边两个结合spring官方文档来简单介绍下。

@Cacheable

先看看它的源码

public @interface Cacheable {
   
   

    /**
     * 设定要使用的cache的名字,必须提前定义好缓存
     */
    @AliasFor("cacheNames")
    String[] value() default {};

    /**
     * 同value(),决定要使用那个/些缓存
     */
    @AliasFor("value")
    String[] cacheNames() default {};

    /**
     * 使用SpEL表达式来设定缓存的key,如果不设置默认方法上所有参数都会作为key的一部分
     */
    String key() default "";

    /**
     * 用来生成key,与key()不可以共用
     */
    String keyGenerator() default "";

    /**
     * 设定要使用的cacheManager,必须先设置好cacheManager的bean,这是使用该bean的名字
     */
    String cacheManager() default "";

    /**
     * 使用cacheResolver来设定使用的缓存,用法同cacheManager,但是与cacheManager不可以同时使用
     */
    String cacheResolver() default 
<think>我们正在讨论Spring Boot中同时集成Caffeine和Redis缓存的问题。根据引用内容,我们可以确认这是可行的,并且通常用于构建两级缓存(本地缓存+分布式缓存)系统。 引用[1]提到“Spring Boot 使用多级缓存 {Caffeine+Redis}”,并给出了快速入门的示例。 引用[2]解释了在分布式环境下使用Redis的发布/订阅功能来同步各个节点的缓存,解决一致性问题。 引用[3]则展示了具体的配置代码,其中通过条件注解@ConditionalOnProperty来控制本地缓存Caffeine)的开关。 因此,我们可以分步骤解释如何在Spring Boot中同时集成Caffeine和Redis: 步骤1:添加Maven依赖 需要同时添加spring-boot-starter-cache(用于支持Spring缓存抽象)、spring-boot-starter-data-redis(用于Redis)和caffeine(用于本地缓存)的依赖。 步骤2:配置缓存 在application.properties或application.yml中配置Redis和Caffeine的相关属性。 步骤3:启用缓存 在启动类上添加@EnableCaching注解。 步骤4:配置多级缓存 如引用[3]所示,可以创建配置类来定义Redis缓存Caffeine缓存,并且通过条件注解来控制Caffeine缓存的启用。 步骤5:使用缓存 在业务代码中,可以使用@Cacheable注解使用缓存。同时,为了支持多级缓存,可能需要自定义缓存管理器,将Caffeine作为一级缓存,Redis作为二级缓存。 引用[2]提到,为了解决分布式环境下本地缓存不一致的问题,可以使用Redis的发布/订阅功能来同步各个节点的缓存。 下面是一个简化的示例代码,展示如何配置多级缓存: ```java @Configuration @EnableCaching public class CacheConfig { // 配置Redis连接工厂 @Bean public RedisConnectionFactory redisConnectionFactory() { return new LettuceConnectionFactory(); } // 配置RedisTemplate @Bean public RedisTemplate<String, Object> redisTemplate() { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(redisConnectionFactory()); template.setKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); return template; } // 配置Redis缓存管理器 @Bean public RedisCacheManager redisCacheManager(RedisTemplate<String, Object> redisTemplate) { RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate); cacheManager.setTransactionAware(true); cacheManager.setLoadRemoteCachesOnStartup(true); cacheManager.setUsePrefix(true); return cacheManager; } // 配置Caffeine缓存管理器 @Bean public CaffeineCacheManager caffeineCacheManager() { CaffeineCacheManager cacheManager = new CaffeineCacheManager(); cacheManager.setCaffeine(Caffeine.newBuilder() .expireAfterWrite(10, TimeUnit.MINUTES) .maximumSize(1000)); return cacheManager; } // 配置多级缓存管理器(组合Caffeine和Redis) @Primary @Bean public CacheManager multiLevelCacheManager(CaffeineCacheManager caffeineCacheManager, RedisCacheManager redisCacheManager) { // 这里需要自定义一个组合缓存管理器,可以使用已有的开源实现或者自己实现 // 通常,读取时先读本地缓存,再读Redis;写入时同时写入两级缓存 // 注意:需要处理缓存同步和一致性问题 return new MultiLevelCacheManager(caffeineCacheManager, redisCacheManager); } } ``` 注意:上述代码中的MultiLevelCacheManager需要自定义实现,它负责协调两级缓存。同时,为了保持缓存一致性,当数据更新时,需要使所有节点的一级缓存失效,这可以通过Redis的发布/订阅机制实现(如引用[2]所述)。 另外,引用[3]中提到了使用条件注解来控制本地缓存的开关,我们可以这样实现: ```java @Configuration @ConditionalOnProperty(name = "cache.local.enabled", havingValue = "true") public class LocalCacheConfig { // 配置本地缓存相关的Bean } ``` 这样,通过配置文件中的`cache.local.enabled`属性,可以动态开启或关闭本地缓存。 综上所述,Spring Boot可以同时集成Caffeine和Redis,构建多级缓存系统,并通过配置灵活控制。 生成相关问题: 1. 如何自定义多级缓存管理器(MultiLevelCacheManager)? 2. 如何利用Redis的发布/订阅实现缓存同步? 3. 在Spring Boot中配置多级缓存时,需要注意哪些问题?</think>在 Spring Boot 项目中,**可以同时集成 Caffeine 和 Redis 缓存**,形成多级缓存架构(本地缓存 + 分布式缓存)。这种组合能显著提升系统性能,同时解决分布式环境下的缓存一致性问题。以下是关键实现方案: --- ### **一、实现原理** 1. **两级缓存架构** - **一级缓存(本地)**:使用 Caffeine 提供超高速访问(纳秒级响应),适合高频访问的热点数据。 - **二级缓存(分布式)**:使用 Redis 保证多节点间数据一致性,作为后备存储。 ```mermaid graph LR A[应用] --> B[Caffeine 本地缓存] B -->|缓存未命中| C[Redis 分布式缓存] C -->|缓存未命中| D[数据库] ``` 2. **缓存同步机制** - 通过 Redis 的 **发布/订阅(Pub/Sub)** 功能同步各节点的本地缓存(如引用[2]所述)。 - 当某节点修改数据时,发布消息使其他节点失效本地缓存。 --- ### **二、集成步骤** #### 1. **添加 Maven 依赖** ```xml <!-- Caffeine --> <dependency> <groupId>com.github.ben-manes.caffeine</groupId> <artifactId>caffeine</artifactId> </dependency> <!-- Redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> ``` #### 2. **启用缓存(启动类)** ```java @SpringBootApplication @EnableCaching // 开启缓存抽象 public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ``` #### 3. **配置多级缓存管理器** ```java @Configuration public class CacheConfig { @Bean public CacheManager cacheManager(RedisConnectionFactory factory) { // Caffeine 作为一级缓存(本地) CaffeineCacheManager caffeineCacheManager = new CaffeineCacheManager(); caffeineCacheManager.setCaffeine(Caffeine.newBuilder() .expireAfterWrite(10, TimeUnit.MINUTES) // 本地缓存过期时间 .maximumSize(1000) ); // Redis 作为二级缓存(分布式) RedisCacheManager redisCacheManager = RedisCacheManager.create(factory); // 组合多级缓存(优先本地,其次Redis) return new MultiLevelCacheManager(caffeineCacheManager, redisCacheManager); } } ``` #### 4. **实现缓存同步(关键)** 通过 Redis 发布/订阅同步本地缓存失效(如引用[2]): ```java @Bean public RedisMessageListenerContainer container(RedisConnectionFactory factory) { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(factory); container.addMessageListener(new MessageListenerAdapter(this), new ChannelTopic("cache-invalidate")); return container; } // 收到消息时失效本地缓存 public void handleMessage(String cacheKey) { caffeineCacheManager.getCache(cacheKey).clear(); } ``` #### 5. **动态开关本地缓存(如引用[3])** ```java @Configuration @ConditionalOnProperty( // 通过配置控制开关 name = "cache.local.enabled", havingValue = "true", matchIfMissing = false ) public class LocalCacheConfig { @Bean public CaffeineCacheManager caffeineCacheManager() { // 本地缓存配置 } } ``` 配置文件 `application.yml`: ```yaml cache: local: enabled: true # 动态启用/禁用 Caffeine ``` --- ### **使用缓存示例** ```java @Service public class UserService { @Cacheable(value = "users", key = "#id") // 自动使用多级缓存 public User getUserById(Long id) { return userRepository.findById(id); // 数据库查询 } @CacheEvict(value = "users", key = "#id") public void updateUser(User user) { // 更新数据后发布缓存失效消息 redisTemplate.convertAndSend("cache-invalidate", "users:" + user.getId()); } } ``` --- ### **四、优势与适用场景** | **优势** | **适用场景** | |-------------------------|----------------------------------| | **高性能**:Caffeine 本地缓存响应极快 | 高频读取的热点数据(如商品详情) | | **一致性**:Redis 保证多节点同步 | 分布式集群环境 | | **灵活性**:动态开关本地缓存 | 测试环境降级、流量高峰控制 | > **注意**:需权衡本地缓存带来的内存消耗,建议通过 `maximumSize` 限制缓存条目(如引用[3])。 --- ### **相关问题** 1. 如何解决 Caffeine 和 Redis 之间的数据一致性问题? 2. 在多级缓存架构中,如何设计缓存穿透和雪崩的保护机制? 3. 如何监控 Spring BootCaffeine 和 Redis 的缓存命中率? [^1]: Spring Boot 使用多级缓存 {Caffeine+Redis},快速入门示例 [^2]: 基于 Redis 发布/订阅实现分布式缓存同步 [^3]: 通过 `@ConditionalOnProperty` 动态控制本地缓存开关
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值