In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/01 Report--
This article will explain in detail the example analysis of @Async causing circular dependence in SpringBoot. Xiaobian thinks it is quite practical, so share it with you as a reference. I hope you can gain something after reading this article.
accident timeline
In line with the principle of "stop loss first, then re-offer analysis," let's take a look at the timeline of this publishing accident.
November 16, 2021 at 23:00:00 p.m. to start publishing, at this time the group devops a bit slow
At 23:03:01 pm on November 16, 2021, a message of publishing failure was received. The login server found that a circular dependency occurred. The specific error is shown in the following figure. From the log, you can see that the bean dataCollectionSendMessageService has a circular dependency.
The problem needs to be solved first and then analyzed why. See this error log I also know why, so quickly solved, the solution is as follows: add @Lazy annotation to DataCollectionSendMessageService
At 23:07:16 p.m. on November 16,2021, the re-integrated code was used to start publishing, and about 10 minutes later, all online nodes were published. From the timeline point of view, it took nearly 15 minutes from the discovery of the problem to the solution of the problem (during which time the code integration and release took too much time), which was also considered to have stopped the loss in time and did not let the problem continue to expand.
conjecture
My bold guess is that because the bean annotated with @Aysnc generates a proxy for the object, the Spring bean is not loaded with an original object, which leads to the occurrence of this problem, so right? Next, we will analyze it in detail through the source code.
What is Circular Dependence?
The so-called circular dependency means that the Spring IOC container loads beans in order, instantiating beanA first. BeanA is then found to depend on beanB, which is then instantiated. When instantiating beanB, beanB is found to depend on beanA. If the container does not handle circular dependencies, the container will execute the above process indefinitely until the memory overflow and the program crashes, so this time it will throw BeanCurrentlyInCreationException, which is what we often call circular dependencies. Here are two common scenarios for circular dependencies.
Circular dependencies between several beans
@Componentpublic class A { @Autowired private B b;}@Componentpublic class B { @Autowired private C c;}@Componentpublic class C { @Autowired private A a;}
The renderings are as follows:
Self-reliance.
@Componentpublic class A { @Autowired private A a;}
The renderings are as follows:
Spring is how to solve circular dependencies
First of all, Spring maintains three Maps, which is what we usually call a third-level cache.
SingletonObjects: Commonly known as singleton pool, cache created singleton beans
singletonFactories: maps the original factory that creates the Bean
earlySingletonObjects: early references to the Map Bean, meaning that the beans in this Map are not complete, but instantiated, but not initialized
Spring addresses circular dependencies through third-level caching, where the first-level cache is singleton objects, the second-level cache is early-exposure objects, and the third-level cache is early-exposure objects factories.
When A and B are cyclically referenced, after A is instantiated, an object factory is created using the instantiated object and added to the third-level cache. If A is AOP proxied, then the object obtained through this factory is the object after A is proxied. If A is not AOP proxied, then the object obtained by this factory is the object instantiated by A.
When A performs attribute injection, it will create B, and B depends on A. Therefore, when creating B, it will call getBean(a) to obtain the required dependency. At this time, getBean(a) will be obtained from the cache. The first step is to obtain the factory in the third-level cache. The second step is to call the getObject method of the object factory to obtain the corresponding object. After obtaining this object, it will be injected into B.
Then B goes through its lifecycle, including initialization, post-processor, and so on. When B is created, B is injected back into A, and A completes its life cycle. At this point, the circular dependency is over!
In a word: first go to the cache to find the Bean, if there is no instantiation of the current Bean into the Map, if there is a need to rely on the current Bean, you can get from the Map.
What is @Async?
@Async annotation is Spring provided for us to call asynchronous annotations,@Async can be applied to classes or methods, marked @Async method will be executed in a separate thread, the caller does not have to wait for it to complete, can continue other operations. As you can see from the source code, methods marked with the @Async annotation are submitted to org.springframework.core.task. Executor for asynchronous execution.
Or we can specify which custom thread pool to use by value, like this:
@Async("asyncTaskExecutor")
bean injection timing marked by @Async
Let's take a look at how @Async marked beans are injected into Spring containers from a source perspective. After we turn on the @EnableAsync annotation, it means that we can inject AsyncAnnotationBeanPostProcessor into the Spring container. It is a postprocessor. Let's take a look at its class diagram.
The code that actually creates the proxy object is in the postProcessAfterInitialization method in AbstractAdvisingBeanPostProcessor, and the following code is truncated to keep only the core logic code
//This map is used to cache all beans processed by the postProcessAfterInitialization method private final Map
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: 294
*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.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.