In-depth analysis of Spring boot property file loading and effective order

The core feature of spring boot is automatic configuration. When we learn spring boot, we first need to understand its automatic configuration principle, followed by the loading sequence of property files. I think these two points are the focus of learning spring boot.

There are many articles on the Internet that introduce the loading sequence of spring boot attribute files, but they have not analyzed the source code in depth.
Today I will explore the loading sequence of spring boot property files through the source code with everyone.

Let me explain one point first :
the attributes loaded first may not take effect, and the attributes loaded later may not necessarily overwrite the attribute values ​​loaded first.

Note:
Loading refers to the process of reading and loading the attribute value into the spring container;
validation refers to the process of using the loaded attribute value to initialize the bean.

The order in which attribute values ​​are loaded is not necessarily related to the order in which attribute values ​​take effect.

Why analyze?

Mainly in the actual project development process, due to the large number of property files, the configuration of the property files is often confused. The
most common problem is:
Why is the property configured clearly, but why does it not take effect when the project is started?
Therefore, it is very important to understand the order of reading and validating property files in the daily development process based on spring boot.

Source code analysis

1. Through the main startup class, find the doInvokeListener() method to establish a breakpoint, and observe the changes in the attribute source in the ApplicationEvent:
Note: The tested project is registered in euroke, and the attributes are loaded from the configuration center config.
Insert picture description here

2. The first 3 property sources
Insert picture description here
loaded Inlined Test Properties unit test properties
systemProperties JVM system properties
SystemEnvironmentProperty system environment variable properties

3. When the ConfigFileApplicationListener listener is initialized, the following data source
Insert picture description here
configurationProperties
configuration property source is newly loaded . This property source is special. He will not load the configuration properties himself, but put the property sources that have been loaded in the environment into storage in order Come in and put yourself at the head of the propertySourceList first. (I don’t understand it well, I feel it may be a caching mechanism)
random random number property source
springCloudClientHostInfo spring cloud client host related property source
bootstrap-dev.properties
bootstrap.properties
defaultProperties

4. Load configuration center properties. It
Insert picture description here
can be found that although the configuration center property source configService is loaded later, it is placed at the head of the propertySourceList.

5. After the startup is complete, the order of propertySourceList in the environment
Insert picture description here
feign feign calls the property source
systemProperties java se runtime system property
SystemEnvironmentProperty system environment variable property
configService configuration center property source
configurationProperties configuration property source
Inlined Test Properties unit test property
random random number property source
application -dev.propeties application-profile property source
application.propeties application property source
springCloudClientHostInfo spring cloud client host related property source
bootstrap-dev.propeties bootstrap-profile property source
bootstrap.propeties bootstrap property source
eureka/server.properties eureka service property source
defaultProperties Default attribute source

6. Source code analysis for reading property files
Insert picture description here

When springboot starts, it will initialize various property sources PropertySource and store the loaded property sources in the propertySourceList of the environment. When we get the property, we read the property value by traversing the property source of the propertySourceList, and get the corresponding property value and return it directly (read first), so the property source in front of the propertySourceList will take priority.

Note that the type of propertySourceList is CopyOnWriteArrayList, which is thread-safe ArrayList

7. Turn on the attribute acquisition log and monitor the attribute acquisition process

logging.level.org.springframework.core.env=trace

Insert picture description here

By injecting Environment, view the execution attribute loading sequence

@SpringBootTest
@Slf4j
class DemoApplicationTests {
    
    

    @Autowired
    Environment environment;

    @Test
    void getProperties() {
    
    
        System.out.println(environment.getProperty("spring.user.name"));
    }
}

Properties and yml configuration file loading order

Generally, it is best to use only one type of configuration file uniformly in spring boot to avoid configuration confusion.
The yml configuration file has a better format and more powerful functions, but the configuration format requirements of the property file are compared. It is difficult to troubleshoot the problem that the attribute cannot be read due to the format error, and it is not very convenient to search for the specified attribute by the attribute key value. The advantage of properties file is that it is simple, not prone to formatting problems, and it is easy to find properties.
Assuming that a project has both application.properties and application.yml files in the same location,

And they all contain the same key but different values, such as:

In application.properties: server.port=8001,

application.yml中:server.port=8888。

Question: Does springboot load both configuration files? If two files have the same key, which file value is used?

Answer: All are loaded, and loaded in the order of properties→yml.
Insert picture description here
In spring.factories, the order of configuration loader is to execute PropertiesPropertySourceLoader first and then to YamlPropertySourceLoader.

When the ConfigFileApplicationListener gets the value of the server.port key, you can find that both configuration files are loaded in, and pay attention to the order, with the application.properties file first.
Insert picture description here
The getSource() method gets the two Sources, first find the value in the application.properties file, once found, return immediately, if not found, then find it from application.yml.

to sum up

1. The properties read first in spring boot are not necessarily effective. The order of effectiveness is determined by the order of the property source propertySourceList in the environment when the bean is initialized.

2. The order in which the property source is initialized and read is not necessarily related to the order in which the propertySourceList is finally stored in the environment.

    environment.getPropertySources().addFirst(source);
    environment.getPropertySources().addAfter(source1,source2);
    environment.getPropertySources().addBefore(source1,source2);
    environment.getPropertySources().addLast(source);

3. The reading order of the property file is probably:
java se runtime system properties——"system environment variable properties——"
bootstrap.properties——"bootstrap-dev.properties——"configService configuration center property source——"application Property source-"application-dev property source

Note:
It can be seen from the loading sequence of the attribute source, why we must configure it in the bootstrap attribute file when we configure the configuration center in the business service module in the microservice.

4. Generally, only one type of configuration file is used for the configuration files in the two formats of yml and properties in the project.
If you configure both at the same time, the configuration file of properties will be loaded first, and the configuration properties of properties will take effect first.

5. The order in which the property file takes effect is roughly:
java se runtime system properties-"system environment variable properties-"
configService configuration center properties-"application-dev property source-" application property source-"bootstrap- dev.properties ——"bootstrap.properties
The properties that we configure in the java-jar startup script belong to the java se runtime system properties and have the highest priority.

6. If it is found in the project that the configured properties have not been effective, you can refer to the effective order of the property source to see if there is a problem of property overwriting.
A more direct way is to pass unit tests, execute environment.getProperty("spring.user.name"), view the order of the property source list propertySourceList, and print logs to determine which property source the property value is loaded from.

I hope that after reading this article, when you are asked about the loading sequence of the spring boot properties file, you can talk about it with confidence.

https://www.jianshu.com/p/256e6019349d

More exciting, follow me.
Legend: Follow the old man to learn java

Guess you like

Origin blog.csdn.net/w1014074794/article/details/106628856