在OSGi参考注释中动态设置目标属性 [英] Dynamically setting target property in OSGi Reference annotatation

查看:174
本文介绍了在OSGi参考注释中动态设置目标属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在阅读文章之后参考目标(以及相应的属性),当在运行时设置了target 时,我仍然不了解如何检索服务(通常目标和属性是在编译时设置,并在运行时由SCR进行评估.

After reading an article on Reference target (and corresponding properties), I still don't understand how to retrieve a service, when target is set at runtime (typically target and properties are set at compile time and evaluated by SCR at runtime).

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

Let's say there are three service implementations defining@Property(name="type", value="csv"), @Property(name="type", value="xls") and @Property(name="type", value="pdf"), respectively.

一名消费者:

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

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

NOTE %runtime_variable% is automatically evaluated at runtime (read from a settings file).

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

Should I just call getServiceReferences(Class<S> clazz, String filter) in the @Activate/@Modified annotated method in order to get the right service at runtime?

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

How is the component.xml created, if I don't explicitly use @Reference and dynamically set the target in the @Activate/@Modified annotated method?

我可以使用

And can I use the@Designate metatype annotation to make my life simpler here?

推荐答案

声明性服务(DS)和标准的OSGi注释

That article, you have read, is 7 year old and it is not clear to me which annotations it uses (yes, there are several). I'd suggest to ignore it. Today you better use Declarative Services (DS) and the standard OSGi annotations.

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

In short there are 2 important pieces:

    捆绑包内提供/使用服务的/OSGI-INF文件夹中的
  • XML文件
  • 服务组件运行时(SCR)-一个在运行时检查其他捆绑软件的捆绑软件,如果找到上述XML文件,则负责注册和连接服务.
  • XML files in /OSGI-INF folder inside the bundles providing / consuming services
  • Service Component Runtime (SCR) - a bundle that inspects other bundles at runtime and if it finds the above XML files, takes care of registering and wiring the services.

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

While you can write the XML files by hand, they are typically generated by Bnd or other build tools using Bnd (such us bnd-maven-plugin). This is done at build time when Bnd inspects your classes for annotations and uses the information provided to generate the XML files. Thus the annotations are not used at all at runtime.

关于接线,当您拥有

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

字段service将自动连接到在OSGi的服务注册表中注册的与目标过滤器匹配的Service服务的一个实例(是的,可以有多个).这是在运行时由SCR完成的.您可以在运行时通过使用组件的PID重新配置组件来更改目标.您可以通过程序或使用配置管理器 a>.

The field service will be automatically wired to one of the instances (yes there can be more than one) of Service service registered in OSGi's service registry that matches the target filter. This is done at runtime by SCR. You can change the target at runtime by reconfiguring your component using its PID. You can do that programmatically or via properties files using Configuration Admin.

您提到的@Designate批注与另一个名为Metatype的OSGi规范有关.它使您可以更好地定义配置字段的类型. 在这里,您可以阅读有关如何将Metatype与声明式服务1.3.

The @Designate annotation you mentioned relates to another OSGi specification called Metatype. It allows you to better define the types of the configuration fields. Here you can read more about how to use Metatype together with Declarative Services 1.3.

关于OSGi注释的另一个很好的信息来源是

Another good source of information regarding OSGi annotations is here (ignore the Liferay specific ones)

要反映您已编辑的问题,您可以选择一些方法.一种是获取所有实例:

To reflect your edited question, you have some options. One is to get all instances:

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

Then you can get your service from _services map by type. Another is reconfigure your component. For example if you define it like this

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

您可以通过my.component.cfg在其中指定

myService.target=(type=somethingElse)

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

You can do the same programmatically using the Configuration Admin API.

这篇关于在OSGi参考注释中动态设置目标属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