In OSGi declarative services, I can create prototype instances declaring a ComponentServiceObjects
like this:
@Reference(unbind = "-",
scope=ReferenceScope.PROTOTYPE_REQUIRED)
private ComponentServiceObjects<MyService> serviceProvider;
and then instantiating the service with
service = serviceProvider.getService();
then I can finish the configuration of the instance by setting some other attributes (configuration values or non-OSGi collaborators) with setters. This has the problem, that the activation is performed before the initialization is complete.
Is there a way to inject this attributes before activating the service?
I am using DS in the context of Liferay Portal 7
EDIT
As a clarification I have an example: let's say I have a component DirectoryListener. And I want to initialize several instances of this component, each one with a different directory. I would like to make some initialization during the activation based on this directory.
The consumer of a service does not know anything about the implementing component... or indeed whether the service is implemented by a component at all, versus something more low-level. Therefore it cannot dictate the configuration of the component.
It sounds like your use-case demands making the directory part of the service API, and therefore your service interface should be DirectoryListenerFactory
. The component can be registered as a simple, singleton service and the directory would be passed via a method e.g. createListener(File dir)
.
In this scenario you need to be a little careful with lifecycle. If a client calls createListener
it should be careful to release that listener when it is no longer needed. For example DirectoryListener
could extend java.lang.AutoCloseable
.
Any service dependencies can be injected via @Reference
into the component class that implements the factory. I would expect them to be passed to the DirectoryListener
instances via constructor.