1

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

<import resource="classpath*:/META-INF/spring/BContext.xml" />

但是,我得到一个FileNotFoundException. 我认为这是由于项目 B 的捆绑包未公开资源这一事实造成的。我可以访问类,但不能访问文件。

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

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

4

3 回答 3

3

您应该这样做的方式是利用 OSGi 服务。您可以使用以下内容在 Spring DM 中注册服务(通常在单独的 osgi-context.xml 文件中完成,以确保代码库不依赖于 OSGi 以进行测试。在此示例中,您将拥有一个带有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>

然后在消费包的 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>

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

于 2011-07-20T15:25:43.683 回答
3

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

于 2011-07-20T12:58:34.863 回答
3

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

编辑:回应评论中的讨论:

我自己从未尝试过,但理论上应该可以使用 Spring DM 的osgi 命名空间来对作为项目 B 的 ApplicationContext的 OSGi 服务进行 bean 引用。然后,拥有一个作为 ApplicationContext 的 bean,您可以使用普通Spring 配置使用getBean()方法之一 从中提取 bean 。请注意,您可以使用在 Spring 配置中为工厂方法指定参数,如本示例部分底部所示。 <constructor-arg ... />

于 2011-07-19T20:06:59.943 回答