Spring Boot - 添加外部属性文件

Posted

技术标签:

【中文标题】Spring Boot - 添加外部属性文件【英文标题】:Spring Boot - add external property files 【发布时间】:2015-05-14 20:16:24 【问题描述】:

我在 SpringBoot 中有一个简单的 MVC 应用程序,使用 java-config 创建(我没有 web.xml)。 该应用程序具有基于 JPA 的数据库连接。到目前为止,一切都很好,但现在我必须将 db.properties 从 WAR 内部移动到 OS 变量(“CONFIG_LOCATION”)指定的位置。 在spring doc 中写的不多。只能说它是可能的,但我应该如何在我的 Spring 应用程序中设置它? 我想这应该在初始化程序之前完成。 然后我只看到两个选项: - SpringApplication - 在某个地方我应该从 OS 变量中插入文件位置,但我找不到它, - 一些注释,它将理解 OS 变量,并在创建 EntityManager 之前将文件从它添加到 spring 上下文。

我愿意建议我应该如何做。

【问题讨论】:

不能更同意以下观点:“spring doc 所写的内容不多” 【参考方案1】:

如果你使用spring-boot的config参数,只是在execute jar或war时指定config位置,参数--spring.config.location。

例子:

$ java -jar myproject.jar --spring.config.location=/opt/webapps/db.properties

【讨论】:

除了命令行参数,您也可以使用 SPRING_CONFIG_LOCATION 系统变量 好的,应该可以,但是如果我在某个位置有更多 (10+) 个属性文件怎么办?【参考方案2】:

好的,我找到了办法。

我创建了返回 PropertySourcesPlaceholderConfigurer 的类。 在该 PSPC 中,我获取操作系统变量,并扫描该位置中的所有文件。 扫描后,我将所有具有属性扩展名的文件添加到 PSCS 作为位置。 方法是@Bean,类是@Configuration。之后一切正常:)

imports...

@Configuration
public class AppServiceLoader 
    @Bean(name = "propLoader")
    public static PropertySourcesPlaceholderConfigurer properties() 
        PropertySourcesPlaceholderConfigurer pspc = new PropertySourcesPlaceholderConfigurer();

        String mainConfigPath = StringUtils.isNotEmpty(System.getenv("CONFIG_LOCATION"))
                ? System.getenv("CONFIG_LOCATION") : System.getProperties().getProperty("CONFIG_LOCATION");

        File configFolder = new File(mainConfigPath);

        if(configFolder.isDirectory()) 
            FilenameFilter ff = new FilenameFilter() 

                @Override
                public boolean accept(File file, String string) 
                    return string.endsWith(".properties");
                
            ;
            File[] listFiles = configFolder.listFiles(ff);
            Resource[] resources = new Resource[listFiles.length];
            for (int i = 0; i < listFiles.length; i++) 
                if(listFiles[i].isFile()) 
                    resources[i] = new FileSystemResource(listFiles[i]);
                
            
            pspc.setLocations(resources);
        

        pspc.setIgnoreUnresolvablePlaceholders(true);
        return pspc;

    

【讨论】:

【参考方案3】:

您也可以使用注解@PropertySource。比代码解决方案更清晰干净。

见:http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/annotation/PropertySource.html

例如:

@Configuration @PropertySource("classpath:/com/myco/app.properties") public class AppConfig ...

【讨论】:

我更喜欢注释方式,但请告诉我如何使用 OS 变量来做?并且对于文件夹中的所有文件,不仅仅是在注释中列出的? 您可以使用@PropertySource 和@Profile("xxxx") 定义一些类,因此只有与当前配置文件匹配的类才加载其属性文件。然后您可以选择带有操作系统变量的当前配置文件:-Dspring.profiles.active【参考方案4】:

如果您只想让 Spring 引用项目根目录下的外部属性文件。 这是一个更简单的解决方案:

@Configuration
@PropertySource("file:$user.dir/your_external_file.properties")
public class TestConfig 
  @Autowired
  Environment env;

如有必要,您可以将 $user.dir 更改为 $user.home。

【讨论】:

【参考方案5】:

正如另一个答案中提到的@PropertySource 注释是要走的路(我会添加一些细节)。在 Java 8 中,您可以将它多次应用到您的配置类中,而且顺序很重要!例如,您可以进行以下配置:

@SpringBootApplication
@PropertySource("classpath:/db.properties")
@PropertySource(ignoreResourceNotFound = true, value = "file:$MY_APP_HOME/db.properties")
@PropertySource(ignoreResourceNotFound = true, value = "file:$user.home/.myapp/db.properties")
@ComponentScan("com.myorg")
public class Application 
     // ....

这里我假设您应该有MY_APP_HOME 环境变量,并且您可能希望在用户主页中放置一些设置。但是这两个配置都是可选的,因为 ignoreResourceNotFound 设置为 true。

还要注意订单。你可能在src/main/resources/db.properties中有一些合理的开发环境设置。并将特定设置放在运行生产服务的主机操作系统中。

详情请查看javadoc 中的Resolving $... placeholders within @PropertySource resource locations 部分。

【讨论】:

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

关于Spring boot中读取属性配置文件出现中文乱码的问题

如何在 Wildfly 中将外部属性文件加载到 Spring Boot

单体Spring boot引入外部配置文件yml,properties

使用 Spring Boot 和 Docker 的外部属性文件

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

Spring Boot如何选择外部化的弹簧属性文件