Rick has posted 25 posts at DZone. You can read more from them at their website. View Full User Profile

Escape from XML Hell Redux: Spring 2.5 Annotation Driven DI

03.07.2008
| 14021 views |
  • submit to reddit

This post is an escape from XML redux. As stated in the last post, there are some who do not like to configure dependency injection (DI) in XML. They call it "XML Hell"!

In the last post we showed how using JSF to manage beans and perform some basic DI was very verbose. Then the post showed how simple DI with XML could be with Spring. Then we used Spring Java Spring Config to get rid of the XML configuration altogether.

This post uses Spring 2.5 annotation driven DI and scope management.

The example had a controller called ContactController. The ContactController had three dependencies that were injected named ContactRepository, GroupRepository and TagRepository.


In this weeks installment demonstrates how to use Spring 2.5 style annotation injections. Spring 2.5 annotation injection is a bit different than Spring Java Config as you annotate the classes directly that Spring manages.

To identify a bean as one that Spring is managing you need to annotated it with @Repository, @Service, @Component, @Controller, etc., or define your own custom annotations to denote that Spring is managing your bean.

Let's explore the example, the ContactController which is annotated with @Controller. This identifies the ContactController to Spring to be manage. Notice that the ContractController is put into Session scope, i.e., here is the modified controllers as follows:


package com.arcmind.contact.controller;
...
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;


@Controller
@Scope("session")
public class ContactController extends AbstractCrudController{

If you don't specify a qualifier, the name of the bean by default is "contactController".

The ContactRepository which is annotated with @Repositoryr. This identifies the ContactRepository to Spring to be managed. Notice that the ContractRepository is put into the default scope of SINGLETON which is similar to the Servlet APIs application scope.

package com.arcmind.contact.model;
...
import org.springframework.stereotype.Repository;

@Repository
public class ContactRepository {

 

The other repos are setup the same way.

In a similar way we manage the group repository and the tag repository. Once all of the repositories are managed, we can use them from the ContactController using the @Autowired as follows:

public class ContactController extends AbstractCrudController{
/** Contact Controller collaborates with contactRepository. */
@Autowired(required=true) @Qualifier("contactRepository")
private ContactRepository contactRepository;

@Autowired(required=true) @Qualifier("groupRepository")
private GroupRepository groupRepository;

@Autowired(required=true) @Qualifier("tagRepository")
private TagRepository tagRepository;

 

Spring provides many ways to inject dependencies with annotations: method arguments, JavaBean properties and constructor arguments. My favorite approach is the above which is to inject directly into the field, thus not polluting my class with JavaBean properties, etc.

Spring can scan package names to find beans to manage as follows:

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">

<context:component-scan base-package="com.arcmind.contact"/>


</beans>

 

The above is a one time setup.

One thing that I don't like about the above is that your classes import Spring specific classes which pollutes your beans with another API just to get DI. However, Spring provides the ability to define your own annotations that are not tied to Spring and yet can still identify your classes for Spring's scope management and DI.

(You can find the above example using Spring's 2.5 annotation DI at Architecture Proofs of Concept: contacts 6 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 examples in this Spring/JSF series will extend the examples in this JSF 1.2 tutorial series.

What do you think of Spring 2.5 annotated DI and scope management?



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

Published at DZone with permission of its author, Rick Hightower.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Peter Veentjer replied on Fri, 2008/03/07 - 9:43am

The problem with annotation driven DI is that is isn't DI but just  a Service Locator (imho). And this makes components less reusable (not always an issue btw).

Another big advantage of a bunch of files containing the structure of your application, is that it much easier to figure out how a system works. Although the XML nature of the current Spring application context suck, I think a better solution to the problem would be to replace it by something more powerful like a ruby/groovy based DSL. Introducing an internal DSL also reduces the need to fiddle around with all kinds of clumsy FactoryBeans (a symptom of external dsl's).

Guillaume Bilodeau replied on Mon, 2008/03/10 - 11:39am

The good points about Spring annotation DI are that it allows me to register components and wire them quickly, keep scope configuration close to the code, and remove loads of XML config.

However I do agree with alarmnummer that in the end you get less flexibility. You can't easily proxy your components, configuration is scattered and injecting constants isn't as elegant.

Once again, it's a matter of weighing the pros and cons. For standard webapps, you don't need much proxying so annotation DI is enough. As soon as you need more flexibility though, switch back to XML.

Carla Brian replied on Sat, 2012/04/28 - 5:59am

I think this is really effective. I am new to this one. Thanks for sharing. - DR Marketing Group

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.