【问题标题】:Specifying Java path for properties file指定属性文件的 Java 路径
【发布时间】:2010-12-02 06:22:41
【问题描述】:

我有一个使用 Maven 配置的 Java Spring 项目。随着单元测试及其配置文件的数量迅速增加,我试图将测试配置集中到一个属性文件中(同一个,用于构建项目)。

单元测试位于树中(当然,相对于项目路径)

src/test/java/com (...)

这些测试的资源文件在

src/test/resources(...)

最后,资源文件应该读取的属性文件在目录中

src/main/filters

现在,我有一个 Junit 类,我在其中指定配置文件位置,如下所示:


@ContextConfiguration(locations = { "classpath:com/initrode/quartz/SyncManagerJobTest-context.xml"})

在配置文件SyncManagerJobTest-context.xml中有一行


<context:property-placeholder location="/src/main/filters/deploy.local.properties"/>

这会导致从目录中读取属性文件。我想读的是属性文件,它位于 src/main/filters 下。我尝试使用 ../../ 向上遍历目录,但这没有帮助。使用类路径:也没有成功。我可以使用带有“file:”的绝对路径,但这需要项目中的每个开发人员修改配置,这也不好。

总而言之,问题是:如何强制 src/test/resources/ 中的配置文件读取 src/main/filters 中的属性文件?

还有一个相关的额外问题:在Java环境中处理文件时,除了“file:”和“classpath:”之外,还有其他修饰符吗?

【问题讨论】:

    标签: java spring file maven-2 properties


    【解决方案1】:

    如果您将src/main/filters 指定为资源位置,Maven 会将资源移动到target/classes,并在构建过程中将类编译到同一位置。然后,您没有要处理的相对路径,因为它们具有相同的根。如果您不这样做,您的过滤器目录将不会包含在构建中。

    更新:当然您的测试代码输出到目标/测试类,所以为了简化测试,您可以指定在过程测试资源阶段将src/main/filters 复制到target/test-classes。我已修改示例以显示该行为。

    如果您还没有这样做,您可以使用build-helper-maven-plugin 将过滤器文件夹添加为资源位置。

    这样做的配置如下所示:

    <plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>build-helper-maven-plugin</artifactId>
      <version>1.3</version>
      <executions>
        <execution>
          <id>add-resource</id>
          <phase>process-test-sources</phase>
          <goals>
            <goal>add-test-resource</goal>
          </goals>
          <configuration>
            <resources>
              <resource>
                <directory>scr/main/filters</directory>
              </resource>
            </resources>
          </configuration>
        </execution> 
      </executions>
    </plugin>
    

    【讨论】:

      【解决方案2】:

      对我来说,如果您不打算将此文件用作...过滤器,那么将属性文件放在src/main/filters 中听起来有点奇怪。如果这个文件作为标准测试资源,为什么不放在src/test/resources呢?如果你想过滤一些资源文件,为什么不直接使用过滤后的资源呢?我希望看到类似的东西:

      <build>
        <!-- Filter resources -->
        <filters>
          <filter>src/main/filters/my-filter.properties</filter>
        </filters>
        <!-- Resources for src/main -->
        <resources>
          <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
          </resource> 
        </resources>
        <!-- Resources for src/test -->
        <testResources>
          <testResource>
            <directory>src/test/resources</directory>
            <filtering>true</filtering>
          </testResource>
        </testResources>
      </build> 
      

      我可能遗漏了一些东西,但我认为你混淆了一些概念。在您的情况下(如果我正确理解您要做什么),我会使用 Maven 配置文件和过滤器来管理多个环境部署。看看:

      【讨论】:

      • properties 文件的位置可能不是最好的,但由于我正在处理现有项目,所以我将保留它。我们为不同的生产环境提供了三个不同的属性.开发应用时,需要配置的属性很多,db、ldap等。拥有两个资源位置意味着必须维护两个属性文件,我认为这并不理想。感谢您的链接,我会检查它们。
      • 我不确定您所说的“拥有两个资源位置”是什么意思,无论如何这不是必需的。但是,如果你有不同的生产环境,你不是必须为每个环境管理不同的吗?这就是链接的意义(以一种行家的方式)。
      • @Pascal 这是一个很好的观点(+1),但从问题的其他部分来看,我认为 OP 可能并不意味着 Maven 意义上的过滤器。所以这些文件可能应该放在 src/main/resources 中。在使用现有项目结构时,尽管这可能是不可能的,因此我的解决方法
      • @Rich 我认为你是对的。我只是想指出行家的方式,以防万一。
      【解决方案3】:

      Spring 允许我们单独指定测试资源的位置,以便它们仅在测试阶段被占用。通过使用@TestPropertySource("/test.properties") 注解,您可以指定要加载的测试属性文件进行测试。

      @TestPropertySource 是一个类级别的注解,您可以使用它来配置属性文件和内联属性的位置,这些属性将被添加到 Environment 中的 PropertySource 集合中,以便为集成加载的 ApplicationContext测试。

      您可以在单独的配置类中指定此注解,可以指定仅在测试期间扫描。示例:

      @Component
      public class ClassUsingProperty {
      
      @Value("${testpropertysource.one}")
      private String propertyOne;
      
      public String retrievePropertyOne() {
          return propertyOne;
       }
      }
      
      @RunWith(SpringRunner.class)
      @ContextConfiguration(classes = ClassUsingProperty.class)
      @TestPropertySource
      public class DefaultTest {
      
      
      @Autowired
      ClassUsingProperty classUsingProperty;
      
      @Test
      public void givenDefaultTPS_whenVariableRetrieved_thenDefaultFileReturned() {
          String output = classUsingProperty.retrievePropertyOne();
      
          assertThat(output).isEqualTo("default-value");
          }
       }
      

      此外,我们可以更改默认配置文件位置,或添加具有更高优先级的额外属性:

      @TestPropertySource(locations = "/other-location.properties",
        properties = "baeldung.testpropertysource.one=other-property-value")
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-10-05
        • 2011-07-09
        • 2012-03-11
        • 1970-01-01
        • 1970-01-01
        • 2018-08-06
        • 1970-01-01
        相关资源
        最近更新 更多