I’m in the midst of a little refactor of groovyblogs to move to a message based architecture. Should make things a lot more reliable. Along the way I’m coming across a few common things that need to be written down. One of the first to sort out is the “circular dependencies” issue.

Here’s the classic scenario. I have a feed service that needs to talk to the queue service to make requests. And when new items come into from the queue service, I need to call the feed service and let it know. So you end up with something like:

class FeedService {

    QueueService queueService

    ...
}

class QueueService {

    FeedService feedService

    ...
}

Which looks all good to you and me. But if you tried to run this app you’d be greeted with:

 Error creating bean with name '(inner bean)': Initialization of bean failed;
nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException:
Error creating bean with name 'queueService':
org.springframework.beans.factory.FactoryBeanNotInitializedException:
FactoryBean is not fully initialized yet
        at java.security.AccessController.doPrivileged(Native Method)
        at RunApp_groovy$_run_closure2_closure7.doCall(RunApp_groovy:69)

or something like that. The problem? Spring can’t initialise either bean since they reference each other - and each relies on the other already existing. Hmm.. Chicken and egg scenario…

So how to work around it? The easiest way is to initialise one of the references lazily, rather than letting Spring do the work for you. But to do the “lazy” deal, you’ll need a handle to the Spring “ApplicationContext” which holds all the bean definitions. This turns out to be pretty trivial. Here’s a refactored queueService…

import org.springframework.context.*

class QueueService implements ApplicationContextAware {

    ApplicationContext applicationContext

    def feedServiceBean  // note the change of name to stop injection

    def slurpOffQueue() {

        feedServiceBean = applicationContext.getBean("feedService")
        feedServiceBean.doStuff()
    }
}

Not you’ll need a few things:

Anyway, thought I’d document a few of these things as I go. Actually, I”ve been meaning to write up some of these JMS experiences too. I really need to get back on the blog horse (have been twittering a bit lately, but it’s just not the same… I’m so GenX…)