OSGi bundle访问来自另一个bundle的Spring上下文文件

时间:2011-07-19 15:01:35

标签: java spring osgi apache-karaf apache-servicemix

我有一个存在为多个Spring项目的现有应用程序。项目A的Spring上下文XML文件使用

来存储B的Spring上下文XML文件
<import resource="classpath*:/META-INF/spring/BContext.xml" />

然而,我得到FileNotFoundException。我认为这是由于项目B的捆绑没有公开资源这一事实。我可以访问类,但不能访问文件。

在研究这个问题时,常见的评论是使用OSGi服务并注入服务而不是尝试直接注入bean。但是,由于这是一个现有的应用程序,我想避免重新布线。

有没有办法告诉OSGi导出资源?我在Karaf上运行ServiceMix。

3 个答案:

答案 0 :(得分:3)

它只是一个类路径资源,所以我假设添加一个适当的Export-Package指令就可以了。但这绝对不是正确的做法。该上下文文件的路径表明,包含BContext.xml的项目可能已设置为与Spring Dynamic Modules一起使用。如果是这样,那么当您启动该捆绑包时,Spring ApplicationContext将作为服务导出。在OSGi控制台中查找它。

修改:回应评论中的讨论:

我自己从未尝试过这个,但理论上应该可以使用Spring DM的osgi namespace来创建一个bean reference to the OSGi service,这是项目B的ApplicationContext。然后,使用作为ApplicationContext的bean,您可以使用normal Spring configuration使用one of the getBean()方法从中提取bean。请注意,您可以使用<constructor-arg ... />在Spring配置中指定工厂方法的参数,如toward the bottom of this examples section所示。

答案 1 :(得分:3)

从另一个模块加载Spring Context和所有实现类是对模块封装的巨大违反。如果你愿意这样做,那么A和B根本就没有任何意义,你也可以将它们作为一个单独的捆绑包。

答案 2 :(得分:3)

您应该这样做的方法是使用OSGi服务。您可以使用以下命令在Spring DM中注册服务(通常在单独的osgi-context.xml文件中完成,以确保代码库不依赖于OSGi进行测试。在此示例中,您将拥有一个bean在BContext.xml中定义的id诊所,它被引用为OSGi服务

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/osgi"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xsi:schemaLocation="http://www.springframework.org/schema/osgi  
        http://www.springframework.org/schema/osgi/spring-osgi.xsd
        http://www.springframework.org/schema/beans   
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <service id="osgiClinic" ref="clinic" interface="org.springframework.petclinic.repository.Clinic" />

</beans:beans>

然后在使用bundle的osgi-context.xml中,您将引用该服务。在下面的示例中,您现在有一个名为clinic的bean,它利用第一个bean的代码。

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/osgi"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xsi:schemaLocation="http://www.springframework.org/schema/osgi  
        http://www.springframework.org/schema/osgi/spring-osgi.xsd
        http://www.springframework.org/schema/beans   
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <reference id="clinic" interface="org.springframework.petclinic.repository.Clinic"/>

</beans:beans>

这种做法将确保您考虑捆绑包之间的依赖关系,并仅导出其他捆绑包所必需的服务。