Home > Software > Overriding Spring Beans

Overriding Spring Beans


Spring IoC container is a very powerful configuration tool. So powerful that became a de-facto industry standard. I would choose it without second doubts in almost any project, especially bigger ones.
Still there is a feature in Spring that I would consider it confusing. With Spring IoC Container you can override beans. Very simple actually. Just define another bean with the same id. Spring will consider the last definition and ignore all the others before. You can have the following scenarios

a.xml
		<beans>
			<bean class="java.lang.String" id="x">
				<constructor-arg>Bean from A</constructor-arg>
			</bean>
		</beans>
b.xml
		<beans>
			<import resource="a.xml"/>
			<bean class="java.lang.String" id="x">
				<constructor-arg>Bean from B</constructor-arg>
			</bean>
		</beans>
web.xml
		<context-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:b.xml</param-value>
		</context-param>
a.xml
		<beans>
			<bean class="java.lang.String" id="x">
				<constructor-arg>Bean from A</constructor-arg>
			</bean>
		</beans>
b.xml
		<beans>
			<bean class="java.lang.String" id="x">
				<constructor-arg>Bean from B</constructor-arg>
			</bean>
		</beans>
web.xml
		<context-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:a.xml,classpath:b.xml</param-value>
		</context-param>

In both cases the Bean from A is overridden by the Bean from B. In the first case a.xml is imported in b.xml and only a.xml is referenced from web.xml and in the second case both a.xml and b.xml are referenced from web.xml, but b.xml is the last one.

If you have many configuration files and many modules this can be somewhat confusing. Personally I would add an attribute named, let’s say, override, that must be set to true if you want that the current bean override another bean definition. If not, then an exception will be thrown during configuration load. (default value will be false).
I also encountered another issue with Spring configuration: having the same configuration file name in different classpath locations (aka jars). This lead to undeterministic behavior (unlike the first case) resulting in loading one of the two files. But this one is clearly bad practice from the programmer side. I usually keep my Spring configuration files along with the sources. So in the package com.my.package I have a file package-ctx.xml. This can be referenced in Spring as classpath:/com/my/package/package-ctx.xml. I would not recommend names like spring-ctx.xml or general.xml. They are too general and counterintuitive.

Categories: Software Tags:
  1. February 7, 2014 at 2:48 am

    Thanks Adrian, a succinct and useful explanation of how to override beans.

    Shaun

  2. Anonymous
    November 10, 2014 at 10:21 pm

    Can you elaborate on how you can force uniqueness on duplicate bean id’s from multiple bean imports?
    “Personally I would add an attribute named, let’s say, override, that must be set to true if you want that the current bean override another bean definition. If not, then an exception will be thrown during configuration load. (default value will be false).”

  1. June 15, 2011 at 6:49 pm
  2. June 15, 2011 at 6:50 pm
  3. June 26, 2011 at 9:46 pm
  4. June 26, 2011 at 9:47 pm
  5. May 29, 2012 at 1:44 am

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: