Avoid duplicate JCacheOperationSource bean registration in <cache:annotation-driven />#27499
Avoid duplicate JCacheOperationSource bean registration in <cache:annotation-driven />#27499nivolg wants to merge 1 commit into
Conversation
In our application we use xml context and <cache:annotation-driven /> declaration. Also we disable bean definition duplication by setting GenericApplicationContext.setAllowBeanDefinitionOverriding(false) in ApplicationContextInitializer. Such combination leads to BeanDefinitionOverrideException because bean "org.springframework.cache.jcache.interceptor.DefaultJCacheOperationSource" is registered twice: String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef); parserContext.registerBeanComponent(new BeanComponentDefinition(sourceDef, sourceName));
|
@nivolg Please sign the Contributor License Agreement! Click here to manually synchronize the status of this Pull Request. See the FAQ for frequently asked questions. |
|
@pivotal-cla This is an Obvious Fix |
|
@nivolg This Pull Request contains an obvious fix. Signing the Contributor License Agreement is not necessary. |
|
Thanks for the report and PR @nivolg. I wasn't able to reproduce the problem with a vanilla project started from start.spring.io. Please look at it and let us know what is missing. If it turns out that a change is required in Spring Framework, I unfortunately disagree that this is an obvious fix so you'll have to sign the CLA. |
|
@nivolg Thank you for signing the Contributor License Agreement! |
|
Thanks for quick response. I can't access your vanilla project repopsitory. But I made example project to reproduce the issue. I missed an important details in description: aspectj and jcache are used together. Also I signed CLA. |
|
@nivolg bummer, it got created as private by default, sorry about that. Thank you for the sample, I missed the aspectJ bits. |
|
Thanks for the repro project. I have confirmed that the following exception occurs. But I have not yet confirmed the proposed fix. We'll look into this. |
| Object eleSource = parserContext.extractSource(element); | ||
|
|
||
| BeanDefinition sourceDef = createJCacheOperationSourceBeanDefinition(element, eleSource); | ||
| String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef); |
There was a problem hiding this comment.
| String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef); | |
| String sourceName = parserContext.getReaderContext().generateBeanName(sourceDef); |
This would be a simpler fix, since it avoids the undesired side effect of registering the bean when generating the name (and the rest of the code can remain unchanged), but I think your CompositeComponentDefinition proposal is more in line with how components are handled for XML namespaces. So we'll go with that.
There was a problem hiding this comment.
Thanks for review. I understand what you mean.
I thought about such simpler fix but read the methods above and decided that CompositeComponentDefinition is required for some reasons I don't know.
There was a problem hiding this comment.
The CompositeComponentDefinition is not technically required.
It's really just there for tooling support. Without it, the application would work the same.
…otation-driven /> In our application we use XML context and <cache:annotation-driven /> 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 spring-projectsgh-27499
Hello.
In our application we use XML context and
<cache:annotation-driven mode="aspectj"/>declaration in combination with JCache API. Also we disable bean definition overrides by settingGenericApplicationContext.setAllowBeanDefinitionOverriding(false)in anApplicationContextInitializer.Such combination leads to
BeanDefinitionOverrideExceptionbecause the bean "org.springframework.cache.jcache.interceptor.DefaultJCacheOperationSource" is registered twice: