java – 默认情况下,Spring的CacheInterceptor正在覆盖自定义CacheInterceptor
作者:互联网
我已经实现了一个自定义CacheInterceptor,允许通过通配符驱逐缓存:
public class CustomCacheInterceptor extends CacheInterceptor {
private static final Logger LOGGER = LoggerFactory.getLogger(CustomCacheInterceptor.class);
@Override
protected void doEvict(Cache cache, Object key) {
try {
// evict cache
} catch (RuntimeException ex) {
getErrorHandler().handleCacheEvictError(ex, cache, key);
}
}
}
现在我正努力让它发挥作用:
@Configuration
public class CustomProxyCachingConfiguration extends ProxyCachingConfiguration {
private static final Logger LOGGER = LoggerFactory.getLogger(CustomProxyCachingConfiguration.class);
@Bean
public CacheInterceptor cacheInterceptor() {
LOGGER.info("Creating custom cache interceptor");
CacheInterceptor interceptor = new CustomCacheInterceptor();
interceptor.setCacheOperationSources(cacheOperationSource());
if (this.cacheResolver != null) {
interceptor.setCacheResolver(this.cacheResolver);
} else if (this.cacheManager != null) {
interceptor.setCacheManager(this.cacheManager);
}
if (this.keyGenerator != null) {
interceptor.setKeyGenerator(this.keyGenerator);
}
if (this.errorHandler != null) {
interceptor.setErrorHandler(this.errorHandler);
}
return interceptor;
}
}
问题是我的CustomCacheInterceptor默认被覆盖了一个:
Overriding user-defined bean definition for bean 'cacheInterceptor' with a framework-generated bean definition: replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=customProxyCachingConfiguration; factoryMethodName=cacheInterceptor; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [com/package/test/CustomProxyCachingConfiguration.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.cache.annotation.ProxyCachingConfiguration; factoryMethodName=cacheInterceptor; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/cache/annotation/ProxyCachingConfiguration.class]]
我尝试了不同的方法来解决这个问题:
1)试图用@ComponentScan排除ProxyCachingConfiguration(excludeFilters = @ ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,value = ProxyCachingConfiguration.class))并提供自己的BeanFactoryCacheOperationSourceAdvisor – 没有帮助
2)试过@Primary但它似乎只在注射时工作 – 不是我的情况
3)尝试选择bean的不同名称 – “customCacheInterceptor” – 在这种情况下我的自定义类没有被调用
4)尝试添加位于ProxyCachinConfiguration中的@DependsOn(“cacheOperationSource”)以使Spring在我的配置之前加载ProxyCachinConfiguration – 没有帮助
最奇怪的是,有时我的配置在应用程序启动期间获胜并且一切正常
如何使用CustomCacheInterceptor覆盖默认的CacheInterceptor?
Spring Boot版本 – 2.0.0.RELEASE
解决方法:
Spring bean overriding是凌乱的,应该避免.给定名称的最后一个bean定义创建了实际的bean,但定义之间没有可预测的顺序,因为它取决于多个因素,例如: Groovy vs XML vs JavaConfig.
从您的上下文@ComponentScan中排除ProxyCachingConfiguration配置类并自己重新定义它会更安全,同时提供CacheInterceptor和BeanFactoryCacheOperationSourceAdvisor.
如果您的目标是仅替换默认BeanFactoryCacheOperationSourceAdvisor bean中的建议集,则可以定义新的BeanPostProcessor
bean并在postProcessBeforeInitialization()期间调用setAdvice().
标签:java,spring,spring-boot-2,spring-cache 来源: https://codeday.me/bug/20190710/1424223.html