There is an interesting interface called ServiceFactory. Citing the documentation (link at end), it
Allows services to provide customized service objects in the OSGi environment.
When registering a service, a ServiceFactory object can be used instead of a service object, so that the bundle developer can gain control of the specific service object granted to a bundle that is using the service.
So what does that mean?
- The service object can be created when the consuming bundle asks for it.
In the normal scenario a service object is created and then registered when the bundle is started. With the ServiceFactory, the consuming bundle asks for the service and then the provider bundle creates the service object. (You don't need to register the newly created service object; the registration was already done with the ServiceFactory instance.) - The ServiceFactory can return service objects which are different for each requesting bundle.
In the normal scenario a service object is created and used by whichever bundle wants it. Now for each bundle which requests the service, the method ServiceFactory.getService is called and allows to return a new instance. - The ServiceFactory can customize service objects before making them available.
For instane the ServiceFactory instance can inspect the Bundle which requests the service object (like looking at certain entries in the MANIFEST). Depending on that inspection it can return different types of service objects or service objects with different configurations.
There are some interesting runtime details too:
- Service objects are cached by the framework.
When a bundle requests a service, it gets delivered a service object. The next request call will deliver the same service object (unless it has been released in between). When the consuming bundle calls ungetService to tell that it doesn't need the service object anymore, the method ServiceFactory.ungetService is called by the framework. (Actually ungetService must be called as many times as getService, the framework maintains a use count.)
However, for a second bundle, the service objects of the first bundle are not reused by the framework. If two bundles retrieve a service and thus use the ServiceFactory, its getService method gets called for each of the bundles.
Samples in osgisnippets Project
The project osgisnippets contains a set of bundles with the name starting with set3. set3fac provides services using the ServiceFactory. set3cons1 and set3cons2 are two almost identical bundles, which consume the service. They create a window with a get and an unget button. The ServiceFactory provides a unique ID for each service object. The ID of the service object is shown by the consuming bundles in their window.
Resources
-
ServiceFactory API doc:
http://www.osgi.org/javadoc/r5/core/org/osgi/framework/ServiceFactory.html -
Official OSGi Site:
OSGi R4: http://www.osgi.org/Release4/Download
(OSGi R5: http://www.osgi.org/Release5/Download) -
Source code of OSGi snippets is at the project site:
https://sourceforge.net/projects/osgisnippets/