This is the fourth part of Spring Best Practices series as per Best practices introduction post. This forth part is related with the best practices when using Spring’s XML configurations. You can refer the other four posts through this links… Part 1, Part 2, Part 3 and Part 5. I am expecting the corrections (if any)as well as the new best ways from my readers.
- Avoid using spring’s ‘autowiring’
Spring can autowire dependencies through introspection of the bean classes so that you do not have to explicitly specify the bean properties or constructor arguments. Bean properties can be autowired either by property names or matching types. Constructor arguments can be autowired by matching types. You can even specify the autodetect autowiring mode, which lets Spring choose an appropriate mechanism. As an example, consider the following
The property names of the OrderService class are used to match a bean instance in the container. Autowiring can potentially save some typing and reduce clutter. However, you should not use it in real-world projects because it sacrifices the explicitness and maintainability of the configurations. Many tutorials and presentations tout autowiring as a cool feature in Spring without mentioning this implication. In my opinion, like object-pooling in Spring, it is more a marketing feature. It seems like a good idea to make the XML configuration file smaller, but this will actually increase the complexity down the road, especially when you are working on a large project where many beans are defined. Spring allows you mix autowiring and explicit wiring, but the inconsistency will make the XML configurations even more confusing.
- Use naming conventions
This is the same philosophy as for Java code. Using clear, descriptive, and consistent name conventions across the project is very helpful for developers to understand the XML configurations. For bean ID, for example, you can follow the Java class field name convention. The bean ID for an instance of OrderServiceDAO would be orderServiceDAO.For large projects; you can add the package name as the prefix of the bean ID.
- Use shortcut forms
The shortcut form is less verbose, since it moves property values and references from child elements into attributes. For example, the following
Can be rewritten in the shortcut form as:
The shortcut form has been available since version 1.2. Note that there is no shortcut form for <ref local=”…”>.The shortcut form not only saves you some typing, but also makes the XML configuration files less cluttered. It can noticeably improve readability when many beans are defined in a configuration file.
- Prefer type over index for constructor argument matching
Spring allows you to use a zero-based index to solve the ambiguity problem when a constructor has more than one arguments of the same type, or value tags are used. For example, instead of:
It is better to use the type attribute like this
Using index is somewhat less verbose, but it is more error-prone and hard to read compared to using the type attribute. You should only use index when there is an ambiguity problem in the constructor arguments.
- Reuse bean definitions, if possible
Spring offers an inheritance-like mechanism to reduce the duplication of configuration information and make the XML configuration simpler. A child bean definition can inherit configuration information from its parent bean, which essentially serves as a template for the child beans. This is a must-use feature for large projects. All you need to do is to specify abstract=true for the parent bean, and the parent reference in the child bean. For example
The shippingService bean inherits the value valuemometum for the companyName property from the abstractService bean. Note that if you do not specify a class or factory method for a bean definition, the bean is implicitly abstract.
- Prefer assembling bean definitions through ApplicationContext over imports
Like imports in Ant scripts, Spring import elements are useful for assembling modularized bean definitions. For example
However, instead of pre-assembling them in the XML configurations using imports, it is more flexible to configure them through the ApplicationContext. Using ApplicationContext also makes the XML configurations easy to manage. You can pass an array of bean definitions to the ApplicationContext constructor as follows: