如何通过配置属性启用/禁用Spring Boot中的Caffeine缓存
我完全理解你的痛点——每次要开关缓存都得注释代码、重新构建部署实在太麻烦了。其实Spring Boot提供了多种优雅的方式,让你通过配置属性就能在启动时启用或禁用缓存,完全不用改代码。下面给你几个可行的方案:
方案一:全局开关——用@ConditionalOnProperty控制缓存配置类加载
这是最直接的全局解决方案:给你的缓存配置类加上@ConditionalOnProperty注解,只有当指定配置属性为true时,整个配置类(包括@EnableCaching)才会被Spring加载。
修改你的ReportCacheConfiguration:
@Configuration @EnableCaching // 当my.property.cache.enabled为true时生效,默认启用缓存 @ConditionalOnProperty(name = "my.property.cache.enabled", havingValue = "true", matchIfMissing = true) class ReportCacheConfiguration { @Bean CacheManagerCustomizer<CaffeineCacheManager> cacheManagerCustomizer(MeterRegistry registry) { return cacheManager -> cacheManager.registerCustomCache("report", reportCache()); } private Cache<Object, Object> reportCache() { return Caffeine.newBuilder() .expireAfterWrite(1, TimeUnit.MINUTES) .build(); } }
怎么用:
- 启用缓存(默认行为,和你原来的代码效果一致):
在application.properties里不用加任何配置,或者显式设置:my.property.cache.enabled=true - 禁用缓存:
只需要修改配置:
或者在启动应用时通过JVM参数指定:my.property.cache.enabled=falsejava -jar your-app.jar -Dmy.property.cache.enabled=false
当配置为false时,Spring会完全忽略这个配置类,@EnableCaching不生效,所有@Cacheable注解都会被跳过,直接执行方法体里的昂贵操作。
方案二:精细控制——给单个@Cacheable方法加开关
如果不需要全局禁用所有缓存,只想控制某个特定的缓存方法(比如findBook),可以在@Cacheable注解里用SpEL表达式结合配置属性,控制注解是否生效:
修改你的BookServiceImpl:
@Service public class BookServiceImpl implements BookService { // 只有当配置属性为true时,缓存才生效 @Cacheable( cacheNames = "report", condition = "#{@environment.getProperty('my.property.cache.enabled', 'true') == 'true'}" ) public Book findBook(String isbn) { // 昂贵的网络+数据库操作 return new Book(...); } }
这种方式的好处是可以针对不同的缓存方法设置不同的开关,灵活性更高。
方案三:全局空缓存——用NoOpCacheManager禁用缓存
如果你需要保留@EnableCaching的上下文(比如有些监控或其他功能依赖缓存框架),但实际不缓存任何数据,可以在禁用缓存时注册一个空的缓存管理器NoOpCacheManager:
@Configuration @EnableCaching class CacheConfiguration { // 启用缓存时,用Caffeine配置 @Bean @ConditionalOnProperty(name = "my.property.cache.enabled", havingValue = "true", matchIfMissing = true) CacheManagerCustomizer<CaffeineCacheManager> caffeineCacheManagerCustomizer(MeterRegistry registry) { return cacheManager -> cacheManager.registerCustomCache("report", reportCache()); } // 禁用缓存时,用空缓存管理器 @Bean @ConditionalOnProperty(name = "my.property.cache.enabled", havingValue = "false") CacheManager noOpCacheManager() { return new NoOpCacheManager(); } private Cache<Object, Object> reportCache() { return Caffeine.newBuilder() .expireAfterWrite(1, TimeUnit.MINUTES) .build(); } }
NoOpCacheManager是Spring提供的空实现,它会接受所有缓存操作,但不会实际存储任何数据,所有请求都会直接执行方法体。
总结
这几个方案都能帮你告别“注释代码→构建→部署”的低效流程:
- 如果你要全局开关缓存,优先选方案一,简单高效;
- 如果你需要精细控制单个缓存方法,选方案二;
- 如果你需要保留缓存框架上下文但不实际缓存,选方案三。
只需要修改配置或者启动参数,重启应用就能切换缓存状态,完全不用动代码。
备注:内容来源于stack exchange,提问作者PatPanda

