Consider the following situation: You have a singleton service manager bean that should be the access point for a set of services. Obviously, at some time each service has to be registered with the service manager in order to be accessible to the application. But how should that be done?
A simple approach would be something like this:
Unfortunately, there are two drawback:
1. In a large application where bean definitions are divided into several XML files, we cannot add/remove a service without changing the bean definition of the ServiceManager bean. This destroys the modularity of the applications since an application module cannot add a service without a change to the application core (where the ServiceManager belongs). Note also that such a change would add a dependency from the core to the service module effectively "hard linking" the service module to the core.
2. Again, if the application is split into modules (each with its own bean definitions) all modules that declare services must be loaded at startup so that the service beans can be instantiated prior to the instantiation of the ServiceManager bean.
So, how do we get around these problems? Is there any support for calling a registration method on another bean when a bean is instantiated?
So far, the only solution I've come up with is to use MethodInvokingFactoryBean:
This, however, is more of a hack than an actual solution (and also seems far to verbose). There is also another problem that I didn't mention before: If an application module is to be deactivated/removed at runtime (say, in an OSGi environment) this does not say how to unregister the service when the "SubBeanFactory" of the service module is destroyed.
Enough talk... anyone got some good ideas on how to implement this?
Best regards,
Soren Petersen
A simple approach would be something like this:
Code:
<bean id="ServiceManager" class="..."> <property name="services"> <list> <value ref="Service1" /> <value ref="Service2" /> </list> </property> </bean> <bean id="Service1" class="..." /> <bean id="Service2" class="..." />
Unfortunately, there are two drawback:
1. In a large application where bean definitions are divided into several XML files, we cannot add/remove a service without changing the bean definition of the ServiceManager bean. This destroys the modularity of the applications since an application module cannot add a service without a change to the application core (where the ServiceManager belongs). Note also that such a change would add a dependency from the core to the service module effectively "hard linking" the service module to the core.
2. Again, if the application is split into modules (each with its own bean definitions) all modules that declare services must be loaded at startup so that the service beans can be instantiated prior to the instantiation of the ServiceManager bean.
So, how do we get around these problems? Is there any support for calling a registration method on another bean when a bean is instantiated?
So far, the only solution I've come up with is to use MethodInvokingFactoryBean:
Code:
<bean id="ServiceManager" class="..." /> <bean id="Service1" class="..." /> <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> <property name="targetObject" ref="ServiceManager" /> <property name="targetMethod" value="registerService" /> <property name="arguments"> <list> <ref bean="Service1" /> </list> </property> </bean> <bean id="Service2" class="..." /> <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> <property name="targetObject" ref="ServiceManager" /> <property name="targetMethod" value="registerService" /> <property name="arguments"> <list> <ref bean="Service2" /> </list> </property> </bean>
Enough talk... anyone got some good ideas on how to implement this?
Best regards,
Soren Petersen
Comment