Find out in 10 minutes How does SpringBoot gracefully read configuration files?

Keywords: Programming Spring Lombok SpringBoot Java

This article is and is included in the springboot-guide (not just SpringBoot but also Spring Key Knowledge Points), address: https://github.com/Snailclimb/springboot-guide .Make it easier for you to learn Spring!If you feel good, welcome to a Star!

Many times we need to put some commonly used configuration information such as Aliyun oss configuration, information configuration about sending SMS, etc. into the configuration file.

Let's see how Spring can help us read this configuration information from the configuration file.

The application.yml is as follows:

wuhan2020: 2020 At the beginning of this year, a new type of coronavirus broke out in Wuhan, which caused a serious epidemic. However, I believe everything will be over!Go to Wuhan!Go China!

my-profile:
  name: Guide Brother
  email: koushuangbwcx@163.com

library:
  location: HuBei Wuhan Petroleum China Petroleum
  books:
    - name: Basic Law of Genius
      description: On the day his father diagnosed Alzheimer's disease, 22-year-old Lin learned that he had been secretly in love with the campus God Pei for many years and was about to go abroad for further study - the school his father had chosen was the one he had abandoned for her.
    - name: Order of time
      description: Why do we remember the past, not the future?What does the passage of time mean?Are we in time, or is time in us?Carol·With his poems, Rowe invites us to think about this perpetual problem, the nature of time.
    - name: Great Me
      description: How can I make a new habit?How can I make my mind more mature?How can I have a high quality relationship?How do I get out of the hard times of life?

1. Read simpler configuration information through @value

Read simpler configuration information using @Value("${property}"):

@Value("${wuhan2020}")
String wuhan2020;

It is important to note that @value is not recommended, and Spring recommends the following ways to read configuration information.

2. Read from @ConfigurationProperties and bind to bean s

The LibraryProperties class has the @Component annotation added, and we can inject it into the class as if it were a normal bean.


import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
@ConfigurationProperties(prefix = "library")
@Setter
@Getter
@ToString
class LibraryProperties {
    private String location;
    private List<Book> books;

    @Setter
    @Getter
    @ToString
    static class Book {
        String name;
        String description;
    }
}

At this point, you can inject it into the class as you would with a normal bean:

package cn.javaguide.readconfigproperties;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author shuang.kou
 */
@SpringBootApplication
public class ReadConfigPropertiesApplication implements InitializingBean {

    private final LibraryProperties library;

    public ReadConfigPropertiesApplication(LibraryProperties library) {
        this.library = library;
    }

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

    @Override
    public void afterPropertiesSet() {
        System.out.println(library.getLocation());
        System.out.println(library.getBooks());    }
}

Console Output:

HuBei Wuhan Petroleum China Petroleum
 [LibraryProperties.Book(name = Basic Law of Genius, description.......)]

3. Read and verify through @ConfigurationProperties

Let's first modify application.yml to the following, which clearly shows that this is not the correct email format:

my-profile:
  name: Guide Brother
  email: koushuangbwcx@

The ProfileProperties class is not annotated with @Component.We use @EnableConfiguration Properties to register our configuration bean s where we want to use ProfileProperties:

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;

import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;

/**
* @author shuang.kou
*/
@Getter
@Setter
@ToString
@ConfigurationProperties("my-profile")
@Validated
public class ProfileProperties {
   @NotEmpty
   private String name;

   @Email
   @NotEmpty
   private String email;

   //Default value if not read in configuration file
   private Boolean handsome = Boolean.TRUE;

}

Specific use:

package cn.javaguide.readconfigproperties;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;

/**
 * @author shuang.kou
 */
@SpringBootApplication
@EnableConfigurationProperties(ProfileProperties.class)
public class ReadConfigPropertiesApplication implements InitializingBean {
    private final ProfileProperties profileProperties;

    public ReadConfigPropertiesApplication(ProfileProperties profileProperties) {
        this.profileProperties = profileProperties;
    }

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

    @Override
    public void afterPropertiesSet() {
        System.out.println(profileProperties.toString());
    }
}

Because our mailbox format is incorrect, the program runs with errors and cannot run at all, which ensures the security of data types:

Binding to target org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'my-profile' to cn.javaguide.readconfigproperties.ProfileProperties failed:

    Property: my-profile.email
    Value: koushuangbwcx@
    Origin: class path resource [application.yml]:5:10
    Reason: must be a well-formed email address

If we correct the mailbox test and run it again, the console will print out the read information successfully:

ProfileProperties(name=Guide Brother, email=koushuangbwcx@163.com, handsome=true)

4.@PropertySource reads the specified properties file

import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

@Component
@PropertySource("classpath:website.properties")
@Getter
@Setter
class WebSite {
    @Value("${url}")
    private String url;
}

Use:

@Autowired
private WebSite webSite;

System.out.println(webSite.getUrl());//https://javaguide.cn/

5. Off-topic: Priority of Spring loading configuration files

Spring also has priority in reading configuration files, as shown above:

<img src="https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-11/read-config-properties-priority.jpg" style="zoom:50%;" />

For more information, check the official documentation: https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-external-config

Source code for this article: https://github.com/Snailclimb/springboot-guide/tree/master/source-code/basis/read-config-properties

Open source project recommendation

Author's other open source projects recommend:

  1. JavaGuide :[Java Learning + Interview Guide] Covers the core knowledge most Java programmers need to master.
  2. springboot-guide : Spring Boot tutorials for beginners and experienced developers (maintenance in spare time is welcome).
  3. programmer-advancement : I think technicians should have some good habits!
  4. spring-security-jwt-guide : Get started from zero!Spring Security With JWT (with permission validation) back-end part code.

Public Number

Posted by vincent30000 on Sat, 08 Feb 2020 19:56:20 -0800