【发布时间】:2016-04-29 08:00:57
【问题描述】:
我正在使用 OSGi DS 组件和 ConfigurationAdmin。
我创建了一个简单的可配置组件
@Component(service=ConfigurableService.class)
public class ConfigurableService {
private String message;
@Activate
public void activate(Map<String, Object> params) {
System.out.println("Activate configurable");
message = (String) params.get("msg");
}
@Modified
public void modified(Map<String, Object> params) {
System.out.println("Modify configurable");
message = (String) params.get("msg");
}
@Deactivate
public void deactivate(Map<String, Object> params) {
System.out.println("Deactivate configurable");
message = (String) params.get("msg");
}
public void execute() {
System.out.println("Service says: " + message);
}
}
然后我创建了一个 Felix Gogo shell 命令组件来通过 ConfigurationAdmin 触发配置
@Component(property = {
CommandProcessor.COMMAND_SCOPE + "=fipro",
CommandProcessor.COMMAND_FUNCTION + "=configure"
},
service = ConfigurationCommand.class
)
public class ConfigurationCommand {
private ConfigurationAdmin cm;
@Reference(unbind="-")
public void setConfigAdmin(ConfigurationAdmin cm) {
this.cm = cm;
}
public void configure(String input) throws IOException {
Configuration config = cm.getConfiguration("org.fipro.osgi.config.ConfigurableService");
Hashtable<String, Object> props = new Hashtable<>();
props.put("msg", input);
config.update(props);
}
}
最后,我创建了另一个使用 ConfigurableService 的 Felix Gogo shell 命令组件
@Component(property = {
CommandProcessor.COMMAND_SCOPE + "=fipro",
CommandProcessor.COMMAND_FUNCTION + "=welcome"
},
service = WelcomeCommand.class
)
public class WelcomeCommand {
private ConfigurableService service;
@Reference(unbind="-")
public void setConfigurable(ConfigurableService service) {
this.service = service;
}
public void updatedConfigurable(ConfigurableService service, Map<String, Object> properties) {
System.out.println("ConfigurableService updated");
}
public void welcome() {
service.execute();
}
}
如果我使用包含这些组件的捆绑包启动一个 OSGi 应用程序,我希望在最初执行 welcome 时,我会看到组件已激活并且服务输出为空,因为尚未应用任何配置(确保此连续呼叫的变化)。如果我之后执行configure Dirk,我希望执行带有@Modified 注释的方法以指示服务配置已更新。我还希望执行WelcomeCommand 中的updatedConfigurable 方法。至少这是我阅读规范后的理解。
现在我观察到 Equinox 和 Felix 的不同行为。
春分:
修改后的方法按预期调用,ConfigurableService 配置正确。但是updatedConfigurable(<Service>, <Map>) 没有被调用。只有当我将方法签名更改为采用ServiceReference 时,更新的方法才会被调用。
规范说所有引用事件方法都支持以下方法签名
void <method-name>(ServiceReference);
void <method-name>(<parameter-type>);
void <method-name>(<parameter-type>, Map);
我在规范中没有看到的更新方法是否有例外,或者这是 Equinox 中我应该提出票证的问题?
菲利克斯:
如果我在 Bndtools 中的 Felix 上运行相同的示例,修改和更新方法都不会被调用。我检查了ConfigurationCommand,并且有一个 ConfigurationAdmin 可用,所以更新配置没有例外。但它永远不会以某种方式应用。
在 Felix 上运行示例时我是否遗漏了什么?
更新:
将控制台输出添加到每个生命周期事件方法会创建以下输出:
____________________________
Welcome to Apache Felix Gogo
g! ConfigurationCommand: Activate
ConfigurableService: Activate
WelcomeCommand: Activate
welcome
Service says: null
g! configure Dirk
g! welcome
Service says: null
g! exit 0
WelcomeCommand: Deactivate
ConfigurableService: Deactivate
ConfigurationCommand: Deactivate
如您所见,从不调用 modify 和 updated 事件。
【问题讨论】:
标签: java osgi apache-felix equinox declarative-services