导读:本期聚焦于大海创作的《如何在Spring Boot中通过@EnableCaching注解快速开启缓存支持?》,敬请观看详情。缓存是提升接口响应速度的关键手段,但不少人在Spring Boot里开启缓存时总弄不清注解该放哪。@EnableCaching本质是利用ImportSelector向容器注入CacheInterceptor等后置处理器,从而拦截带缓存注解的方法。实际整合时,仅添加该注解还不够,还需配置CacheManager指明底层存储,比如使用ConcurrentMap或Redis。若未指定管理器,应用启动会抛NoSuchBeanDefinitionException。相比手动写缓存逻辑,该方案减少大量模板代码,不过分布式场景下必须选Redis等集中式缓存,否则多实例间数据不一致。

在Spring Boot应用里,想要让方法结果被自动缓存起来,最便捷的方式就是使用@EnableCaching注解。这个注解本身只是一个开关,它告诉Spring框架去激活缓存基础设施,之后我们就可以在业务方法上用@Cacheable、@CachePut、@CacheEvict等注解来管理缓存。理解它的整合过程,有助于我们在单体或分布式系统中正确落地缓存方案。

如何在Spring Boot中通过@EnableCaching注解快速开启缓存支持?

@EnableCaching的底层启用原理

从源码角度看,@EnableCaching是一个组合注解,它内部通过@Import引入了CachingConfigurationSelector。这个类实现了ImportSelector接口,在Spring容器启动阶段会被调用,进而向容器中注册一系列处理缓存注解的Bean,例如CacheInterceptor、CacheAnnotationParser以及负责代理创建的AutoProxyCreator。也就是说,加了该注解后,Spring会为标注了缓存注解的Bean生成代理对象,方法调用前后由拦截器根据注解配置读写缓存。

很多初学者误以为只要写了@EnableCaching就会产生缓存效果,其实它只是启用了“能力”,并没有指定“存到哪里”。如果项目中没有定义CacheManager类型的Bean,Spring Boot在早些版本会尝试使用ConcurrentMapCacheManager作为默认实现,但在某些自动配置条件下仍可能因缺少明确管理器而报错。因此我们通常会在配置类上写@EnableCaching,并同时显式声明一个CacheManager。

下面是一段典型的开启与配置代码,展示了注解位置和缓存管理器的声明方式:

@Configuration
@EnableCaching
public class CacheConfig {

    @Bean
    public CacheManager cacheManager() {
        // 使用简单的内存缓存,适用于单机演示
        return new ConcurrentMapCacheManager("userCache", "orderCache");
    }
}

基于Redis的集中式缓存整合实践

当应用以多实例部署时,使用本地内存缓存会造成各节点数据不一致,此时应当整合Redis。Spring Boot通过spring-boot-starter-data-redis提供了RedisConnectionFactory,我们再将其包装为RedisCacheManager即可。这种方案下,@EnableCaching依然只需要标注一次,真正变化的是CacheManager的实现类。

在配置Redis缓存管理器时,建议明确设置过期时间和序列化方式。例如采用Jackson2JsonRedisSerializer可以避免Java原生序列化带来的体积膨胀与版本兼容问题。下面的代码演示了如何构建一个带默认过期时间的Redis缓存管理器,并开启@EnableCaching:

@Configuration
@EnableCaching
public class RedisCacheConfig {

    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofMinutes(30))
                .serializeValuesWith(RedisSerializationContext
                        .SerializationPair.fromSerializer(new Jackson2JsonRedisSerializer<Object>(Object.class)));
        return RedisCacheManager.builder(factory).cacheDefaults(config).build();
    }
}

使用Redis作为后端后,业务层方法只需标注@Cacheable即可,例如@Cacheable(value = "userCache", key = "#id")会让方法在第一次以某id调用时查库并写入Redis,后续同id调用直接走缓存。需要注意key的生成策略,若不加key参数,默认用所有参数生成Key,复杂参数需实现KeyGenerator以免产生过长或冲突的键。

缓存注解的使用误区与整合排错

在Spring Boot整合@EnableCaching后,最常见的误区是在私有方法或类内部调用上加缓存注解。由于Spring缓存基于代理机制,自调用(this.method())不会经过代理,注解完全失效。此外,@CacheEvict若未指定beforeInvocation,默认在方法成功后才清除缓存,若方法抛异常则缓存不会被清理,这可能引发脏数据。

另一个容易忽略的点是:当项目中存在多个CacheManager时,必须在@EnableCaching的环境下通过@Primary标注主管理器,或在注解中用cacheManager属性指定。否则启动会报NoUniqueBeanDefinitionException。下表列出了两种典型整合方式的特点:

缓存管理器适用场景一致性
ConcurrentMapCacheManager单机开发测试进程内,重启即丢
RedisCacheManager分布式生产环境多实例共享,需维护Redis

排查缓存不生效问题时,可以开启DEBUG日志观察CacheInterceptor是否打印命中记录,或者在配置类上临时加入@EnableCaching(proxyTargetClass = true)来强制使用CGLIB代理,以避免基于接口的JDK代理导致的注入类型不匹配。整体来看,Spring Boot整合@EnableCaching是一条低成本提升性能的清晰路径,只要理清管理器与代理机制,就能稳定落地。

Spring_BootEnableCaching缓存整合修改时间:2026-08-19 03:38:29

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。