Spring Boot如何读取jar外的属性文件

Posted

技术标签:

【中文标题】Spring Boot如何读取jar外的属性文件【英文标题】:Spring boot how to read properties file outside jar 【发布时间】:2017-06-04 21:35:49 【问题描述】:

在我的目标文件夹中,有 2 个文件夹,lib 和 conf。所有的properties文件都放在conf文件夹中,jars放在libfolder中。

在spring boot之前,我们在spring.xml中使用如下配置来使用@value

<context:property-placeholder location="classpath*:*.properties"/>

在java代码中:

@Value("$name")

private String name;

但是在 spring boot 中,我不知道如何在 java 代码中做同样的事情。

我试过了,但没用

@Configuration
@PropertySource(value = "classpath:aaa.properties")
public class AppConfig 
    @Bean
    public PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() 
    return new PropertySourcesPlaceholderConfigurer();
    

【问题讨论】:

【参考方案1】:

找到解决方案:

首先创建一个类并添加@ConfigurationProperties

@ConfigurationProperties(prefix = "asdf", locations = "file:conf/aaa.properties")
public class ASDF 
    private String name;   

    public String getName() 
        return name;
    

    public void setName(String name) 
        this.name = name;
    

请注意位置,我使用文件,而不是类路径。

然后在您的应用程序类中,添加@EnableConfigurationProperties

@SpringBootApplication
@EnableConfigurationProperties(ASDF.class, BBB.class)
public class InitialBeanTestApplication 

    public static void main(String[] args) 
        SpringApplication.run(InitialBeanTestApplication.class, args);
    

然后你可以读取conf文件夹中的配置文件

【讨论】:

@ConfigurationProperties(prefix = "asdf", locations = "file:conf/aaa.properties") 中的位置可以在 application-profile.yml 文件中定义。并更改为位置 =“$configFilePath”。而对于dev,它的值可以是classpath:*.properties,对于prod,它的值可以是file:*.properties。【参考方案2】:

我对问题的标题和描述有点困惑。希望我不会再把你和我的 cmets 搞混了。

总的来说,Spring Boot 对项目结构以及创建的二进制文件非常有意见。推荐的方法(Spring Boot 意见)是构建一个包含所有依赖项的 jar(fat jar)。如果您需要在 fat jar 之外定义的配置属性(或者如果您构建的是 war),Spring Boot 提供了许多选项(请参阅参考资料 1)。我喜欢我的应用程序使用可以使用系统属性设置的标志 (spring.config.location) 指向外部文件:

java -jar -Dspring.config.location=<path-to-file> myBootProject.jar

请注意,您可以通过使用环境变量来定义外部文件所在的位置来执行类似的操作。

我希望这会有所帮助!

参考资料: 1.https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

【讨论】:

谢谢,此优惠物超所值 你知道我是否有多个属性文件,如何在单独的配置类中读取它? 你指的是多个外部文件吗? 是的,比如一个用于db设置的文件,一个用于redis设置的文件,一个用于其他设置的文件。我们想拆分不同的设置。 你能展示如何使用环境变量来定义配置位置吗?【参考方案3】:

找到另一个解决方案。

将每个配置放在一个application.properties文件中,并在代码中使用@Value("$name") 来读取。

并使用汇编文件将资源文件夹的文件复制到目标配置文件夹中。

部署后,只需要更改config文件夹中的application.properties文件并运行应用程序。

这是因为 spring boot 按以下顺序读取 application.properties 文件。

• 位于当前目录中的 /config 子目录

• 当前目录

• 类路径 /config 包

• 类路径根

但这适用于一个属性文件。不适用于多重属性文件

【讨论】:

【参考方案4】:

我不确定您是否遇到与我相同的情况,但在我的情况下,我有一个 jar 和一个 *.properties 文件。我为获得位于 jar 外部的 *.properties 文件所做的工作是下一个:

@Configuration
public class ApplicationContext 

  @Bean
  public PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() 
    PropertySourcesPlaceholderConfigurer properties = new PropertySourcesPlaceholderConfigurer();
    properties.setLocation(new FileSystemResource("application.properties"));
    properties.setIgnoreResourceNotFound(false);

    return properties;
  

当我设置 application.properties 文件的位置时,我创建了 FileSystemResource 对象,它允许我获取位于 jar 旁边的 properties.files。例如,如果您的 .properties 文件位于类路径中,您可以使用其他类(如 ClassPathResource)。您可以阅读 spring 提供的其他类来获取包 org.springframework.core.io 下的 Resource 对象。

我希望这个 cmets 有所帮助。

【讨论】:

这似乎是一个更通用的解决方案。如果您想使用setLocations 方法设置多个位置。【参考方案5】:

正如Spring Boot docs中提到的,

SpringApplication 将从application.properties 加载属性 在以下位置创建文件并将它们添加到 Spring 环境:

    当前目录的 /config 子目录。 当前目录 类路径 /config 包 类路径根

列表按优先级排序(在位置定义的属性 列表中较高的位置会覆盖较低位置中定义的那些)。

一种方法是将您的“conf”目录简单地重命名为“config”,它会毫无问题地工作。因此,除非您希望您的属性文件位于上述 4 之外的某个位置,否则无需进行额外配置。

在这种情况下,您可以显式定义属性源。

@PropertySource("classpath:config.properties")

对于多个属性文件

@PropertySources(
    @PropertySource("classpath:config.properties"),
    @PropertySource("classpath:logging.properties"),
    @PropertySource(value="classpath:missing.properties", ignoreResourceNotFound=true)
)

【讨论】:

【参考方案6】:

其实最简单的办法就是把application.propertiesyour.jar放到同一个目录下,只有java -jar your.jar会自动加载这个外部配置文件。

如果你试图通过ClassPathResource从资源文件夹加载一些上下文/文件,当你读取文件时不要使用pathResource.getFile(),而是使用pathResource.getInputStream()getFile()在你的IDE中运行良好,但是它不适用于独立的jar

【讨论】:

以上是关于Spring Boot如何读取jar外的属性文件的主要内容,如果未能解决你的问题,请参考以下文章

java 如何读取jar包外的properties文件(转)

读取 JAR 文件外的属性文件

Spring boot 如何读取jar包外面的properties文件

Spring Boot Learning(配置文件)

无法从 Spring Boot 中的外部属性文件中读取值

Spring Boot参考教程Spring Boot Jar方式读取资源文件