Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Abnormal problems caused by the change of loading mode of Spring configuration file

2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly shows you the "abnormal problems caused by changes in the loading mode of Spring configuration files", which is easy to understand and well-organized. I hope it can help you solve your doubts. Let me lead you to study and learn the abnormal problems caused by changes in the loading mode of Spring configuration files.

Problem background

The configuration file of our project has always been managed through Apollo, but recently, due to some special deployment requirements, we need to use the native object of K8S to get the configuration, so we need to use the environment variable spring.config.location to specify the path of the application.properties file in order to get the configuration dynamically.

Description: the project is a dubbo project, the configuration file mainly includes the configuration of some basic components, as well as dubbo-related configuration.

At this time, the problem arises. If all the configurations and codes remain unchanged, if you do not specify the environment variable to use the local application.properties, there will be no exception, and the project can start normally, but once the configuration is loaded through spring.config.location, the project will fail directly and report the following exception:

NoSuchBeanDefinitionException, this exception misled me for a long time. Generally speaking, when Spring initializes the container, it does not find the corresponding bean definition during dependency injection, which means that the bean has not been registered in BeanFactory at all. This is very strange, but the configuration file is loaded differently, so why does it affect the registration of bean?

Process

When bean cannot be found, there are two most common problems: either configuration problems, such as misconfiguration of scanned packages, configuration ineffectiveness, and so on. Or there is a problem with the IoC container, there are multiple containers, resulting in bean isolation.

Positioning

In this problem scenario, both reasons are possible, but if the problem can be repeated, it will be easier to solve. Let's verify directly that the simplest and roughest way is to serve at breakpoints and compare the differences between the two configuration loading methods. We know that except for delayed loading bean, all bean are initialized in org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons, so in this method, make a conditional breakpoint with the name of bean in the exception message.

Through the breakpoint, you can get two pieces of information

1. Through the current stack, we can see that the current initialization bean logic is not triggered by SpringBoot's IoC container, but by SpringCloud.

2. BeanNames, that is, all the registered bean in the current beanFactory, is not loaded into any bean identified by the @ Service annotation of Spring, but it is loaded into all bean loaded by the @ Service of Dubbo.

In this way, we can confirm that multi-container isolation does exist, and SpringCloud will also create an IoC container through the BootstrapApplicationListener listener to check the official instructions:

A Spring Cloud application operates by creating a "bootstrap" context, which is a parent context for the main application. It is responsible for loading configuration properties from the external sources and for decrypting properties in the local external configuration files. The two contexts share an Environment, which is the source of external properties for any Spring application. By default, bootstrap properties (not bootstrap.properties but properties that are loaded during the bootstrap phase) are added with high precedence, so they cannot be overridden by local configuration.

Containers created by SpringCloud are loaded earlier than SpringBoot, are its parent, and share the same Environment.

Although you now know the cause of the exception, why is it loaded by the parent container if you change the configuration load mode? According to the second information above, the bean identified by the Dubbo comment has been loaded, but the SpringBean on which the bean depends has not been loaded, which means that the loading timing of the bean marked by the Dubbo has changed due to a change in the way the configuration file is loaded.

Root cause

The next step is to take a look at Dubbo's bean loading logic. Our service is older and uses spring-boot-starter-dubbo to integrate SpringBoot and Dubbo. Generally, spring-boot-starter automatically loads the relevant bean through @ EnableXXX or spring.factories, but spring-boot-starter-dubbo does not use @ Enable, so go directly to the spring.factories file under the jar package and find the corresponding Initializer:

It implements ApplicationContextInitiailizer, and these interfaces will be called in prepareContext after preparing the Context environment, so it is obvious that the parent container will execute first and the child container will execute later. Looking at the code logic, it registers bean only when it reads that spring.dubbo.scan has a value. The reason is obvious. When using application.properties, the parent container cannot read the configuration, while when using spring.config.location to load the configuration, the parent container can read the configuration.

Configure the loading order

There is a sentence in the SpringCloud document mentioned above:

By default, bootstrap properties (not bootstrap.properties but properties that are loaded during the bootstrap phase) are added with high precedence

So is it in bootstrap phase to load attributes through spring.config.location? directly find the loading class BootstrapApplicationListener of SpringCloud, search spring.config.location, and find that it does have priority to load.

If you use application.properties, the configuration file will not be loaded into the SpringCloud, but will be loaded by the child container.

Solve

Since the root of the problem has been found, it is easier to solve it in two ways:

Directly close the boostrap listener of SpringCloud and configure spring.cloud.bootstrap.enabled=false.

As a matter of fact, this problem is also caused by the unreasonable integration of dubbo, which is scanned with annotations that come with Dubbo instead of configuration files.

These are all the contents of this article entitled "abnormal problems caused by changes in the loading mode of Spring configuration files". Thank you for reading! I believe we all have a certain understanding, hope to share the content to help you, if you want to learn more knowledge, welcome to follow the industry information channel!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report