在Sping Boot 中,我想使用一个定义为bean的缓存管理器加上application.yaml中定义的Redis缓存。但是在定义缓存管理器(如bean)后,application.yaml中的另一个被忽略了。
@Bean
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager(LDAP_CACHE_NAME) {
@Override
protected Cache createConcurrentMapCache(final String name) {
return new ConcurrentMapCache(name, CacheBuilder.newBuilder().expireAfterWrite(30, TimeUnit.SECONDS).maximumSize(100).build().asMap(), false);
}
};
}
application.yaml:
spring:
redis:
host: localhost
cache:
type: redis
cache-names: REDISCACHE
cache-specs:
myCustomCache:
time-to-live: 600s
1条答案
按热度按时间y4ekin9u1#
使用Sping Boot ,您不需要显式定义/声明
CacheManager
bean。例如,当
spring-boot-starter-cache
(here)和spring-boot-starter-data-redis
(here)依赖项都在Sping Boot 应用程序类路径上声明时,Spring Boot将自动为您配置CacheManager
bean。此外,请查看start.spring.io
的此链接,这将帮助您开始。您仍然需要启用缓存,方法是在一个Spring应用程序
@Configuration
类上声明Spring缓存@EnableCaching
注解(参见文档),但您不需要显式声明CacheManager
bean。这样做实际上会覆盖Sping Boot 中的自动配置,并且在您的情况下,特别是Sping Boot 自动配置类(source)(对于Redis)。请参阅Spring Boot为您提供的RedisCacheManager
bean。警告:如果您的Sping Boot 应用程序类路径上一次有多个缓存提供程序,则需要显式声明您打算使用哪个提供程序进行缓存。您可以使用Spring Boot
application.properties
或application.yaml
文件中的spring.cache.type
属性来执行此操作。请参阅文档部分中的第一个“提示”。提示:您甚至可以通过声明
RedisCacheManagerBuilderCustomizer
(Javadoc,source)类型的bean来自定义Sping Boot 自动配置的基于Redis的CacheManager
bean。因此,通过声明显式的
CacheManager
bean(ConcurrentMapCacheManager
bean,不少于),您有效地完成了覆盖Sping Boot 的自动配置(例如,this)。也就是说,Spring Boot只会自动配置RedisCacheManager
bean,如果您自己没有显式地这样做。这就是当Sping Boot 说“convention over configuration”时的意思,除非您显式指定自己,然后Spring Boot悄悄地后退并假设您知道自己在做什么(查看更多细节,在这里)。
更糟糕的是,你声明了一个
ConcurrentMapCacheManager
bean,它不会在Redis中使用或存储任何东西,作为缓存提供者。它只会使用内存中的ConcurrentMap
(准确地说是java.util.concurrent.ConcurrentHashMap
)来缓存Sping Boot 应用程序服务方法的结果,从而完全绕过Redis。所以,你无意中搬起石头砸了自己的脚,;- )
希望这有帮助!