You can do it with ManagedServiceFactory and a few lines of code.
Define a bean for the Factory, and inject the BundleContext. Chose a Pid to later identify and configure this Factory:
<bean id="myServiceFactory" class="org.my.MyServiceFactory" init-method="init" destroy-method="destroy">
<property name="bundleContext" ref="blueprintBundleContext"/>
<property name="configurationPid" value="org.my.pid"/>
</bean>
Implement the service Factory (not working code, just to give you an idea):
public class MyServiceFactory implements ManagedServiceFactory {
private BundleContext bundleContext;
private String configurationPid;
public void setConfigurationPid(String configurationPid) {
this.configurationPid = configurationPid;
}
public void setBundleContext(BundleContext bundleContext) {
this.bundleContext = bundleContext;
}
public void init() {
// your setup goes here
}
public void destroy() {
// your shutdown logic goes here
}
@Override
public String getName() {
return configurationPid;
}
@Override
public void updated(String pid, Dictionary dict) throws ConfigurationException {
// Instantiate each service with its own properties
MyServiceImpl service = new MyServiceImpl(dict);
Dictionary servProps = new Properties();
servProps.put("custom.service.property", "an id or someting")
bundleContext.registerService(MyServiceImpl.class.getName(), service, servProps);
// save your servicereferences to unregister, eg in a map
// you can customize your service by giving some property to later retrieve it
}
@Override
public void deleted(String pid) {
// get the ServiceReference from some map
servicereference.unregister();
}
}
The ManagedServiceFactory has one method init()
to setup all required resources, a destroy()
method to clean up (for example by unregistering all the services).
A new service instance is created for each config file in etc/org.my.pid-*.cfg
, for example to create 3 instances of a service:
etc/org.my.pid-serviceinstance1.cfg
etc/org.my.pid-serviceinstance2.cfg
etc/org.my.pid-whatever.cfg
To get a particular instance of the service, register them with some custom property (like custom.service.property
in my example). Then in a consumer bundle ask for an instance of MyService
with custom.service.property
= serviceinstance2 and you're done.
You can even create new CamelContexts this way. There is a complete tutorial on PacktPub website.
edit:
When you write a new file in etc/org.my.pid-*
the updated()
method is called and a new service deployed. When a file is removed, the deleted()
method is called and you must destroy and unregister the service. Of course, you can add/delete/modify files with JBoss/Karaf running :-) without stopping the main bundle.