From 09ef597836edbde9908e4687cca29c9536fe28e8 Mon Sep 17 00:00:00 2001 From: Nick Date: Thu, 30 Sep 2021 22:40:21 +0300 Subject: [PATCH] Avoid duplicate JCacheOperationSource bean registration in In our application we use XML context and declaration. Also we disable bean definition duplication by setting GenericApplicationContext.setAllowBeanDefinitionOverriding(false) in an ApplicationContextInitializer. This combination leads to a BeanDefinitionOverrideException because the DefaultJCacheOperationSource bean is registered twice. - once for: parserContext.getReaderContext().registerWithGeneratedName(sourceDef); - once for: parserContext.registerBeanComponent(new BeanComponentDefinition(sourceDef, sourceName)); This commit refactors JCacheCachingConfigurer.registerCacheAspect(...) so that the JCacheOperationSource bean is registered only once. Closes gh-27499 --- .../AnnotationDrivenCacheBeanDefinitionParser.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/cache/config/AnnotationDrivenCacheBeanDefinitionParser.java b/spring-context/src/main/java/org/springframework/cache/config/AnnotationDrivenCacheBeanDefinitionParser.java index 41c0bbc7b6d5..c7466616d496 100644 --- a/spring-context/src/main/java/org/springframework/cache/config/AnnotationDrivenCacheBeanDefinitionParser.java +++ b/spring-context/src/main/java/org/springframework/cache/config/AnnotationDrivenCacheBeanDefinitionParser.java @@ -245,16 +245,20 @@ private static void registerCacheAdvisor(Element element, ParserContext parserCo private static void registerCacheAspect(Element element, ParserContext parserContext) { if (!parserContext.getRegistry().containsBeanDefinition(CacheManagementConfigUtils.JCACHE_ASPECT_BEAN_NAME)) { Object eleSource = parserContext.extractSource(element); + + BeanDefinition sourceDef = createJCacheOperationSourceBeanDefinition(element, eleSource); + String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef); + RootBeanDefinition def = new RootBeanDefinition(); def.setBeanClassName(JCACHE_ASPECT_CLASS_NAME); def.setFactoryMethodName("aspectOf"); - BeanDefinition sourceDef = createJCacheOperationSourceBeanDefinition(element, eleSource); - String sourceName = - parserContext.getReaderContext().registerWithGeneratedName(sourceDef); def.getPropertyValues().add("cacheOperationSource", new RuntimeBeanReference(sourceName)); + parserContext.getRegistry().registerBeanDefinition(CacheManagementConfigUtils.JCACHE_ASPECT_BEAN_NAME, def); - parserContext.registerBeanComponent(new BeanComponentDefinition(sourceDef, sourceName)); - parserContext.registerBeanComponent(new BeanComponentDefinition(def, CacheManagementConfigUtils.JCACHE_ASPECT_BEAN_NAME)); + CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource); + compositeDef.addNestedComponent(new BeanComponentDefinition(sourceDef, sourceName)); + compositeDef.addNestedComponent(new BeanComponentDefinition(def, CacheManagementConfigUtils.JCACHE_ASPECT_BEAN_NAME)); + parserContext.registerComponent(compositeDef); } }