OSGi 包从另一个包访问 Spring 上下文文件
我有一个作为多个 Spring 项目存在的现有应用程序。项目 A 的 Spring 上下文 XML 文件使用以下命令导入 B 的 Spring 上下文 XML 文件
<import resource="classpath*:/META-INF/spring/BContext.xml" />
,但是,我得到了 FileNotFoundException
。我认为这是由于项目 B 的捆绑包未公开该资源造成的。我可以访问类,但不能访问文件。
在研究这个问题时,常见的评论是使用 OSGi 服务并注入服务,而不是尝试直接注入 Bean。但是,由于这是一个现有的应用程序,我想避免重新连接整个应用程序。
有没有办法告诉OSGi导出资源?我在 Karaf 上运行 ServiceMix。
I have an existing application that exists as multiple Spring projects. Project A's Spring context XML file improts B's Spring context XML file using
<import resource="classpath*:/META-INF/spring/BContext.xml" />
However, it I get a FileNotFoundException
. I assume this is caused by the fact that the resource is not exposed by project B's bundle. I can access the classes, but not the file.
When researching this issue the common comment was to use OSGi services and inject the services instead of trying to inject the beans directly. However, since this is an existing application, I would like to avoid rewiring the entire thing.
Is there any way to tell OSGi to export the resource? I'm running ServiceMix on Karaf.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
它只是一个类路径资源,所以我假设添加适当的
Export-Package
指令就可以解决问题。但这绝对不是正确的方法。该上下文文件的路径表明包含 BContext.xml 的项目可能已经设置为与 Spring 动态模块一起使用。如果是这样,那么当您启动该包时,Spring ApplicationContext 将作为服务导出。在您的 OSGi 控制台中查找它。编辑:回应评论中的讨论:
我自己从未尝试过,但理论上应该可以使用Spring DM的osgi 命名空间 来创建一个 对 OSGi 服务的 bean 引用< /a> 这是项目 B 的 ApplicationContext。然后,拥有一个 ApplicationContext 的 bean,您可以使用 普通 Spring 配置 使用 一个 getBean() 方法。请注意,您可以使用
在 Spring 配置中指定工厂方法的参数,如下所示 在此示例部分的底部。It's just a classpath resource, so I would assume adding an appropriate
Export-Package
directive would do the trick. That's definitely not the right way to do it, though. The path of that context file suggests that perhaps the project that contains BContext.xml is already set up to work with Spring Dynamic Modules. If so, then when you start that bundle, the Spring ApplicationContext is exported as a service. Look for it in your OSGi console.Edit: In response to discussion in the comments:
I've never tried this myself, but theoretically it should be possible to use Spring DM's osgi namespace to make a bean reference to the OSGi service which is project B's ApplicationContext. Then, having a bean which is the ApplicationContext, you can use normal Spring configuration to extract beans from it using one of the getBean() methods. Note that you can use
<constructor-arg ... />
to specify arguments to a factory method in a Spring config, as shown toward the bottom of this examples section.从另一个模块加载 Spring Context 和所有实现类是对模块封装的巨大违反。如果您愿意这样做,那么将 A 和 B 作为单独的捆绑包确实毫无意义,您还不如将它们作为一个捆绑包。
Loading the Spring Context and all of the implementation classes from another module is a huge violation of module encapsulation. If you are willing to do that, then it really makes no sense for A and B to be separate bundles at all, and you might as well make them a single bundle.
您应该执行此操作的方法是利用 OSGi 服务。您可以使用以下命令在 Spring DM 中注册服务(通常在单独的 osgi-context.xml 文件中完成,以确保代码库不依赖于 OSGi 进行测试。在此示例中,您将拥有一个带有BContext.xml 中定义的 id Clinic,它被引用为 OSGi 服务
然后在消费包的 osgi-context.xml 中,您将引用该服务。在下面的示例中,您现在有一个名为 Clinic 的 bean。利用第一个 bean 中的代码,
这种做法将确保您考虑捆绑包之间的依赖关系,并且仅导出其他捆绑包所需的服务。
The way you should do this is to utilize OSGi Services. You can register a service in Spring DM with the following (which is usually done in a seperate osgi-context.xml file to ensure that the code base is not dependent on OSGi for testing purposes. In this example, you would have a bean with the id clinic defined in BContext.xml, and which is referenced as an OSGi service
Then in the consuming bundle's osgi-context.xml, you would reference the service. In the example below, you now have a bean called clinic that utilizes the code from the first bean.
This way of doing things will make sure you think about the dependencies between your bundles and only export those services that are necessary for other bundles.