首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >在OSGi参考注释中动态设置目标属性

在OSGi参考注释中动态设置目标属性
EN

Stack Overflow用户
提问于 2017-11-20 14:03:33
回答 3查看 4.6K关注 0票数 3

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

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

和一个消费者:

代码语言:javascript
代码运行次数:0
运行
复制
//@Reference(target="(type=%runtime_variable%)")
Service service;

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

我是否应该在@Activate/@Modified注释方法中调用@Activate,以便在运行时获得正确的服务?

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

我可以使用@Designate元类型注释来简化这里的生活吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-11-20 16:00:49

您已经阅读过的文章已经7岁了,我不清楚它使用了哪些注释(是的,有几个)。我建议忽略它。现在,您最好使用声明式服务(DS)和标准的OSGi注释。

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

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

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

至于电线,当你有

代码语言:javascript
代码运行次数:0
运行
复制
   @Reference(target="(type=pdf)")
   Service service;

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

您提到的@Designate注释与另一个名为元类型的OSGi规范有关。它允许您更好地定义配置字段的类型。这里您可以阅读更多关于如何使用元类型和声明性服务1.3的内容。

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

为了反映您编辑的问题,您有一些选项。一是获取所有实例:

代码语言:javascript
代码运行次数:0
运行
复制
@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地图获取服务。另一个是重新配置组件。例如,如果您像这样定义它

代码语言:javascript
代码运行次数:0
运行
复制
@Component(
 configurationPid = "my.component"
)
public class MyComponent implements ... {
   @Reference(target="(type=pdf)")
   Service myService;
}    

您可以通过my.component.cfg配置它,在其中指定

代码语言:javascript
代码运行次数:0
运行
复制
myService.target=(type=somethingElse)

您可以使用Configuration以编程方式进行同样的操作。

票数 3
EN

Stack Overflow用户

发布于 2017-11-20 17:02:52

简单地使用

代码语言:javascript
代码运行次数:0
运行
复制
@Reference
Service myService;

然后,在运行时为组件创建一个配置,并设置如下过滤器:

代码语言:javascript
代码运行次数:0
运行
复制
myService.target=(mykey=1)
票数 2
EN

Stack Overflow用户

发布于 2018-11-19 13:05:50

你可以这样做:

代码语言:javascript
代码运行次数: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创建配置文件:

代码语言:javascript
代码运行次数:0
运行
复制
myService.target="(type\=pdf)"

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47393876

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档