Friday, February 16, 2007

Spring-Loaded Observer vs. TypeCollectorFactory

I've just re-read Scott Priolo's Spring-Loaded Observer Pattern on TSS. I had a similar desire to work with something like the observer pattern for an event model on a recent project. Scott's pattern works reasonably well, but you do end up having a fair amount of Spring XML for each listener you want to add. The MethodInvokingFactoryBean is a reasonable approach, but nine lines of Spring XML to inject a single observer can be a fair amount of Spring code, if you have a lot of listeners. (To be honest, I also hadn't thought about using it, but even seeing it, I prefer the pattern I've employed).

So where Scott's example does this:

<bean id="registerTownResident1"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject"><ref local="townCrier"/></property>
<property name="targetMethod">
<value>addListener</value>
</property>
<property name="arguments">
<list>
<ref bean="townResident1"/>
</list>
</property>
</bean>


I've done this:
<bean name="eventService" 
class="CoreEventService">
<parameter name="eventListeners">
<bean class="SpringTypeCollectorFactory">
<parameter name="typeToCollect"
value="EventListener" />
</bean>
</parameter>
</bean>


The SpringTypeCollectorFactory simply grabs all the items of a particular type from the context and collects them up in a list which it returns. This allows me to simply declare event listeners that match the EventListener interface and voila, they're injected into the event service.

More importantly, it means that client projects which consume our core spring configuration can simply add their own event listeners to their own Spring files and these two are picked up and added into the core event service.

Since this seems like something other people might be able to find good uses for, I'm sharing it, both here (this blog entry), and here.

3 comments:

Rick said...

Aye, I have done a similar thing on a number of projects. Like you say it is really convenient when you have a lot of listeners spread out across a number of distinct modules, and it really cuts down on what would otherwise be boilerplate XML configuration.

Not too sure whether it will make it into the Spring core seeing as it is really easy to implement by oneself, but it is a useful Spring-ish pattern.

Cheers
Rick (Spring Developer)

Geoffrey Wiseman said...

It can be valuable to offer the 'pattern' so that people consider framing their problems this way, particularly when they're new to the idea.

Likewise, if it's something that a lot of people are doing, it's helpful to not have to implement it repeatedly (or find your own reuse strategy).

That said, I won't be broken up if it doesn't go in, and I have to implement it myself. It is, as you say, fairly easy to do.

rainwebs said...

Maybe interesting to you how I used the concept in JSF enviroments:

http://blog.rainer.eschen.name/2006/11/16/the-observer-pattern-in-mixed-dependency-injection-contexts-spring-jsf/