Is having two definition for a bean (with same name and class) valid in Spring IOC ?
I am having two bean definition files included in web.xml. See the sample below.
This is valid and useful especially when you try to change the implementation of a third party bean (I mean, where you are not allowed to change the implementation of a bean) and Where you need to provide/configure some extra (merge) properties for the bean.
The overriding of the bean depends upon the order of the xmls you provide to build the ApplicationContext
through web.xml or stand-alone. The latest bean definition will win the game.
It's valid, but you'll find that one bean is overridden by the other. You'll see this in the logs as
Overriding bean definition for...
This behaviour allows you to override previously supplied bean definitions. It affects the static assembly of your app, and doesn't relate to threading/clustering as suggested in your question.
Note that the DefaultListableBeanFactory
allows you to configure this behaviour via setAllowBeanDefinitionOverriding()
From Spring Boot version 2.1 it is disabled by default. (link)
Bean Overriding: Bean overriding has been disabled by default to prevent a bean being accidentally overridden. If you are relying on overriding, you will need to set
spring.main.allow-bean-definition-overriding
totrue
.
I know it is very very late to reply, But sill want to add something...
It valid as long as you are defining two bean definitions with same id of same bean on two different spring configuration files. And you are importing one configuration file into another (kind of merging), does not matter how you importing (kind of merging). The later one or the last one bean definition will be override by the first one(s).
package com.demo.bean;
public class TestBean {
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
e.g # 1
spring-config1.xml
<bean id="testbean" class="com.demo.TestBean">
<property name="message" value="INSIDE_SPRING_CONFIG_1"></property>
</bean>
spring-config2.xml
<import resource="spring-config1.xml"/><
<bean id="testbean" class="com.demo.TestBean">
<property name="message" value="INSIDE_SPRING_CONFIG_1"></property>
</bean>
e.g # 2
spring-config1.xml
<bean id="testbean" class="com.demo.TestBean">
<property name="message" value="INSIDE_SPRING_CONFIG_1"></property>
</bean>
spring-config1.xml
<bean id="testbean" class="com.demo.TestBean">
<property name="message" value="INSIDE_SPRING_CONFIG_1"></property>
</bean>
web.xml
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring-config1.xml,
/WEB-INF/spring-config2.xml
</param-value>
</context-param>
But if you are defining the two bean definitions with same bean id of same bean in same file you will find spring application start up failed. Spring would not let you define multiple bean definitions of same bean with same name in the same spring configuration file.
e.g # 3 spring-config3.xml
<bean id="testbean" class="com.demo.TestBean">
<property name="message" value="CONFIG_VALUE_1"></property>
</bean>
<bean id="testbean" class="com.demo.TestBean">
<property name="message" value="CONFIG_VALUE_2"></property>
</bean>
Error :
ERROR ContextLoader:331 - Context initialization failed
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Bean name 'testbean' is already used in this <bean> element
Offending resource: resource [/spring-config3.xml]
at org.springframework.beans.factory.parsing.FailFastProblemReporter.error(FailFastProblemReporter.java:70)
at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:85)
at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:80)
at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.error(BeanDefinitionParserDelegate.java:316)
at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.checkNameUniqueness(BeanDefinitionParserDelegate.java:525)
at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseBeanDefinitionElement(BeanDefinitionParserDelegate.java:471)
at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseBeanDefinitionElement(BeanDefinitionParserDelegate.java:443)
at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.processBeanDefinition(DefaultBeanDefinitionDocumentReader.java:314)
at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseDefaultElement(DefaultBeanDefinitionDocumentReader.java:205)
at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:184)
at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.doRegisterBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:141)
at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.registerBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:110)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.registerBeanDefinitions(XmlBeanDefinitionReader.java:508)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:391)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:335)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:303)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:180)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:216)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:187)
at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:125)
at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:94)
at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:129)
at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:540)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:454)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4716)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5178)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:152)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1403)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1393)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)