Jar 中的 @PropertySource 用于类路径上的外部文件
Posted
技术标签:
【中文标题】Jar 中的 @PropertySource 用于类路径上的外部文件【英文标题】:@PropertySource in a Jar for an external file on the classpath 【发布时间】: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
属性中指定类路径(具有两个变体),但它总是给出相同的结果。
【问题讨论】:
【参考方案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:<PATH_TO_EXTERNAL_FILE>\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
【讨论】:
以上是关于Jar 中的 @PropertySource 用于类路径上的外部文件的主要内容,如果未能解决你的问题,请参考以下文章
spring @value和@@PropertySource注解简单使用