【问题标题】:@PropertySource in a Jar for an external file on the classpathJar 中的 @PropertySource 用于类路径上的外部文件
【发布时间】:2015-07-16 17:43:28
【问题描述】:

我正在尝试在 Jar 中使用 Spring 框架的 @PropertySource 注释从 jar 外部加载属性文件,但找不到该文件。

我需要将属性文件放在 Jar 的外部,以便可以对其进行编辑。我不知道文件的确切位置,我想我可以将它放在类路径中的任何位置。

我在 Config 类上使用了以下注释。

@PropertySource('classpath:stc.properties')

并把stc.properties与创建的Jar文件放在同一目录下。我尝试在java 命令中明确指定类路径,但仍然找不到文件:

java -cp . -jar stc.jar
Exception in thread "main" org.springframework.beans.factory.BeanDefinitionStoreException: Failed to load bean class: com.example.stc.Config; nested exception is java.io.FileNotFoundException: class path resource [stc.properties] cannot be opened because it does not exist
        at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:162)
        at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:299)
        at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:243)
        at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:254)
        at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:94)
        at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:609)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
[...]

等等

我也尝试使用 ./ 作为类路径,并尝试在 jar 清单的 Class-Path 属性中指定类路径(具有两个变体),但它总是给出相同的结果。

【问题讨论】:

    标签: java spring jar classpath properties-file


    【解决方案1】:

    假设你有两个文件,一个用于本地,一个用于生产

    @PropertySources({
            @PropertySource("classpath:application.properties"),
            @PropertySource(value = "${ws.properties}", ignoreResourceNotFound = true)
    
    })
    

    在tomcat或者你的jar文件中,传递这个参数

    -Dws.properties=file:/path-to.properties
    

    我在 setenv.sh 中添加了这个

    APPLICATION_OPTS="-Dlog4j.configurationFile=file:$PATH/log4j2.xml -Dlog4j.debug=true -Dapplication.properties=file:$PATH/application.properties

    这仅适用于 Spring 4

    【讨论】:

    • 我在tomcat中添加这个“-Dws.properties=file:/path-to.properties”
    • 我在 setenv.sh 中添加了。更新了我的答案
    【解决方案2】:

    使用变量(系统或环境)来获取文件的值,您可以像这样引用您的文件:

    @PropertySource("file:${MY_PATH}/application.properties")
    

    【讨论】:

      【解决方案3】:

      我的环境是:

      操作系统:Windows |容器:Tomcat |爪哇:7 |春天:4.2.4 | Springboot 1.3.1 | Maven

      步骤 1 a(战争)

      将文件外部化属性文件添加到 JVM 系统属性。

      正如我在 Tomcat 上运行的那样;我通过在<TOMCAT_HOME>/bin/setenv.bat 中创建 setenv.bat 来做到这一点

      set CATALINA_OPTS=%CATALINA_OPTS% -Dexternal.app.properties=file:<PATH_TO_EXTERNAL_FILE>\application-prod.properties
      

      步骤 1 b(罐子)

      如果您从 jar 中运行,则可以使用:

      -Dexternal.app.properties=file:&lt;PATH_TO_EXTERNAL_FILE&gt;\application-prod.properties

      注意file:在开头的使用就行了。

      第二步:在我的应用启动类中,我使用注解@PropertySource来加载具体环境的应用属性。

      @SpringBootApplication
      @PropertySources({
              @PropertySource(value = "${external.app.properties.file}", ignoreResourceNotFound = true),
              @PropertySource(value = "classpath:application.properties")
      })
      public class Application extends SpringBootServletInitializer {
      
          public static void main(String[] args) {
              SpringApplication.run(Application.class, args);
          }
      
          @Override
          protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
              return application.sources(Application.class);
          }
      
      }
      

      第 3 步

      在项目中使用外部属性

      external/file/path/application-prod.properties

      spring.datasource.url.ext=

      /src/main/resources/application.properties

      spring.datasource.url=${spring.datasource.url.ext}

      希望这可以帮助其他遇到同样问题的人。

      【讨论】:

        【解决方案4】:

        尝试给出文件的完整路径:

        @PropertySource('file:c:/.../stc.properties')
        

        【讨论】:

        • 那行得通,但它不能解决我的问题。正如我所提到的,我不知道文件的位置。
        • 怎么样:@PropertySource('file:/../stc.properties')
        • 这仍然假设文件位于相对于 jar 的特定位置。
        • 这个想法实际上帮助了我,我使用了@PropertySource 的两个实例,第一个使用类路径:第二个使用 file: 格式并指向,例如:file:./stc.properties .它非常适合我查看类路径中的属性文件以及 jar 的相同路径。
        【解决方案5】:

        您可以在运行 jar 时使用 --spring.config.location=file:/somepath 参数,在其中指定配置文件的路径(可以是相对的)。

        更多信息in docs

        【讨论】:

          【解决方案6】:

          假设您有一个 jar,其类路径中有一个默认的 main 和一些默认的 stc.properties

          如果在 jar 旁边(实际上在执行目录中)有一个具有该名称的配置文件,则可以选择在该配置中设置的属性与默认配置的属性合并。

          如果用户决定不使用外部配置,则不会发生错误。

          对于上述场景你需要:

          @PropertySources({
                  @PropertySource("classpath:stc.properties"),
                  @PropertySource(value = "file:./stc.properties", ignoreResourceNotFound = true)
          
          })
          

          例如假设默认的stc.properties(在罐子里)内容是:

          propA=valueA
          propB=valueB
          

          现在,如果我在 jar 旁边添加一个同名文件,其中包含:

          propB=updatedValueB
          propC=valueC
          

          执行java -jar stc.jar时有效加载的属性有:

          propA=valueA
          propB=updatedValueB
          propC=valueC
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-03-30
            • 2014-12-16
            • 2011-08-22
            • 2013-02-27
            • 1970-01-01
            • 1970-01-01
            • 2013-08-27
            • 1970-01-01
            相关资源
            最近更新 更多