Archive

Posts Tagged ‘spring’

Overriding Spring Beans

May 8, 2011 7 comments

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.

Advertisements
Categories: Software Tags: