java 您如何制作多模块弹簧配置?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/748377/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do you make a multi-module spring configuration?
提问by krosenvold
I have a multi-module (maven) spring build. All the modules publish some beans, and most also consume beans defined further down the dependency graph. Although most of it is annotation declared beans, almost every module also has one or two xml-declared beans.
我有一个多模块(maven)spring 版本。所有模块都发布一些 bean,并且大多数还使用在依赖关系图中进一步定义的 bean。虽然大部分是注解声明的bean,但几乎每个模块也有一两个xml声明的bean。
Although we have a half-decent solution, but I am really wondering what is the correct/optimal way to organize the xml files in this scenario? Do you use import between the modules or is there some other way ? Do you put all the xml files in one place or spread them around according to the dependency graph? How does your solution handle partial spring contexts (typical integration tests) ?
虽然我们有一个不错的解决方案,但我真的想知道在这种情况下组织 xml 文件的正确/最佳方法是什么?您是在模块之间使用导入还是有其他方式?您是将所有 xml 文件放在一个地方还是根据依赖关系图分散它们?您的解决方案如何处理部分 spring 上下文(典型的集成测试)?
I'd also like to have this organized in a way that lets me leverage my IDE's spring support optimally (IDEA and a few eclipse users).
我还希望以一种可以让我最佳地利用我的 IDE 的 spring 支持(IDEA 和一些 eclipse 用户)的方式组织它。
采纳答案by Oliver Drotbohm
We use wildcarded imports in the modules to allow other modules contribute beans to the module declaring the import:
我们在模块中使用通配符导入,以允许其他模块向声明导入的模块贡献 bean:
<import resource="classpath*:com/acme/**/*-core-support.xml" />
Modularity
模块化
Modules that want to contribute to the "host" just have to place a correctly named files in src/main/resources/com/acmein this case to be picked up automagically. If you use classpath scanning (by <context:component-scan />it will become even easier).
src/main/resources/com/acme在这种情况下,想要为“主机”做出贡献的模块只需要放置一个正确命名的文件即可自动拾取。如果您使用类路径扫描(通过<context:component-scan />它会变得更加容易)。
Another thing that helps in that regard is some small Spring extension that picks up beans of a given type and republishes them in ApplicationContextagain. By doing something like this:
在这方面有帮助的另一件事是一些小的 Spring 扩展,它选择给定类型的 bean 并再次重新发布它们ApplicationContext。通过做这样的事情:
<plugin:list id="beanList" class="com.acme.MyCoolPluginInterface" />
<bean class="com.acme.MyPluginHost">
<property name="plugins" ref="beanList" />
</bean>
In combination with the wildcarded import this will:
结合通配符导入,这将:
- Collect all beans found in the
ApplicationContextthat implementMyCoolPluginInterfaceand wrap them in a list registered asbeanListin theApplicationContext. - Allow the
MyPluginHostto reference that list.
- 收集在该
ApplicationContext工具中找到的所有 beanMyCoolPluginInterface并将它们包装在一个beanList在ApplicationContext. - 允许
MyPluginHost引用该列表。
In fact, you now can simply extend your app by adding plugin modules to the classpath (aka dependency in Maven).
事实上,您现在可以通过将插件模块添加到类路径(在 Maven 中也称为依赖项)来简单地扩展您的应用程序。
That tiny Spring extension is called Spring Plugin and published under Apache 2 licence. See http://github.com/SpringSource/spring-pluginfor more info. There's also a more advanced sample projectat Github, that shows how this works and improves modularity at GitHub. The app is sample code for my "Whoops! Where did my architecture go?" presentation which you can see the slides hereor watch a recording here.
这个小小的 Spring 扩展名为 Spring Plugin,并在 Apache 2 许可下发布。有关更多信息,请参阅http://github.com/SpringSource/spring-plugin。Github上还有一个更高级的示例项目,它展示了它是如何工作的,并在 GitHub 上改进了模块化。该应用程序是我的“哎呀!我的架构去哪儿了?”的示例代码。演示文稿,您可以在此处查看幻灯片或在此处观看录音。
Different environments
不同的环境
Usually we configure our apps to run in the target environment (using JNDI lookups and stuff). Of course you would like to use the standard PropertyPlaceholderConfigurermechanisms to externalize configuration that has to be touched by admins or will change through various environments.
通常我们将应用程序配置为在目标环境中运行(使用 JNDI 查找等)。当然,您希望使用标准PropertyPlaceholderConfigurer机制将必须由管理员触及或将通过各种环境更改的配置具体化。
For integration tests we usually have additional config files in src/main/testthat get loaded additionallyto the normal config files overridingthe critical beans that tie the configuration to the environment. E.g. if you have a datasource in your normal config file
对于集成测试,我们通常有额外的配置文件,src/main/test这些文件除了覆盖将配置与环境联系起来的关键 bean的普通配置文件之外,还被加载。例如,如果您的普通配置文件中有一个数据源
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/MyDataSource" />
you would override this in your test-context.xmlby using
你可以test-context.xml使用
<bean id="dataSource" class="...DataSource" />
<!-- config -->
</bean>
and importing that afterthe original one in the test class
并在测试类中的原始之后导入
@ConfigurationContext(locations = {"app-context.xml", "test-context.xml"})
public FooBarIntegrationtest {
// ...
}
回答by Robin
We simply create the application context from multiple XML config files based on usage.
我们只是根据使用情况从多个 XML 配置文件创建应用程序上下文。
For example, for testing without a server, the context is created by using all the config files in each service module.
例如,对于没有服务器的测试,上下文是通过使用每个服务模块中的所有配置文件创建的。
When deployed, we access the services via Spring Remoting, and thus the client uses an application context that is initialized via an XML config which defines the proxy beans that enable remoting. Meanwhile the services are confgured by the same XML files as used by the test cases, but the application context is now loaded by either the DispatcherServlet or an EJB or MDB.
部署时,我们通过 Spring Remoting 访问服务,因此客户端使用通过 XML 配置初始化的应用程序上下文,该配置定义了启用远程处理的代理 bean。同时,服务由与测试用例使用的相同的 XML 文件配置,但应用程序上下文现在由 DispatcherServlet 或 EJB 或 MDB 加载。
This setup allows us to tailor the Application Context for each scenario without having to duplicate any information in configuration files, which keeps maintenance much simpler. Also, there is no hard dependency between config files via imports, since that is handled at the layer above that actually creates the ApplicationContext.
这种设置允许我们为每个场景定制应用程序上下文,而无需复制配置文件中的任何信息,这使得维护更加简单。此外,通过导入在配置文件之间没有硬依赖关系,因为它是在实际创建 ApplicationContext 的上层处理的。
Can't comment on the IDE support since we are not using it yet.
无法评论 IDE 支持,因为我们还没有使用它。

