如何在运行时控制OSGi中的依赖注入

时间:2017-11-10 18:41:20

标签: java dependency-injection osgi apache-felix

我试图了解如何控制OSGi中的依赖注入(特别是Adobe Experience Manager(AEM)中使用的Apache Felix)。我在一个引用接口的字段上有一个带有@Reference注释的servlet - 在我的例子中,它代表一个安全的文档签名提供者。我有一个实现接口的实现类,它会自动注入到servlet中。

在servlet中:

@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
private DocumentSigningProvider signingProvider;
...
URL redirectUrl = signingProvider.Sign(...);

和我的实现类:

@Component(metatype=true)
@Service
@Property(name = "service.ranking", intValue = 1000)
public class DocumentSigningProviderDocuSignImpl implements DocumentSigningProvider {

如果我写第二个实现,我可以控制通过service.ranking值注入哪一个 - 最高数量获胜。如果没有在任何实现上声明排名,则最早的获胜。

到目前为止,非常好 - 除了要更改我需要重新编译和重新部署的值。我需要在运行时控制它,或者通过绑定到环境的配置文件或运行模式"来控制它。我无法看到如何做到这一点。

由于@Component在中声明metatype=true@Property注释,因此该类会在OSGi控制台的GUI中生成控件。我可以使用该GUI在运行时更改值。但service.ranking在类本身的@Property 中声明,并且它似乎不会在GUI中生成控件。

此外,以类命名的配置文件在运行时提供默认值,并且我可以为每个环境或" runmode"提供不同的配置文件。这对我也有用;在一个环境中,我可以配置模拟实现,并使用" real"在另一个环境中实现。但同样,这些配置文件似乎适用于} 类中的@Property声明,但不适用于 类。

我已经在这里阅读了很多关于这个主题的帖子,但没有涉及在OSGi GUI或配置文件中公开service.ranking

有没有办法控制注入哪个类而不修改,重新编译和重新部署源代码?

1 个答案:

答案 0 :(得分:1)

在声明性服务中,您可以通过为组件提供配置并设置属性来在运行时覆盖任何服务属性。 因此,设置service.ranking=1或类似内容实际上应该有效。

有一点需要注意。默认情况下,声明性服务绑定到第一个可用服务并保持不变。因此,如果您想确保使用排名较高的服务,即使它比排名较低的服务要晚,那么您需要在消费者方面使用此选项:

@Reference(policyOption=ReferencePolicyOption.GREEDY)

如果以后有更好的服务,这可以确保DS切换服务。

如果您想更具体地说明在消费者方面使用哪种服务,您还可以在运行时使用过滤器。

target.signingProvider=(myproperty=myvalue)

我收集了更多提示here