3

我遇到了一个案例,我想在运行时使用 Blueprint (Aries) 来解决依赖关系,并且实现是在需要它的同一个包中定义的,并且不会在任何其他包中使用。我正在抽象这个包中的实现,以便在单元测试时更容易模拟依赖项。如果我将此服务放在自己的捆绑包中,则会导致内聚性差。

在运行时,蓝图表示它正在等待依赖项。如何使用 Blueprint 在包中实现依赖注入?

<!-- Interface -->
<reference id="modelEntityMapper" interface="org.example.blog.rest.cxf.server.model.ModelEntityMapper" />
<!-- Implementation defined within same bundle -->
<bean id="modelEntityMapperImpl" class="org.example.blog.rest.cxf.server.model.impl.ModelEntityMapperImpl" />
<service ref="modelEntityMapperImpl" interface="org.example.blog.rest.cxf.server.model.ModelEntityMapper" />

<!-- Object which has dependency -->
<bean id="posts" class="org.example.blog.rest.cxf.server.BlogResourceImpl">
        <property name="modelEntityMapper" ref="modelEntityMapper" />
</bean>

编辑

我刚刚尝试了@christian-scheider 的建议,Blueprint 仍在等待一些服务来满足 ModelEntityMapper

XML

<!-- Interface -->
<reference id="modelEntityMapper" interface="org.example.blog.rest.cxf.server.model.ModelEntityMapper" />
<!-- Implementation defined within same bundle -->
<bean id="modelEntityMapperImpl" class="org.example.blog.rest.cxf.server.model.impl.ModelEntityMapperImpl" />

<!-- Object which has dependency -->
<bean id="posts" class="org.example.blog.rest.cxf.server.BlogResourceImpl">
        <property name="modelEntityMapper" ref="modelEntityMapperImpl" />
</bean>

日志

Bundle rest-cxf-server is waiting for dependencies [(objectClass=org.example.blog.rest.cxf.server.model.ModelEntityMapper)]

4

2 回答 2

3

可以直接引用服务的bean吗?如果您在同一个蓝图文件中定义服务和服务引用,那么使用 OSGi 服务没有多大意义。

于 2013-01-09T09:16:41.187 回答
2

我无法在 Aries 网站上找到与在包中引用相关的详细文档,因此我将参考 Eclipse Gemini Blueprint 实现文档(以前称为 Spring Dynamic Modules)。请参阅其文档第 9.2.1.1 节中的警告。是的,从技术上讲,这与他们的实施有关,但我相信这可能是白羊座的类似故事。

声明对同样由同一个包导出的服务的强制引用是错误的,此行为可能导致应用程序上下文创建因死锁或超时而失败。

简而言之,您通常要么导入(引用)一个 OSGi 服务,要么在同一个包中导出一个 OSGi 服务,通常你不会尝试在一个包中同时执行这两种操作。

如果您希望此捆绑包导出类型的服务ModelEntityMapper,则需要将其与service元素一起导出。当其他 bean 需要在同一个包中引用时,您可以ref像使用它一样使用该属性。在这种情况下,您根本不需要该reference元素,而是使用该service元素。

如果您不打算在ModelEntityMapper此捆绑包之外使用 bean,则根本不需要在配置中使用referenceorservice元素。您应该能够在ref属性中使用它,而无需将其导出为 OSGi 服务 - 它基本上是该捆绑包内部的一个 bean。在这种情况下,您应该能够reference完全删除该元素:这<bean id="modelEntityMapperImpl" ...将在包内部创建一个 bean,并且该<property name="modelEntityMapper" ref="modelEntityMapperImpl" />元素应该能够在包内部使用该 bean。

如果您想ModelEntityMapper从 OSGi 导入类型的引用(如果可用),否则使用内部定义的回退,这会变得更加复杂。您必须声明一个非强制性的reference并将该引用与内部定义的 bean 一起注入到您的类中,然后使用默认逻辑来检查它们的可用性。或者,您可以只在与接口分开的包中定义实现。

于 2013-01-10T04:18:46.933 回答