依赖注入:如何维护多个配置?

时间:2009-11-10 13:01:43

标签: java spring dependency-injection inversion-of-control

让我们假设我们已经构建了一个带有DI框架的系统,该框架工作得非常好。该系统目前使用JMS与我们未维护的其他系统“对话”。我们的大多数客户都喜欢JMS方法,并根据我们的规范使用它。执行所有消息传递的组件将Spring注入到应用程序的其余部分。

现在我们得到了一个客户无法实现JMS解决方案并希望使用其他消息传递技术的情况。这不是问题,因为我们可以使用这种技术简单地实现消息传递服务,并将其注入应用程序的其余部分。

但是我们应该如何处理配置的部署和维护?由于应用程序使用Spring,我可以想象检查我对此应用程序的所有配置,系统管理员可以启动应用程序并传递DI XML文件的名称以指定应加载哪个配置。但是......它感觉不对劲。是否有针对此类案例的解决方案?您使用的最佳做法是什么?我甚至可以想象更复杂的场景,它们不仅包含一个服务替换......

非常感谢!

4 个答案:

答案 0 :(得分:4)

另一个建议是:如何将spring配置分为两部分:一个发送给每个人的公共文件,以及一个包含不同bean定义的特定于部署的文件。所以你可以:

applicationCommon.xml
deploymentJMS.xml
deploymentOtherMessaging.xml
deploymentDifferentAgainMessaging.xml

然后,当您的系统管理员部署时,他们会选择部署???。xml文件的一个,具体取决于方案并将其放入配置目录

您的应用程序将配置为使用通配符表达式加载applicationCommon.xml文件和config目录中的任何其他xml文件,将它们一起使用以构建应用程序上下文(无需专门关注它们是哪些实际文件)。

不同的部署XML文件将存在于源代码控制中,并且sys管理员除了知道他们总是部署适合该场景的命名部署???。xml文件之外,不需要任何详细的知识。

(如果是一个Web应用程序,您可能希望将“config”目录与Web应用程序本身分开,以便重新部署应用程序不会覆盖特定于部署的配置)

当然,这个部署都可以编写脚本,以便通过命令行参数选择正确的文件,例如......

答案 1 :(得分:3)

一种解决方案是在Spring配置中使用PropertyOverrideConfigurer。这允许您提供单独的属性文件,该文件可以在启动应用程序上下文时覆盖Spring配置中的值。这样,您就可以在applicationContext.xml中使用标准配置(将其发送给所有人),以及一个附加的属性文件,允许您在不改变主配置文件的情况下基于每个部署自定义配置。

<bean class="org.springframework.beans.factory.config.PropertyOverrideConfigurer">
  <property name="location"><value>file:${config.dir}/config.properties</value></property>   
</bean>

答案 2 :(得分:1)

我们的产品具有相同的用例。

我们为每组配置创建了不同的applicationContext文件集。我们的上下文文件已经分为四个不同的文件(-servlet.xml-services.xml-dao.xml等),并且同一“配置套件”中的每个文件在其文件名中共享相同的前缀

在本产品中,我们使用Ant来构建部署文件(.war)。我们设置了build.xml,因此我们可以将不同的参数传递给构建脚本,以控制打包文件时使用的前缀。例如,我们运行

ant dist -DtargetApp=app1

打包使用app1-dao.xmlapp1-services.xml等构建的部署文件。

在Ant中,我们有类似于这样的逻辑来设置用于“配置套件”名称的属性:

<target name="set-environment">
    <!-- If the targetApp property is not set, default to "app1" -->
    <condition property="targetApp" value="app1">
        <not>
            <isset property="targetApp"/>
        </not>
    </condition>
    <echo>Using targetApp: ${targetApp}</echo>
<target>

由于此产品是Web应用程序,因此${targetApp}属性的值将用于过滤web.xml中的值,以告知Spring要加载哪些应用程序上下文文件。

答案 3 :(得分:0)

我认为,您可以选择发布不同版本的产品,也可以使用支持这两种邮件系统的产品。

我倾向于单品。如果您不希望客户管理员设置定义消息传递系统的参数,那么您可以提供客户特定的配置文件或将该信息附加到许可证文件(如果有),以便您可以确保客户使用正确的版本。

只有当邮件系统依赖于非免费的第三方库时,我才会构建不同的产品,以防止出现许可问题。

相关问题