Learnitweb

Loading bean definitions from multiple XML files in Spring

We can use XML, annotations and Java code to configure the spring beans. We can mix these ways of configurations as well. However, the annotations are more popular now a days but XML is also a good way of defining beans at one place. XML was the popular way of configuration before annotations.

Need to keep bean definitions in multiple files

While developing an enterprise application which involves hundreds of classes, if we keep all classes’ information in a single XML file, the file will be huge. We usually make modules in an application to logically arrange classes or code in our application. So it is better to keep configuration information of a particular module in it’s separate XML configuration file. This way of organizing configuration information is more readable and manageable. Each XML represents a logical layer of module of the application.

We can load bean definitions from multiple files using the <import /> element like the following:

<beans>
    <import resource="bean-file1.xml"/>
    <import resource="resources/bean-file2.xml"/>
    <import resource="/resources/bean-file3.xml"/>

    <bean id="bean1" class="..."/>
    <bean id="bean2" class="..."/>
</beans>

Let us see this with an example. Suppose Car and Engine are two beans and Car needs an Engine. So we can say that Car references Engine or Car has a dependency on Engine. We can keep these two bean definitions in two different files. This is just for demonstration purpose and in actual project an XML can have hundreds of beans.

We can import bean-file.xml in app-context.xml using <import /> element.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">

	<import resource="bean-file.xml" />

	<bean id="engine" class="com.learnitweb.dependency.Engine">
		<constructor-arg name="manufacturer" value="audi" />
		<constructor-arg name="type" value="automatic" />
		<constructor-arg name="cylinders" value="4" />
	</bean>
	
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">

	<bean id="audi" class="com.learnitweb.components.Car">
		<property name="engine" ref="engine"></property>
	</bean>
</beans>

Now we can load a xml file like this :

ApplicationContext ctx = new ClassPathXmlApplicationContext("app-context.xml");

Important points

  • All XML files must be valid XML bean definitions, according to the Spring Schema.
  • All location paths are relative to the definition file which imports the other files.
  • A leading slash is ignored. It is recommended to not use slash(/) at all.
  • We can reference to parent directories using a relative “../” path. But this is not recommended. This creates a dependency on a file which is outside the current application.
  • We can use fully qualified resource locations like “c:/config/bean-file.xml” or “classpath:/config/bean-file.xml”. But this ties your application to absolute locations. So it is better to avoid placement of configuration files at absolute locations.