在OSGi参考注释

时间:2017-11-20 14:03:34

标签: 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并在@Activate / @Modified带注释的方法中动态设置目标,那么component.xml是如何创建的?

我可以使用@Designate元数据注释来让我的生活变得更简单吗?

3 个答案:

答案 0 :(得分:2)

你读过的https://jsbin.com/muqifojaza/edit?html,js,output是7岁,我不清楚它使用哪种注释(是的,有几种注释)。我建议忽略它。今天你最好使用article和标准的OSGi注释。

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

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

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

关于布线,当你有

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

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

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

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

要反映您编辑的问题,您有一些选择。一个是获取所有实例:

@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地图获取服务。另一个是重新配置您的组件。例如,如果你这样定义它

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

您可以通过指定

my.component.cfg对其进行配置
myService.target=(type=somethingElse)

您可以使用Configuration Admin API以编程方式执行相同操作。

答案 1 :(得分:2)

只需使用

@Reference
Service myService;

在运行时,您可以为组件创建配置并设置如下过滤器:

myService.target=(mykey=1)

答案 2 :(得分:0)

您可以执行以下操作:

@Property(name = "myService.target", label = "My Service", description = "The target reference for the MyService, e.g. use target=(type=html) to bind to services by type.")
@Reference(name = "myService")
private Service myService;

然后可以为组件com.example.impl.MyComponent.config创建配置文件:

myService.target="(type\=pdf)"

您还可以在运行时使用Apache Felix Web Console(http://localhost:8888/system/console/configMgr)更改此值。