4

我熟悉 Spring OSGI 和 Blueprint,但遇到了“类路径”困难(就像许多新手一样)。

我有两个 OSGI 包——一个定义了各种 bean(使用蓝图,没关系)并将它们作为服务导出;以及另一个引用服务 bean 的包(使用 Spring OSGI)并将它们插入到一些 Apache Camel 路由中。

服务提供者捆绑包的蓝图如下所示:

<service id="camelTsvDataFormat" 
    interface="org.apache.camel.spi.DataFormat"> 
    <bean class="org.apache.camel.component.flatpack.FlatpackDataFormat"/> 
</service> 

服务消费者包的 Spring 上下文如下所示:

<osgi:reference id="tsvDataFormat" 
    interface="org.apache.camel.spi.DataFormat" /> 

<camel:camelContext> 
    <route> 
        <from uri="vm:in"> 
        <setBody> 
            <constant>SELECT * FROM myTable</constant> 
        </setBody> 
        <to uri="jdbc:myDataSource" /> 
        <marshal ref="tsvDataFormat" /> 
        <to uri="file:/path/to/my/files/?fileName=out.tsv" /> 
    </route> 
</camel:camelContext> 

...但是在部署时,Spring“找不到类 [org.apache.camel.spi.DataFormat]”。我可以将该接口添加到我的 Bnd 指令的 Import-Package 部分,但是必须在不同的位置手动列出该类两次似乎是多余的。

另一种选择是在我自己的项目中扩展接口,这样 Bnd 会自动选择它,但这也很麻烦。

我想我希望 Spring 通过接口名称查找服务,而不必实际解析接口类。这是幼稚的吗?或者有没有办法让 Bnd 在我的 appContext 的服务引用中自动导入接口?如果 Bnd 可以做到这一点(例如使用插件),是否有一种标准方法可以将 Bnd 插件与 Maven 的 Apache Felix 捆绑插件一起使用?

4

2 回答 2

3

正如 Holly 建议的那样,bnd 通常会从调用它的包中的任何字节码中找到这个包。如果 Spring-DM XML 文件位于正确的位置,它还应该自省它们。但是我不知道它是否还以相同的方式支持 Blueprint XML 文件,因为它们不在同一个包位置。因此可能需要升级您的 bnd 版本或使用支持蓝图的插件。

然而,我对这整件事持怀疑态度。如果没有对接口的字节码引用,那么您似乎甚至没有使用服务引用?在这种情况下,为什么不直接删除它呢?

于 2012-01-25T16:16:44.137 回答
1

正如@Neil Bartlett 所指出的,Bnd 应该在包(META-INF/springOSGI-INF/blueprint)内的标准位置内省 Spring 和 Blueprint 文件。我已经在我的 POM 中META-INF/spring/*.xml手动覆盖了这些。OSGI-INF/blueprint/*.xml我认为这很好,因为我的 OSGI 平台中的 Spring 和 Blueprint 扩展程序接受了标头并引导了各自的容器。然而,Bnd 似乎期望一个没有 glob 的更简单的标头(请参阅 参考资料SpringXMLType.java)。我并不是要指派错误,因为它是一个了不起的工具,但是这个让我措手不及。

无论如何,由于我的 Spring 和 Blueprint 标记已经在标准位置,我刚刚从我的 POM 中删除了多余的 Bnd 指令,并且所有 Spring-DM 服务参考接口都被自动拾取并Import-Package“放入我的包中”:

<plugin>
    <groupId>org.apache.felix</groupId>
    <artifactId>maven-bundle-plugin</artifactId>
    <version>2.3.6</version>
    <extensions>true</extensions>
    <configuration>
        <instructions>
            <Bundle-Version>${project.version}.${buildNumber}</Bundle-Version>
            <Bundle-Activator>com.example.BundleActivator</Bundle-Activator>
            <!-- 
                <Spring-Context>META-INF/spring/*.xml</Spring-Context> 
                <Bundle-Blueprint>OSGI-INF/blueprint*.xml</Bundle-Blueprint> 
            -->
        </instructions>
    </configuration>
</plugin>
于 2012-01-25T22:36:21.507 回答