Can we have duplicate names for the same bean id that is mentioned in the XML? If not, then how do we override the bean in Spring?
-
Can you post some example xml to show exactly what you mean – Mark Pope May 01 '11 at 15:20
8 Answers
Any given Spring context can only have one bean for any given id or name. In the case of the XML id
attribute, this is enforced by the schema validation. In the case of the name
attribute, this is enforced by Spring's logic.
However, if a context is constructed from two different XML descriptor files, and an id
is used by both files, then one will "override" the other. The exact behaviour depends on the ordering of the files when they get loaded by the context.
So while it's possible, it's not recommended. It's error-prone and fragile, and you'll get no help from Spring if you change the ID of one but not the other.

- 398,947
- 96
- 818
- 769
-
2If they are in the same hierarchy level it is risky, but one can use `profiles` (see my answer) to get a better control over it. – Roee Gavirel May 07 '15 at 11:42
-
2Is there a way to instruct Spring to throw an error if it encounters any beans that have the same id (i.e. emphatically do not allow overriding)? This is for the `contextConfigLocation` property of `ServletContextHandler` . – Jeff Evans Aug 28 '15 at 20:22
-
For those who use Java Config, the [annotation `@Primary`](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/Primary.html) indicates that a bean should be given preference when multiple candidates are qualified to autowire a single-valued dependency. – elirandav Aug 21 '18 at 10:58
-
so what is the expected order when using `
` ? does the last one win ? – Donatello Feb 07 '20 at 11:05
I will add that if your need is just to override a property used by your bean, the id approach works too like skaffman explained :
In your first called XML configuration file :
<bean id="myBeanId" class="com.blabla">
<property name="myList" ref="myList"/>
</bean>
<util:list id="myList">
<value>3</value>
<value>4</value>
</util:list>
In your second called XML configuration file :
<util:list id="myList">
<value>6</value>
</util:list>
Then your bean "myBeanId" will be instantiated with a "myList" property of one element which is 6.

- 969
- 12
- 14
Not sure if that's exactly what you need, but we are using profiles to define the environment we are running at and specific bean for each environment, so it's something like that:
<bean name="myBean" class="myClass">
<constructor-arg name="name" value="originalValue" />
</bean>
<beans profile="DEV, default">
<!-- Specific DEV configurations, also default if no profile defined -->
<bean name="myBean" class="myClass">
<constructor-arg name="name" value="overrideValue" />
</bean>
</beans>
<beans profile="CI, UAT">
<!-- Specific CI / UAT configurations -->
</beans>
<beans profile="PROD">
<!-- Specific PROD configurations -->
</beans>
So in this case, if I don't define a profile or if I define it as "DEV" myBean will get "overrideValue" for it's name argument. But if I set the profile to "CI", "UAT" or "PROD" it will get "originalValue" as the value.

- 18,955
- 12
- 67
- 94
-
Is "default" a special automagically enabled profile in Spring or do you have to enable it explicitly? – usr-local-ΕΨΗΕΛΩΝ Aug 28 '19 at 10:38
-
It is, as its name suggests, the 'default' profile. The one you get automatically if you don't change it manually. – Roee Gavirel Aug 28 '19 at 11:39
-
What if you enable other profiles that are not related the SIT/UAT env? For example, our application has profiles for database connection (JDBC; JNDI), clustering (SINGLENODE; CLUSTER), authentication (DB; AD; SSO). I suppose that if I enable an authentication profile I can't use a "default" profile for the database service. But thanks for the answer because I am going to investigate further anyway – usr-local-ΕΨΗΕΛΩΝ Aug 28 '19 at 11:41
-
@RoeeGavirel - is it guaranteed that the bean defined inside profile will always override the other one. In my case, i have another xml bean definition file that i'm loading based on selected profile, and want to make sure spring **always** picks up the overridden bean if profile is active. Can you please provide a link if possible if spring claims the order of overriding bean definitions. Thanks for your help – Neeraj B. Mar 25 '20 at 06:23
An example from official spring manual:
<bean id="inheritedTestBean" abstract="true"
class="org.springframework.beans.TestBean">
<property name="name" value="parent"/>
<property name="age" value="1"/>
</bean>
<bean id="inheritsWithDifferentClass"
class="org.springframework.beans.DerivedTestBean"
parent="inheritedTestBean" init-method="initialize">
<property name="name" value="override"/>
<!-- the age property value of 1 will be inherited from parent -->
</bean>
Is that what you was looking for? Updated link

