Spring: Many applicationContext.xml > One applicationContext.xml
This is a short introduction to splitting up your bean definitions from one single Spring application context, to many application contexts. That is, from one XML file to many XML files.
The general idea is to have one single primary application context, usually titled
applicationContext.xml, and then many other application contexts with are named what they contain.
Example
- applicationContext.xml
- applicationContext-dao.xml
- applicationContext-dao-datasource.xml
- applicationContext-ldap.xml
- applicationContext-aspects.xml
- applicationContext-web.xml
Breakdown
In this example, your DAO definitions, transaction managers, and DAO or integration interceptors are defined in applicationContext-dao.xml. We have further broken the DAO application context to a dao-datasource which contains our data sources. LDAP configuration, beans, and DAOs are in their own applicationContext-ldap.xml.
Benefits
Why so many? There have been a few benefits so far.
- Clearly, working with a smaller XML file is easier than working with one enormous file. It is easier to maintain and easier to read.
- Testing. When I wrote my tests for LDAP, I had my LDAP configuration in applicationContext.xml, but then every time I ran an LDAP test, I would get the WebApplicationContext, which would import applicationContext-hibernate, which would connect to the database, tests took forever, needless resources used… Anyway, now I just get applicationContext-ldap.xml which only contains LDAP configurations, so no needless resources are loaded.
- Including. Finally, its really easy to comment out a line like
<import resource="applicationContext-aspects.xml"/>
and quickly have all my aspects, which for me only write logs, disabled.
Does anyone else use multiple application context files? See any other benefits? Or problems?
Jamo Smith 5:52 pm on May 24, 2008 Permalink
I’ve used a folder called springbeans to hold all my context files. They are module or entity centric:
- user.xml
- project.xml
- hibernate.xml
- security.xml
Tests are able to isolate only 1 or 2 contexts that are required to do the given test.
cherouvim 5:53 pm on May 24, 2008 Permalink
Yep. Many files and imports is how I prefer it as well. Especially those which are deployment related (datasource, mail session details etc).
And I see no problems with that.
Ashkan 5:53 pm on May 24, 2008 Permalink
…
Clearly, working with a smaller xml file is easier than working with one enormous file.
…
And working with as little as possible XML stuff is the utopia so take a look at Guice Mike.
Peter Warhol 2:23 pm on May 25, 2008 Permalink
I think that was covered recently in the 90th percentile:
http://icoloma.blogspot.com/2008/01/mock-your-spring-config-for-fun-and.html
Mike 9:19 am on May 26, 2008 Permalink
Thank you Peter. the 90th percentile states
and follows up that with an example of how to import many application contexts into a main one.
Matt 9:55 am on May 27, 2008 Permalink
Another issue we ran into is having several applicationContext.xml on the classpath leads to some very hard to track errors. By giving the file a unique name, you can help avoid these conflicts.
Adrian Neagomir 10:14 am on May 27, 2008 Permalink
I use two definition files when doing web applications with Spring: one containing the database access and the service layer while the web related stuff in the configuration file that’s used to configure the DispatcherServlet.
The advantage of having this setup is that I can instantiate a console application that has access to the entire service layer for batch jobs, tests etc. using only the first file without having any dependency to a servlet container.
Using more files one can assemble different application using the same codebase.
Max Power 6:15 pm on May 28, 2008 Permalink
Splitting your bean definitions into multiple files is definitely a good practice. However, regarding how your old way of not splitting it up caused the app context to connect to the database reminds me of something I read where I believe the preferred way of coding unit tests is to create the beans programmaticly in the setup methods. This way the tests aren’t tied to configuration files that may be changed, causing the tests to become invalid since they aren’t being run in the same configuration against which they were coded.
Mike 7:45 am on May 29, 2008 Permalink
Max, good points on test datasouces. With a Spring context, you could create a datasource bean with the same name, and then load that test context AFTER the production context, the test context would be used. That way you can keep all the configuration in the application contexts and have them injected.
Andrew Sazonov 1:44 am on June 7, 2008 Permalink
Just my 2 cents – suggestion from Mike regarding testing via bean overriding (i.e registering bean in text context using the same name as one in production) will work, but only if context is configured to allows bean definition overriding (there is appropriate setting for that)