@Retention(value=CLASS)
@Target(value=METHOD)
public @interface ConfigurationDependency
In the following example, the "Printer" component depends on a configuration whose PID name is "sample.PrinterConfiguration". This service will initialize its ip/port number from the provided configuration.
First, we define the configuration metadata, using standard bndtools metatatype annotations (see http://www.aqute.biz/Bnd/MetaType):
Next, we define our Printer service which depends on the PrinterConfiguration:package sample; import aQute.bnd.annotation.metatype.Meta.AD; import aQute.bnd.annotation.metatype.Meta.OCD; @OCD(description = "Declare here the Printer Configuration.") public interface PrinterConfiguration { @AD(description = "Enter the printer ip address") String ipAddress(); @AD(description = "Enter the printer address port number.") int portNumber(); }
In the above example, the updated callback accepts a type-safe configuration type (and its fqdn is used as the pid).package sample; import aQute.bnd.annotation.metatype.*; @Component public class Printer { @ConfigurationDependency // Will use the fqdn of the PrinterConfiguration interface as the pid. void updated(PrinterConfiguration cnf) { String ip = cnf.ipAddress(); int port = cnf.portNumber(); ... } }
Configuration type is a new feature that allows you to specify an interface that is implemented
by DM and such interface is then injected to your callback instead of the actual Dictionary.
Using such configuration interface provides a way for creating type-safe configurations from a actual Dictionary
that is
normally injected by Dependency Manager.
The callback accepts in argument an interface that you have to provide, and DM will inject a proxy that converts
method calls from your configuration-type to lookups in the actual map or dictionary. The results of these lookups are then
converted to the expected return type of the invoked configuration method.
As proxies are injected, no implementations of the desired configuration-type are necessary!
The lookups performed are based on the name of the method called on the configuration type. The method names are "mangled" to the following form: [lower case letter] [any valid character]*. Method names starting with get or is (JavaBean convention) are stripped from these prefixes. For example: given a dictionary with the key "foo" can be accessed from a configuration-type using the following method names: foo(), getFoo() and isFoo().
The return values supported are: primitive types (or their object wrappers), strings, enums, arrays of
primitives/strings, Collection
types, Map
types, Class
es and interfaces. When an interface is
returned, it is treated equally to a configuration type, that is, it is returned as a proxy.
Arrays can be represented either as comma-separated values, optionally enclosed in square brackets. For example: [ a, b, c ] and a, b,c are both considered an array of length 3 with the values "a", "b" and "c". Alternatively, you can append the array index to the key in the dictionary to obtain the same: a dictionary with "arr.0" => "a", "arr.1" => "b", "arr.2" => "c" would result in the same array as the earlier examples.
Maps can be represented as single string values similarly as arrays, each value consisting of both the key and value separated by a dot. Optionally, the value can be enclosed in curly brackets. Similar to array, you can use the same dot notation using the keys. For example, a dictionary with
"map" => "{key1.value1, key2.value2}"
and a dictionary with
"map.key1" => "value1", "map2.key2" => "value2"
result in the same map being returned.
Instead of a map, you could also define an interface with the methods getKey1() and getKey2 and use
that interface as return type instead of a Map
.
In case a lookup does not yield a value from the underlying map or dictionary, the following rules are applied:
Class
es and enum values yield null
;
Modifier and Type | Optional Element and Description |
---|---|
java.lang.String |
description
Deprecated.
use standard bndtools metatype annotations instead (see http://www.aqute.biz/Bnd/MetaType)
|
java.lang.String |
heading
Deprecated.
use standard bndtools metatype annotations instead (see http://www.aqute.biz/Bnd/MetaType)
|
PropertyMetaData[] |
metadata
Deprecated.
use standard bndtools metatype annotations instead (see http://www.aqute.biz/Bnd/MetaType)
|
java.lang.String |
name
The name for this configuration dependency.
|
java.lang.String |
pid
Returns the pid for a given service (by default, the pid is the service class name).
|
java.lang.Class<?> |
pidClass
Deprecated.
just define an updated callback which accepts as argument a configuration type.
|
boolean |
propagate
Returns true if the configuration properties must be published along with the service.
|
public abstract java.lang.String pid
public abstract java.lang.Class<?> pidClass
public abstract boolean propagate
public abstract java.lang.String name
Usage example of a Configuration dependency whose pid and propagate flag is configured dynamically from init method:
/** * A Service that dynamically defines an extra dynamic configuration dependency from its init method. */ @Component class X { private Dictionary m_config; // Inject initial Configuration (injected before any other required dependencies) @ConfigurationDependency void componentConfiguration(Dictionary config) { // you must throw an exception if the configuration is not valid m_config = config; } /** * All unnamed dependencies are injected: we can now configure our dynamic configuration whose dependency name is "global". */ @Init Map init() { return new HashMap() {{ put("global.pid", m_config.get("globalConfig.pid")); put("global.propagate", m_config.get("globalConfig.propagate")); }}; } // Injected after init, and dynamically configured by the init method. @ConfigurationDependency(name="global") void globalConfiguration(Dictionary globalConfig) { // you must throw an exception if the configuration is not valid } /** * All dependencies are injected and our service is now ready to be published. */ @Start void start() { } }
public abstract java.lang.String heading
public abstract java.lang.String description
public abstract PropertyMetaData[] metadata