- 24,551
- 7
- 52
- 62

- 8,862
- 7
- 47
- 63
Since Spring 3.0 you can use @Primary
annotation. As per documentation:
Indicates that a bean should be given preference when multiple candidates are qualified to autowire a single-valued dependency. If exactly one 'primary' bean exists among the candidates, it will be the autowired value. This annotation is semantically equivalent to the element's primary attribute in Spring XML.
You should use it on Bean definition like this:
@Bean
@Primary
public ExampleBean exampleBean(@Autowired EntityManager em) {
return new ExampleBeanImpl(em);
}
or like this:
@Primary
@Service
public class ExampleService implements BaseServive {
}

- 812
- 8
- 13
Another good approach not mentioned in other posts is to use PropertyOverrideConfigurer in case you just want to override properties of some beans.
For example if you want to override the datasource for testing (i.e. use an in-memory database) in another xml config, you just need to use <context:property-override ..."/>
in new config and a .properties
file containing key-values taking the format beanName.property=newvalue
overriding the main props.
application-mainConfig.xml:
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource"
p:driverClassName="org.postgresql.Driver"
p:url="jdbc:postgresql://localhost:5432/MyAppDB"
p:username="myusername"
p:password="mypassword"
destroy-method="close" />
application-testConfig.xml:
<import resource="classpath:path/to/file/application-mainConfig.xml"/>
<!-- override bean props -->
<context:property-override location="classpath:path/to/file/beanOverride.properties"/>
beanOverride.properties:
dataSource.driverClassName=org.h2.Driver
dataSource.url=jdbc:h2:mem:MyTestDB

- 5,823
- 4
- 41
- 50
Whether can we declare the same bean id in other xml for other reference e.x.
Servlet-Initialize.xml
<bean id="inheritedTestBean" class="org.springframework.beans.TestBean">
<property name="name" value="parent"/>
<property name="age" value="1"/>
</bean>
Other xml (Document.xml)
<bean id="inheritedTestBean" class="org.springframework.beans.Document">
<property name="name" value="document"/>
<property name="age" value="1"/>
</bean>
-
-
7@Buchi Yes, it is allowed. Bean from the file read later in sequence will override entirely previous definition which won't be instantiated at all. – mrembisz Feb 21 '12 at 14:14
-
Are you sure about that? Are you sure that spring initialize/run constructor of bean at the end of scanning? So when we inject `inheritedtTestBean` into another bean whitch implementation will be injected? first or second? – RMachnik Jul 24 '14 at 21:32
Question was more about XML but as annotation are more popular nowadays and it works similarly I'll show by example.
Let's create class Foo
:
public class Foo {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
and two Configuration files (you can't create one):
@Configuration
public class Configuration1 {
@Bean
public Foo foo() {
Foo foo = new Foo();
foo.setName("configuration1");
return foo;
}
}
and
@Configuration
public class Configuration2 {
@Bean
public Foo foo() {
Foo foo = new Foo();
foo.setName("configuration2");
return foo;
}
}
and let's see what happens when calling foo.getName()
:
@SpringBootApplication
public class OverridingBeanDefinitionsApplication {
public static void main(String[] args) {
SpringApplication.run(OverridingBeanDefinitionsApplication.class, args);
AnnotationConfigApplicationContext applicationContext =
new AnnotationConfigApplicationContext(
Configuration1.class, Configuration2.class);
Foo foo = applicationContext.getBean(Foo.class);
System.out.println(foo.getName());
}
}
in this example result is: configuration2
.
The Spring Container gets all configuration metadata sources and merges bean definitions in those sources. In this example there are two @Bean
s. Order in which they are fed into ApplicationContext
decide. You can flip new AnnotationConfigApplicationContext(Configuration2.class, Configuration1.class);
and result will be configuration1
.

- 5,058
- 7
- 47
- 80