【问题标题】:Using Maven settings.xml properties inside Spring context在 Spring 上下文中使用 Maven settings.xml 属性
【发布时间】:2012-05-30 15:20:58
【问题描述】:

我的 ~/.m2 目录中有一个 Maven settings.xml 文件;它看起来像这样:

<settings>
    <profiles>
        <profile>
            <id>mike</id>
            <properties>
                <db.driver>org.postgresql.Driver</db.driver>
                <db.type>postgresql</db.type>
                <db.host>localhost</db.host>
                <db.port>5432</db.port>
                <db.url>jdbc:${db.type}://${db.host}:${db.port}/dbname</db.url>
            </properties>
        </profile>
    </profiles>
    <activeProfiles>
        <activeProfile>mike</activeProfile>
    </activeProfiles>
    <servers>
        <server>
            <id>server_id</id>
            <username>mike</username>
            <password>{some_encrypted_password}</password>
        </server>
    </servers>
</settings>

我想使用这些属性两次

  • 一旦进入 Maven 的integration-test 阶段,就可以设置和拆除我的数据库。使用 Maven 过滤,这是完美的工作。
  • 第二次运行我的 Spring 应用程序时,这意味着我需要在 Maven 的resources:resources 阶段将这些属性替换到我的servlet-context.xml 文件中。对于settings.xml 上部的属性,例如${db.url},这可以正常工作。 我不知道如何将我的数据库用户名和(解密的)密码替换到 Spring servlet-context.xml 文件中。

我的servlet-context.xml 文件的相关部分如下所示:

<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName"><value>${db.driver}</value></property>
    <property name="url"><value>${db.url}</value></property>
    <property name="username"><value>${username}</value></property>
    <property name="password"><value>${password}</value></property>
</bean>

这里的最终目标是让每个开发人员拥有自己的 Maven 设置(以及在他们自己的机器上用于集成测试的数据库)......以及 Jenkins 服务器上的类似设置。我们不想共享一个共同的用户名/密码/等等。

【问题讨论】:

    标签: spring maven


    【解决方案1】:

    我没有尝试过,但是按照这个maven wiki page,您应该可以使用settings. 前缀引用settings.xml 中的属性。所以${settings.servers.server.username} 理想情况下应该在settings.xml 中返回username

    【讨论】:

    • 这是在 Maven 的范围内,而不是在 Spring 的范围内,所以你不能在运行时访问它们,在 Spring 中。您只能将它们与过滤器选项一起使用。
    【解决方案2】:

    我建议你在中间使用一个属性文件。我的意思是:Spring 应用程序将使用 context:property-placeholder 从属性文件中加载属性值,而 Maven 将使用来自 settings.xml 的值使用过滤替换 ${...} 变量。

    您的属性文件:

    db.driver=${db.driver}
    db.url=${db.url}
    username=${username}
    password=${password}
    

    您的servlet-context.xml 文件

    <context:property-placeholder location="classpath:your-property-file.properties" />
    
    <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName"><value>${db.driver}</value></property>
        <property name="url"><value>${db.url}</value></property>
        <property name="username"><value>${username}</value></property>
        <property name="password"><value>${password}</value></property>
    </bean>
    

    在你的 pom.xml 中

    <resources>
        ...
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
        </resource>
        ...
    </resources>
    

    【讨论】:

      【解决方案3】:

      有一种方法可以通过配置 Maven War Plugin 来过滤 Web 资源。查看this 获取官方插件文档中的 sn-p。

      顺便说一句,我强烈建议重新考虑这种基于过滤的方式,以便在构建时提供事实上的运行时配置。请注意,您必须重新构建相同的代码才能为另一个环境准备包(或者编辑包内容)。您可以为此使用应用程序服务器的特定内容(至少 JBoss 有一个)或使用 AFAIR 也可以像这样配置的 Spring。

      【讨论】:

      • 关于重新编译的那一点是有效的。我肯定需要更多地研究这一点,因为这是我希望避免的反模式。绝对需要它以 CI/CD 风格运行。但与此同时,我正在尝试重新使用已经存在并存储在settings.xml 中的信息
      • 好的,你要重构它真的很好。现在,正如我所说,使用此 Web 资源过滤。正如您所说,它应该可以工作并使您能够在一个地方进行此配置。
      • Spring 3.1 为这种类型的场景引入了大量新内容:blog.springsource.org/2011/02/15/…
      猜你喜欢
      • 2012-07-02
      • 2015-07-07
      • 1970-01-01
      • 1970-01-01
      • 2021-08-19
      • 1970-01-01
      • 2020-06-05
      • 2015-01-13
      • 1970-01-01
      相关资源
      最近更新 更多