Spring Config File Best Practices
Spring based projects revolve around Spring configuration XMLs. As project goes through development phase, with more and more code getting generated, it leads to frequent updating of Spring config XMLs, and it becomes nightmare to manage these files. Following guidelines or best practices would help to manage these files well and avoid merging issues, high maintenance cost etc.
- Location: Where do I keep Spring config files, under \WEB-INF folder directly (in web application context) or create a separate folder, and copy them to the root of classpath during build? Spring does not put any restriction other than accessibility to such files in classpath. But keeping everything under \WEB-INF folder or at the root of classpath before compilation, is not a best way of managing such supporting resources. Instead, create a separate folder called as say ‘beanfactory’ and keep config files in it. During build (using Maven/Ant or any other build tool) move these files to the desired location.
- Test and Main Config: Main files are the one which directly contribute towards application (business) function, while test files can be the code written to unit test e.g. JUnit test files. It may be the case that one is using Spring’s contextual test framework to build application unit tests. This means there are test config files as well. Separate location (‘/beanfactory’) for main and test config files is also recommended here. This means there should be separate config files for these purposes. E.g. for main \src\main\resources\beanfactory would be the location of main Spring config files while \src\test\resources\beanfactory can be location of test config files.
- Modularization: As the number of dependency configurations increase, the file size also grows considerably. If everything is in a single file, there would be frequent changes to it. Merger of different versions of this file through source control becomes difficult at times, as the editors used by source control software to merge XML files are not intelligent enough to understand structure of a XML. These editors perform dumb character comparison and merger leading to broken config files. Hence it is better to create separate files with a config grouping theme. A theme can be: a file per module, a file per layer, or something that suits packaging philosophy to be used to deploy application. It is also important to consider scope of \resources\beanfactory folder in above point while defining contents of a config.
- Separation of Properties: One can use placeholder in config files and extract properties (hardcoded values other than dependency injection configuration) out to a property file(s). It is to separate Spring configuration from data/values.
- Linked Files: It is possible to reference config file(s) in another config file using import shown below. Different files can be linked together to arrive at configuration needed for certain packaging requirement. This can also be used to create hierarchy of configuration. <import resource=”classpath:beanfactory/abc-web-appContext.xml”/>
- Correct Spring XSD Reference: As Spring continues to enhance the framework through continuous releases, there are some modifications to the XSD bundled with each version. There may be slight or no change, but it is better to use latest version of required XSDs.
- Environment Specific Config: Few Spring configurations (e.g. connection pool configuration) tend to change as code moves from one environment to other, e.g. development environment to, system test, user acceptance test, and production environments. It is better to keep such configuration in a separate configuration file, and reference it wherever required.
- Configuration in a Jar: If a module is to be bundled into a jar file, then there should be single config access file that links all other config files in the jar. This file can be imported into the application configurations that use this archive. Also, avoid keeping any environment specific configurations in this archive. Leave it to the user of this jar to provide/override.