article,你已经读过,已经 7 岁了,我不清楚它使用了哪些注释(是的,有几个)。我建议忽略它。今天你最好使用Declarative Services (DS) 和标准的OSGi 注释。
简而言之,有两个重要部分:
- 提供/消费服务的捆绑包内
/OSGI-INF 文件夹中的 XML 文件
- 服务组件运行时 (SCR) - 一个在运行时检查其他包的包,如果找到上述 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 与声明式服务 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 map 按类型获取您的服务。另一个是重新配置您的组件。例如,如果你这样定义它
@Component(
configurationPid = "my.component"
)
public class MyComponent implements ... {
@Reference(target="(type=pdf)")
Service myService;
}
您可以通过您指定的my.component.cfg 对其进行配置
myService.target=(type=somethingElse)
您可以使用 Configuration Admin API 以编程方式执行相同操作。