java - 在 OSGi 引用注释中动态设置目标属性

标签 java osgi apache-felix declarative-services

阅读 article 之后在 Reference target (和相应的属性),我仍然不明白如何在 target 时检索服务在运行时设置(通常目标和属性在编译时设置并由 SCR 在运行时评估)。

假设有三个服务实现定义了 @Property(name="type", value="csv") , @Property(name="type", value="xls")@Property(name="type", value="pdf") , 分别。

一个消费者:

//@Reference(target="(type=%runtime_variable%)")
Service service;

注意 %runtime_variable%在运行时自动评估(从设置文件中读取)。


我应该调用getServiceReferences(Class<S> clazz, String filter)吗?在@Activate/@Modified注释方法以便在运行时获得正确的服务?

如果我不显式使用 @Reference,如何创建 component.xml并在 @Activate 中动态设置目标/@Modified注释方法?

我可以使用 @Designate 吗?元类型注解让我的生活更简单?

最佳答案

那个article ,你读过,是 7 岁,我不清楚它使用了哪些注释(是的,有几个)。我建议忽略它。今天你最好使用Declarative Services (DS)以及标准的 OSGi 注释。

简而言之,有两个重要部分:

  • /OSGI-INF 文件夹中的 XML 文件提供/消费服务
  • 服务组件运行时 (SCR) - 一个在运行时检查其他 bundle 的 bundle ,如果它找到上述 XML 文件,则负责注册和连接服务。

虽然您可以手动编写 XML 文件,但它们通常由 Bnd 生成或其他使用 Bnd 的构建工具(例如我们 bnd-maven-plugin )。这是在构建时完成的,当时 Bnd 检查您的类的注释并使用提供的信息来生成 XML 文件。因此在运行时根本不使用注释。

至于布线,当你有

   @Reference(target="(type=pdf)")
   Service service;

字段 service 将自动连接到在 OSGi 的服务注册表中注册的与目标匹配的 Service 服务实例之一(是的,可以有多个)筛选。这是由 SCR 在运行时完成的。您可以通过使用组件的 PID 重新配置组件来在运行时更改目标。您可以使用 Configuration Admin 以编程方式或通过属性文件执行此操作.

您提到的@Designate 注释与另一个称为Metatype 的OSGi 规范有关。它允许您更好地定义配置字段的类型。 Here您可以阅读有关如何将 Metatype 与 Declarative Services 1.3 一起使用的更多信息。

关于 OSGi 注释的另一个很好的信息来源是 here (忽略 Liferay 特定的)


为了反射(reflect)您编辑的问题,您有一些选择。一种是获取所有实例:

@Reference(
 cardinality = ReferenceCardinality.MULTIPLE,
 policy = ReferencePolicy.DYNAMIC,
 policyOption = ReferencePolicyOption.GREEDY
 )
protected void setService(Service service, Map<String, Object> properties) {
   String type = MapUtil.getString(properties, "type");
   _services.put(type, service);
}

然后你可以从 _services map 按类型获取你的服务。另一个是重新配置您的组件。例如,如果你这样定义它

@Component(
 configurationPid = "my.component"
)
public class MyComponent implements ... {
   @Reference(target="(type=pdf)")
   Service myService;
}    

你可以通过 my.component.cfg 在你指定的地方配置它

myService.target=(type=somethingElse)

您可以使用配置管理 API 以编程方式执行相同的操作。

关于java - 在 OSGi 引用注释中动态设置目标属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47393876/

相关文章:

java - 在 json 中解析尾随字符

java - OSGi 包从另一个包访问 Spring 上下文文件

java - 组件提供服务

Android mkdirs() 创建一个零字节文件而不是文件夹

java - felix scr 注释中元类型属性的用例

java - 新的 Java 9 平台模块系统如何集成到 Maven 中?

ListView 的 Java 字符串形成

java - 如何避免长 switch/case 语句?

java - OSGI:是否可以在不激活 bundle 的情况下导入包?

java - 无法在 Osgi Blueprint 中动态绑定(bind)服务