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.