July 14, 2005
Spring: Bold as Love

I am having trouble getting Spring and Axis to play nicely together.

I've been getting along famously with Spring. We are using Spring's MVC framework, and everything was fitting together as smooth as silk. Our DAO's are coded using HibernateDaoSupport, instantiated as beans wrapped in HibernateTransactionManagers, and injected into our actions and controllers. With this lot set up, Spring and Hibernate between them do all the heavy lifting in terms of database work, and our code needs to know almost nothing about it. And using jMock in our unit tests to mock the DAO, we had close to 100% coverage.

Then I was asked to introduce web services. Axis looked to me to be the de-facto standard, so that was what I've been using so far. In most ways, it's a thing of beauty - I particularly like happyaxis.jsp - but I can't work out how to get it to play happily with Spring. Spring isn't instantiating the service objects, so it doesn't get an opportunity to inject the DAOs.

In order to unit test at all, I've created given the service objects setters and getters for the DAOs they need. The getters lazily initialize the DAOs from Spring in required. In our unit tests, we just call the setter with a mock object, so the lazy initialization never gets used.

public CurrencyDAO getCurrencyDAO() {
 
    // Lazy initialisation. If the DAO hasn't yet been set, we'll get it
    // from Spring. I doubt we'll be able to cover this in testing.
    if (this.currencyDAO == null) {
        this.logger.debug("Lazy initialisation of currencyDAO");
        final ApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext());
        setCurrencyDAO((CurrencyDAO) applicationContext.getBean("currencyDAO"));
    }
    return this.currencyDAO;
}
 
public void setCurrencyDAO(final CurrencyDAO currencyDAO) {
    // This will probably ony be needed for test purposes.
    this.currencyDAO = currencyDAO;
    this.logger.debug("currencyDAO set to " + String.valueOf(currencyDAO));
}

(How do I get the servletContext? In the real code, I grab hold of it with a ServletContextListener, and keep it in a Borg.)

This works, but it feels inelegant. Worse, much of the getter is impossible to unit test. Is there a way to get Spring to instantiate my Axis service objects? Is there a cleaner way of getting beans from Spring? Is there another web service framework that plays nicer with Spring?

Posted to Java by Simon Brunning at July 14, 2005 04:52 PM
Comments
Post a comment
Name:


Email Address:


URL:



Comments:


Remember info?