简体   繁体   English

如何使用Spring Boot加载外部配置?

[英]How to load an external configuration with Spring Boot?

I'm currently learning how to work with Spring Boot. 我目前正在学习如何使用Spring Boot。 Until now I never used Frameworks like Spring and used files directly (FileInputStream, etc.) 到目前为止,我从未使用像Spring这样的框架并直接使用文件(FileInputStream等)

So here is the case: I have some dynamic configuration values like OAuth tokens. 所以情况就是这样:我有一些动态配置值,比如OAuth令牌。 I want to use them inside of my application but I have no clue how to realize this with Spring. 我想在我的应用程序中使用它们,但我不知道如何用Spring实现这一点。

Here is some code to make clear what I'm searching for: 这是一些代码,以明确我正在搜索的内容:

@Config("app.yaml")
public class Test {
    @Value("app.token")
    private String token;
    private IClient client;

    public Test(String token) {
        this.client = ClientFactory.build(token).login();
    }
}

Sure, this example is very plain. 当然,这个例子很简单。 Here I want to get the value "token" dynamically from a YAML configuration file. 在这里,我想从YAML配置文件中动态获取值“token”。 This file must be accessible for the user and not included in the JAR file. 该文件必须可供用户访问且不包含在JAR文件中。

I also found that doc: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html but I have now idea how to apply this to my project. 我还发现doc: https//docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html但我现在知道如何将它应用到我的项目中。

How can I achive this? 我怎么能得到这个? Thank you in advance :) 先感谢您 :)

Edit: 编辑:

Here are some parts of my code: 以下是我的代码的一些部分:

WatchdogBootstrap.java WatchdogBootstrap.java

package de.onkelmorph.watchdog;

import org.springframework.boot.Banner.Mode;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ImportResource;

@SpringBootApplication
@ImportResource("classpath:Beans.xml")
public class WatchdogBootstrap {
    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(WatchdogBeans.class);
        app.setBannerMode(Mode.OFF);
        app.setWebEnvironment(false);
        app.run(args);
    }
}

Beans.xml (Located in default package) Beans.xml (位于默认包中)

<?xml version = "1.0" encoding = "UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <context:annotation-config></context:annotation-config>
</beans>

Watchdog.java Watchdog.java

package de.onkelmorph.watchdog;

// Imports ...

@Component
@PropertySource("file:/watchdog.yml")
public class Watchdog {
    // ...

    // Configuration
    @Value("${watchdog.token}")
    private String token;

    public Watchdog() {
        System.out.println(this.token);
        System.exit(0);
    }

    // ...
}

watchdog.yml (Located in src/main/resources) watchdog.yml (位于src / main / resources)

watchdog:
  token: fghaepoghaporghaerg

First of all your Test class should be annotated with @Component in order for it to be registered as a bean by spring (also make sure all your classes are under your main package - the main package is where a class that is annotated with @SpringBootApplication reside). 首先,你的Test类应该用@Component注释,以便它在春天之前注册为bean(同时确保你的所有类都在你的主包下 - 主包是用@SpringBootApplication注释的类的@SpringBootApplication居住)。

Now you should either move all your properties to application.yml ( src/main/resources/application.yml ), that is picked automatically by spring boot (note that it should be .yml instead of .yaml or register a custom PropertySourcesPlaceholderConfigurer . 现在你应该将所有属性移动到application.ymlsrc/main/resources/application.yml ),这是由spring boot自动选取的(注意它应该是.yml而不是.yaml或注册一个自定义的PropertySourcesPlaceholderConfigurer

Example for PropertySourcesPlaceholderConfigurer : PropertySourcesPlaceholderConfigurer示例:

@Bean
public static PropertySourcesPlaceholderConfigurer PropertySourcesPlaceholderConfigurer() throws IOException {
    PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
    MutablePropertySources propertySources = new MutablePropertySources();
    Resource resource = new DefaultResourceLoader().getResource("classpath:application.yml");
    YamlPropertySourceLoader sourceLoader = new YamlPropertySourceLoader();
    PropertySource<?> yamlProperties = sourceLoader.load("yamlProperties", resource, null);
    propertySources.addFirst(yamlProperties);
    configurer.setPropertySources(propertySources);
    return configurer;
}

Now your properties should be loaded to spring's environment and they will be available for injection with @Value to your beans. 现在你的属性应该被加载到spring的环境中,并且它们可以通过@Value注入你的bean。

You basically got three easy options. 你基本上有三个简单的选择。

  1. Use application.properties which is Springs internal configuration file. 使用application.properties是Springs内部配置文件。
  2. Load your own configuration file using --spring.config.name as VM parameter. 使用--spring.config.name作为VM参数加载您自己的配置文件。
  3. You can use @PropertySource to load either an internal or external configuration. 您可以使用@PropertySource加载内部或外部配置。 @PropertySource only works with .properties config files. @PropertySource仅适用于.properties配置文件。 There is currently an open Jira ticket to implement yaml support. 目前有一个开放的Jira票证来实现yaml支持。 You can follow the progress here: https://jira.spring.io/browse/SPR-13912 您可以按照以下步骤进行操作: https//jira.spring.io/browse/SPR-13912

Notice, if you are using multiple yaml and/or properties files which contain common keys, the it will always use the definition of the key which was loaded last. 请注意,如果您使用包含公共密钥的多个yaml和/或属性文件,它将始终使用最后加载的密钥的定义。 This is why the below example uses two different keys. 这就是下面的示例使用两个不同的键的原因。 If it used the same key, then it would print out PROPERTIES FILE twice. 如果它使用相同的键,那么它将打印两次PROPERTIES FILE

Short simple code snippet: 简短的代码片段:

@Component
@PropertySource("file:/path/to/config/app.properties")
class Address{

    @Value("${addr.street}")
    private String street;

    @Value("${addr.city}")
    private String city;
}

app.properties app.properties

addr.street=Abbey Road
addr.city=London

Extensive Example 广泛的例子

DemoApplication.java DemoApplication.java

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.run(DemoApplication.class, args);

        //Call class with properties
        context.getBean(WatchdogProperties.class).test();
        //Call class with yaml
        context.getBean(WatchdogYaml.class).test();
    }

    //Define configuration file for yaml
    @Bean
    public static PropertySourcesPlaceholderConfigurer properties() {
      PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
      YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();
      yaml.setResources(new ClassPathResource("watchdog.yml"));
      propertySourcesPlaceholderConfigurer.setProperties(yaml.getObject());
      return propertySourcesPlaceholderConfigurer;
    }
}

WatchdogProperties.java WatchdogProperties.java

@Component
//PropertySource only works for .properties files
@PropertySource("classpath:watchdog.properties")
public class WatchdogProperties{
    //Notice the key name is not the same as the yaml key
    @Value("${watchdog.prop.token}")
    private String token;

    public void test(){
        System.out.println(token);
    }
}

WatchdogYaml.java WatchdogYaml.java

@Component
class WatchdogYaml{
    //Notice the key name is not the same as the properties key
    @Value("${watchdog.token}")
    private String token;

    public void test(){
        System.out.println(token);
    }
}

Properties and Yaml files Both of these files are located in src/main/resources 属性和Yaml文件这两个文件都位于src/main/resources

watchdog.yml: watchdog.yml:

watchdog:
  token: YAML FILE

watchdog.properties: watchdog.properties:

watchdog.prop.token=PROPERTIES FILE

Output 产量

PROPERTIES FILE
YAML FILE

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM