@Retention(value=CLASS)
@Target(value={METHOD,FIELD})
public @interface ServiceDependency
@Component class MyComponent { @ServiceDependency(timeout=15000) MyDependency dependency;
Modifier and Type | Optional Element and Description |
---|---|
java.lang.String |
added
The callback method to be invoked when the service is available.
|
java.lang.String |
changed
The callback method to be invoked when the service properties have changed.
|
java.lang.Class<?> |
defaultImpl
The class for the default implementation, if the dependency is not available.
|
java.lang.String |
filter
The Service dependency OSGi filter.
|
java.lang.String |
name
The name used when dynamically configuring this dependency from the init method.
|
boolean |
propagate
Returns true if the dependency service properties must be published along with the service.
|
java.lang.String |
removed
The callback method to invoke when the service is lost.
|
boolean |
required
Whether the Service dependency is required or not.
|
java.lang.Class<?> |
service
The type if the service this dependency is applying on.
|
long |
timeout
The max time in millis to wait for the dependency availability.
|
public abstract java.lang.Class<?> service
public abstract java.lang.String filter
public abstract java.lang.Class<?> defaultImpl
public abstract boolean required
public abstract java.lang.String added
public abstract java.lang.String changed
public abstract java.lang.String removed
public abstract long timeout
IllegalStateException
exception is raised (but the service is not deactivated).Notice that the changed/removed callbacks are not used when the timeout parameter is > -1.
-1 means no timeout at all (default). 0 means that invocation on a missing service will fail immediately. A positive number represents the max timeout in millis to wait for the service availability.
Sample Code:
@Component class MyServer implements Runnable { @ServiceDependency(timeout=15000) MyDependency dependency;. @Start void start() { (new Thread(this)).start(); } public void run() { try { dependency.doWork(); } catch (IllegalStateException e) { t.printStackTrace(); } }
public abstract java.lang.String name
filter
and required
flag from the Service's init method.
All unnamed dependencies will be injected before the init() method; so from the init() method, you can
then pick up whatever information needed from already injected (unnamed) dependencies, and configure dynamically
your named dependencies, which will then be calculated once the init() method returns.
Usage example of a Service whose dependency filter is configured from ConfigAdmin:
/** * A Service whose service dependency "otherService" filter is configured from ConfigAdmin */ @Service class X { private Dictionary m_config; /** * Initialize our service from config ... and store the config for later usage (from our init method) */ @ConfigurationDependency(pid="MyPid") void configure(Dictionary conf) { m_config = config; } /** * All unnamed dependencies are injected: we can now configure other named * dependencies, using the already injected configuration. * The returned Map will be used to configure our "otherService" Dependency. */ @Init Map init() { return new HashMap() {{ put("otherService.filter", m_config.get("filter")); put("otherService.required", m_config.get("required")); }}; } /** * This named dependency filter/required flag will be configured by our init method (see above). */ @ServiceDependency(name="otherService") void bindOtherService(OtherService other) { } /** * All dependencies are injected and our service is now ready to be published. * Notice that you can also use the publisher service attribute if you need * to take control on service exposition. */ @Start void start() { } }
public abstract boolean propagate