Dominik
Dominik

Reputation: 588

Yaml properties not loaded in springboot

I would like to use application.yml instead of application.properties

I followed: https://docs.spring.io/spring-boot/docs/2.1.13.RELEASE/reference/html/boot-features-external-config.html

I am using:

My MCVE: https://github.com/OldEngineer1911/demo1

The issue is: Properties are not loaded. Can someone please help?

Upvotes: 3

Views: 6769

Answers (2)

Dominik
Dominik

Reputation: 588

The solution from "@Panagiotis Bougiokos" is partially correct:

Products products = app.getBean(Products.class); <---Retrieve the Proxy instance from Spring Context

Is necessary, but the rest is optional (it is possible to write List in yml both ways). The solution was to fix yml file with nested products:

products:
  products:
    - 'first'
    - 'second'

And also add setter for products:

@Component
@ConfigurationProperties(prefix="products")
public class Products {
    private List<String> products;

    public List<String> getProducts() {
        return products;
    }

    public void setProducts(List<String> products) {
        this.products = products;
    }
}

This is a working solution (everyone can check Github mentioned in the question). Anyway, it still can be improved - don't know why do I need nested products.

Upvotes: 0

Panagiotis Bougioukos
Panagiotis Bougioukos

Reputation: 19173

You have the following code

@SpringBootApplication
public class Demo1Application {

    public static void main(String[] args) {
        SpringApplication.run(Demo1Application.class, args);
        Products products = new Products();  <---------------------------------ERROR!!!
        List<String> productsFromApplicationYml = products.getProducts();

        System.out.println(productsFromApplicationYml.size()); // I would like to see 2
        products.getProducts().forEach(System.out::println); // I would like to see "first" and "second"
    }



@Component
@ConfigurationProperties(prefix="products")
public class Products {
    private final List<String> products = new ArrayList<>();

    public List<String> getProducts() {
        return products;
    }
}

The error is in the line Products products = new Products(); of your main method. You don't retrieve the bean from Spring context but you create it by yourself in the JVM. Therefore it is as you created it empty.

Read more to understand how Spring uses proxies for your spring beans and not the actual classes that you write.

What you need is the following

public static void main(String[] args) {
  ApplicationContext app = SpringApplication.run(Demo1Application.class, args)

  Products products = app.getBean(Products.class); <---Retrieve the Proxy instance from Spring Context

  List<String> productsFromApplicationYml = products.getProducts();
  System.out.println(productsFromApplicationYml.size())

Edit:

You have also false configured your application.yml file.

products:
  - first
  - second

The symbol - is used for array of complex objects which spring will try to serialize from application.yml. Check what I mean in this SO thread

Considering that you don't have a list of custom objects but a primitive List<String> your application.yml should be in the following form

products: first,second

Upvotes: 1

Related Questions