Spring XML Hell? Escape XML Hell
Join the DZone community and get the full member experience.
Join For FreeThere are some who do not like to configure dependency injection (DI) in XML. They call it "XML Hell"! There are some who even complain about Spring's DI XML configuration with its lack of type safety.
However compared to J2EE XML configuration (and many other frameworks), Spring XML configuration is a breeze and quite powerful. In addition with Spring 2.5 annotations and the Spring Java Config module, you don't have to use XML to do DI.
For example, JSF provides XML DI support. However, JSF configuration in its current version can be very verbose. Spring can simplify doing DI with JSF quite a bit. Let's explore this as an JSF example, then show how to escape "XML Hell" using Spring XML and later the Spring Java Config module.
Let's say in JSF that I have a managed bean that is acting as a controller called ContactController, and it has three dependencies that you need to inject called ContactRepository, GroupRepository and TagRepository. In addition the ContactValidators is a utility class that we use for validation. To configure all of these in standard JSF XML we would do these verbose entries:
<managed-bean>
<managed-bean-name>contactValidators</managed-bean-name>
<managed-bean-class>com.arcmind.contact.validators.ContactValidators</managed-bean-class>
<managed-bean-scope>application</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>contactController</managed-bean-name>
<managed-bean-class>
com.arcmind.contact.controller.ContactController
</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>contactRepository</property-name>
<property-class>
com.arcmind.contact.model.ContactRepository
</property-class>
<value>#{contactRepository}</value>
</managed-property>
<managed-property>
<property-name>groupRepository</property-name>
<property-class>
com.arcmind.contact.model.GroupRepository
</property-class>
<value>#{groupRepository}</value>
</managed-property>
<managed-property>
<property-name>tagRepository</property-name>
<property-class>
com.arcmind.contact.model.TagRepository</property-class>
<value>#{tagRepository}</value>
</managed-property>
</managed-bean>
<managed-bean>
<managed-bean-name>contactRepository</managed-bean-name>
<managed-bean-class>
com.arcmind.contact.model.ContactRepository
</managed-bean-class>
<managed-bean-scope>application</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>groupRepository</managed-bean-name>
<managed-bean-class>
com.arcmind.contact.model.GroupRepository
</managed-bean-class>
<managed-bean-scope>application</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>tagRepository</managed-bean-name>
<managed-bean-class>
com.arcmind.contact.model.TagRepository
</managed-bean-class>
<managed-bean-scope>application</managed-bean-scope>
</managed-bean>
GAK! The JSF version of the configuration takes close to 60 lines. Granted there are many who only configure JSF through IDE tools so they might not care how long it is. However, if you prefer editing files to filling out IDE dialog boxes like me, then Spring can simplify the XML DI configuration a lot. Spring XML is much more developer friendly. This alone might make you interested in Spring if you are doing JSFdevelopment.
(You can download the complete example from this JSF tutorial at IBM developerWorks.)
Let's look at the terse Spring XML configuration version of the above.
<bean id="contactValidators" class="com.arcmind.contact.validators.ContactValidators"/>
<bean id="contactController" class="com.arcmind.contact.controller.ContactController" scope="session">
<property name="tagRepository" ref="tagRepository"/>
<property name="groupRepository" ref="groupRepository"/>
<property name="contactRepository" ref="contactRepository"/>
</bean>
<bean id="contactRepository" class="com.arcmind.contact.model.ContactRepository"/>
<bean id="groupRepository" class="com.arcmind.contact.model.GroupRepository"/>
<bean id="tagRepository" class="com.arcmind.contact.model.TagRepository"/>
Now the XML configuration is only 11 lines long instead of near 60. This is a nice improvement, but still there are some who do not like working with XML even if it is only 1/6th the size of the JSF XML version. (Note you can make the Spring XML DI configuration more terse by using auto-wiring and other techniques, however, the above is a good trade-off for readability.)
(You can find the above example at Architecture Proofs of Concept: contacts 4 example.)
Spring 2.5 provides many options for configuring DI without using much XML. Spring 2.5 provides annotation support that is similar to the support that Seam and Guice provide so that you can do the DI without writing a lot of XML. A less touted project from the Spring portfolios of projects is the Spring Java Configuration project. Here is an example of Spring Java Config as follows:
@Bean
public ContactValidators contactValidators() {
return new ContactValidators();
}
@Bean(scope=DefaultScopes.SESSION)
public ContactController contactController() {
ContactController contactController = new ContactController();
contactController.setContactRepository(contactRepository());
contactController.setTagRepository(tagRepository());
contactController.setGroupRepository(groupRepository());
return contactController;
}
@Bean
public ContactRepository contactRepository() {
return new ContactRepository();
}
@Bean
public GroupRepository groupRepository() {
return new GroupRepository();
}
@Bean
public TagRepository tagRepository() {
return new TagRepository();
}
The above is functionally equivalent to the last two XML versions of the configuration. Notice that the contactController is mapped into SESSION scope.
The nice thing about this configuration is that you can do whatever you want in Java to construct the object as the methods are like factory methods. Also since it is Java, you can subclass the configuration if you have common configuration. Thus if you have a class of application like say a CRUD web application then you can create a common base configuration and then subclass it per application. (Note again you could make the above more terse by using auto-wiring and using constructors instead of setter methods, etc.).
(You can find the above example using Spring's Java Config module at Architecture Proofs of Concept: contacts 5 example.)
There are many advantages to using Spring with JSF so look forward to seeing more posts on this topic. This post merely scratches the surface of the power of Spring. In addition, Tom Cellucci, Paul Hixson and I are writing a series of articles for IBM developerWorks on combining JSF, JPA and Spring effectively. The first article is all on Spring DI and JSF and will have step by step instructions for combining Spring and JSF.
The JSF/Spring article series will include:
- Configuring Spring to work with JSF,
- DI for objects whose life-cycle is controlled by JSF (e.g., PhaseListeners, Converters, etc.),
- Solving common problems with JPA in a JSF web application,
- Using Spring scope proxies to easily write efficient yet coherent JSF managed beans,
- and more
The examples in this Spring/JSF series will extend the examples in this JSF 1.2 tutorial series.
What do you think of Spring Java Config?
What do you think of Spring's IoC support versus JSF's IoC support?
About the author
Rick Hightower is CTO of Mammatus and is an expert on Java and Cloud Computing. Rick is invovled in Java CDI advocacy and Java EE. CDI Implementations - Resin Candi - Seam Weld - Apache OpenWebBeans
Opinions expressed by DZone contributors are their own.
Trending
-
Leveraging FastAPI for Building Secure and High-Performance Banking APIs
-
What to Pay Attention to as Automation Upends the Developer Experience
-
Does the OCP Exam Still Make Sense?
-
How To Ensure Fast JOIN Queries for Self-Service Business Intelligence
Comments