Annotates a method used to configure dynamic dependencies.
When this method is invoked, all required dependencies (except the ones declared with a
name
attribute) are already injected, and optional dependencies on class fields
are also already injected (possibly with NullObjects).
The purpose of the @Init method is to either declare more dynamic dependencies using the DM API, or to
return a Map used to dynamically configure dependencies that are annotated using a
name
attribute.
After the init method returns, the added or configured dependencies are then tracked, and when all
dependencies are injected, then the start method (annotated with @Start) is invoked.
The method annotated with @Init may have the following signatures,
- void init(Component component)
- void init()
- Map init(Component component)
- Map init()
When the init method defines a Component argument, it can then be used by the method to add more dependencie using the Dependency Manager API.
Usage Examples
In this sample, the "PersistenceImpl" component dynamically configures the "storage" dependency from the "init" method.
The dependency "required" flag and filter string are derived from an xml configuration that is already injected before the init
method.
@Component
public class PersistenceImpl implements Persistence {
// Injected before init.
@ConfigurationDependency
void updated(Dictionary conf) {
if (conf != null) {
_xmlConfiguration = parseXmlConfiguration(conf.get("xmlConfiguration"));
}
}
// Parsed xml configuration, where we'll get our storage service filter and required dependency flag.
XmlConfiguration _xmlConfiguration;
// Dynamically configure the dependency declared with a "storage" name.
@Init
Map<String, String> init() {
Map<String, String> props = new HashMap<>();
props.put("storage.required", Boolean.toString(_xmlConfiguration.isStorageRequired()))
props.put("storage.filter", "(type=" + _xmlConfiguration.getStorageType() + ")");
return props;
}
// Injected after init (dependency filter is defined dynamically from our init method).
@ServiceDependency(name="storage")
Storage storage;
// All dependencies injected, including dynamic dependencies defined from init method.
@Start
void start() {
log.log(LogService.LOG_WARNING, "start");
}
@Override
void store(String key, String value) {
storage.store(key, value);
}
}
Same example as above, but this time the dependency is added from the init method using the Dependency Manager API:
@Component
public class PersistenceImpl implements Persistence {
// Injected before init.
@ConfigurationDependency
void updated(Dictionary conf) {
if (conf != null) {
_xmlConfiguration = parseXmlConfiguration(conf.get("xmlConfiguration"));
}
}
// Parsed xml configuration, where we'll get our storage service filter and required dependency flag.
XmlConfiguration _xmlConfiguration;
// Dynamically configure the dependency declared with a "storage" name.
@Init
void init(org.apache.felix.dm.Comppnent myComponent) {
boolean required = _xmlConfiguration.isStorageRequired();
String filter = _xmlConfiguration.getStorageType();
DependencyManager dm = myComponent.getDependencyManager();
myComponent.add(dm.createServiceDependency().setService(Storage.class, filter).setRequired(required));
}
// Injected after init, later, when the dependency added from the init() method is satisfied
volatile Storage storage;
// All dependencies injected, including dynamic dependencies defined from init method.
@Start
void start() {
log.log(LogService.LOG_WARNING, "start");
}
@Override
void store(String key, String value) {
storage.store(key, value);
}
}
Same example as above, but this time the dependency is added from the init method using the Dependency Manager Lambda:
import static org.apache.felix.dm.lambda.DependencyManagerActivator.component;
@Component
public class PersistenceImpl implements Persistence {
// Injected before init.
@ConfigurationDependency
void updated(Dictionary conf) {
if (conf != null) {
_xmlConfiguration = parseXmlConfiguration(conf.get("xmlConfiguration"));
}
}
// Parsed xml configuration, where we'll get our storage service filter and required dependency flag.
XmlConfiguration _xmlConfiguration;
// Dynamically configure the dependency declared with a "storage" name.
@Init
void init(org.apache.felix.dm.Comppnent myComponent) {
boolean required = _xmlConfiguration.isStorageRequired();
String filter = _xmlConfiguration.getStorageType();
component(myComponent, comp -> comp.withSvc(Storage.class, filter, required));
}
// Injected after init, later, when the dependency added from the init() method is satisfied
volatile Storage storage;
// All dependencies injected, including dynamic dependencies defined from init method.
@Start
void start() {
log.log(LogService.LOG_WARNING, "start");
}
@Override
void store(String key, String value) {
storage.store(key, value);
}
}