How do I load external config using Spring Boot?

I am currently learning how to work with Spring Boot. Until now I have never used Frameworks like Spring and used files directly (FileInputStream, etc.)

So like this: I have some dynamic config values ​​like OAuth tokens. I want to use them inside my application, but I don't know how to implement this with Spring.

Here are some codes to clearly define what I am looking 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();
    }
}

      

Of course, this example is very simple. Here I want to dynamically get the "token" value from the YAML config file. This file must be user accessible and not included in the JAR file.

I also found that doc: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html , but now I have an idea how to apply this to to my project.

How can I achieve this? Thank you in advance:)

Edit:

Here are some parts of my code:

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 (found in the default package)

<?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

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:
  token: fghaepoghaporghaerg

      

+3


source to share


2 answers


First of all, your class Test

must be annotated with @Component

so that it is registered as a bean on spring (also make sure all your classes are under your main package - the main package is where the class annotated with @SpringBootApplication

is located).

Now you have to either move all your properties to application.yml

( src/main/resources/application.yml

), which is automatically selected on spring boot (note that this should be .yml

instead .yaml

), or register a custom one PropertySourcesPlaceholderConfigurer

.

Example for 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;
}

      

Your properties should now be loaded into the spring environment and they will be available for insertion from @Value

to your beans.

+4


source


Basically, you have three simple options.

  • Use application.properties

    that is Springs internal config file.
  • Load your own config file using --spring.config.name

    VM as parameter.
  • You can use @PropertySource

    to load internal or external configuration. @PropertySource

    only works with config files .properties. There is currently a Jira open ticket to implement yaml support. You can follow the progress here: https://jira.spring.io/browse/SPR-13912

Note that if you use multiple yaml files and / or properties that contain shared keys, it will always use the definition of the key that was last loaded. This is why the example below uses two different keys. If he used the same key, he printed twice PROPERTIES FILE

.

A short, simple piece of code:

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

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

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

      

app.properties

addr.street=Abbey Road
addr.city=London

      

An extensive example

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



@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

@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);
    }
}

      

Yaml properties and files Both of these files are located insrc/main/resources

watchdog.yml:

watchdog:
  token: YAML FILE

      

watchdog.properties:

watchdog.prop.token=PROPERTIES FILE

      

Output

PROPERTIES FILE
YAML FILE

      

+3


source







All Articles