I strongly recommend you debug the source code where the exception throw.
As I know the exception throw from this function "org.springframework.beans.factory.support.DefaultListableBeanFactory#registerBeanDefinition" in spring.
I copy a slice of code below:
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
Assert.hasText(beanName, "Bean name must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
((AbstractBeanDefinition) beanDefinition).validate();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
}
else if (existingDefinition.getRole() < beanDefinition.getRole()) {
// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
if (logger.isInfoEnabled()) {
logger.info("Overriding user-defined bean definition for bean '" + beanName +
"' with a framework-generated bean definition: replacing [" +
existingDefinition + "] with [" + beanDefinition + "]");
}
}
else if (!beanDefinition.equals(existingDefinition)) {
if (logger.isDebugEnabled()) {
logger.debug("Overriding bean definition for bean '" + beanName +
"' with a different definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Overriding bean definition for bean '" + beanName +
"' with an equivalent definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
this.beanDefinitionMap.put(beanName, beanDefinition);
}
else {
if (hasBeanCreationStarted()) {
// Cannot modify startup-time collection elements anymore (for stable iteration)
synchronized (this.beanDefinitionMap) {
this.beanDefinitionMap.put(beanName, beanDefinition);
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
removeManualSingletonName(beanName);
}
}
else {
// Still in startup registration phase
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
removeManualSingletonName(beanName);
}
this.frozenBeanDefinitionNames = null;
}
if (existingDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
else if (isConfigurationFrozen()) {
clearByTypeCache();
}
}
in above code you may found the exception BeanDefinitionOverrideException is exactly the root cause.
When I set a break point at
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
You may found out all your beans are save in beanDefinitionMap, and if two bean has the same name, and the second bean called this map.get(beanName), it will retrieve the bean with the same name generate in pre process. and thus will trigger the exception!!
So now what you need to do is to compare this two bean. and found where did it come from. If it comes from xml or some Configuration code.
and these is a debug skill you can paste the override bean name, in this case is "elasticsearchTemplate". But in my case the name is "org.springframework.cache.config.internalCacheAdvisor" like my exception shows like :
Description:The bean 'org.springframework.cache.config.internalCacheAdvisor', defined in class path resource [org/springframework/cache/annotation/ProxyCachingConfiguration.class], could not be registered. A bean with that name has already been defined and overriding is disabled. Action: Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true
and it also ask me to "setting spring.main.allow-bean-definition-overriding=true" .
So set a break point at the line of map.get() code, then I paste the bean name in breakpoint condition:
beanName.equals("org.springframework.cache.config.internalCacheAdvisor")
if you don't know how to use debug condition, you can checkout this :
How to use conditions in breakpoints in idea?
then finally I found out this breakpoint will trigger twice, as the second time when it triggered, it will throw the BeanDefinitionOverrideException.
as the bean with the same name has generate the second time.
In my case, what I found out the root cause is the bean announced in both xml and again in spring default Configuration Code.
But your case may not the same. So you need to use this debug tech to found the root cause!!
Hope this will help you, and as I know, don't open the override=true setting. it will get you more trouble than you thought!
@Configuration
and one config extends another. So all beans in parent class will be created twice. Remove@Configuration
from parent class and try. Also Its not a good practice to use inheritance in config classes. – NeedlefulExtendedESConfig
class then, you can use excludeFilter on @ComponentScan annotation to excludeESConfig
class – Needleful@Service
annotation. This effectively made it a@Bean
as well which clashed with the@Bean
definition in the@Configuration
class. Removing@Service
fixed the problem for me in Spring 2.6.3. – Hibbard