That article https://thecarlhall.wordpress.com/2010/06/06/set-osgi-service-reference-target-through-configuration/,你已经读过,已经有 7 岁了,我不清楚它使用了哪些注释(是的,有几个)。我建议忽略它。今天你最好使用声明式服务 (DS) https://enroute.osgi.org/FAQ/300-declarative-services.html以及标准 OSGi 注释。
简而言之,有两个重要部分:
- XML 文件位于
/OSGI-INF
提供/消费服务的包内的文件夹
- 服务组件运行时 (SCR) - 一个在运行时检查其他包的包,如果它找到上述 XML 文件,则负责注册和连接服务。
虽然您可以手动编写 XML 文件,但它们通常是由Bnd http://bnd.bndtools.org/或其他使用 Bnd 的构建工具(例如我们bnd-maven-插件 https://github.com/bndtools/bnd/tree/master/maven/bnd-maven-plugin)。这是在构建时完成的,当时 Bnd 检查类的注释并使用提供的信息生成 XML 文件。因此,在运行时根本不使用注释。
至于接线,当你有
@Reference(target="(type=pdf)")
Service service;
场service
将自动连接到其中一个实例(是的,可以有多个)Service
在 OSGi 的服务注册表中注册的与目标过滤器匹配的服务。这是由 SCR 在运行时完成的。您可以通过使用组件的 PID 重新配置组件来在运行时更改目标。您可以通过编程方式或通过属性文件使用配置管理 https://osgi.org/specification/osgi.cmpn/7.0.0/service.cm.html.
The @Designate
您提到的注释与另一个名为 Metatype 的 OSGi 规范相关。它允许您更好地定义配置字段的类型。Here http://njbartlett.name/2015/08/17/osgir6-declarative-services.html您可以阅读有关如何将 Metatype 与 Declarative Services 1.3 一起使用的更多信息。
关于 OSGi 注释的另一个很好的信息来源是here https://liferay.dev/blogs/-/blogs/liferay-osgi-annotations-what-they-are-and-when-to-use-them(忽略 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)
您可以使用配置管理 API 以编程方式执行相同的操作。