In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-01 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article mainly introduces "how to understand Spring circular dependency in java". In daily operation, I believe many people have doubts about how to understand Spring circular dependency in java. The editor consulted all kinds of materials and sorted out simple and easy-to-use operation methods. I hope it will be helpful for you to answer the doubts about "how to understand Spring circular dependency in java". Next, please follow the editor to study!
Generally speaking, if you ask Spring how to solve circular dependencies, it must be a single default singleton Bean where attributes refer to each other.
For example, several Bean references each other:
Even their own "cycle" depends on themselves:
To state the premise first: the Prototype scenario does not support circular dependencies. It usually goes to the following judgment in the AbstractBeanFactory class and throws an exception.
If (isPrototypeCurrentlyInCreation (beanName)) {throw new BeanCurrentlyInCreationException (beanName);}
The reason is easy to understand. When you create a new A, you find that you want to inject the prototype field B, and you create a new B that you want to inject the prototype field A.
This is the doll, do you think it is StackOverflow or OutOfMemory first?
Spring was afraid that it would be difficult for you to guess, so he threw out BeanCurrentlyInCreationException first.
Based on the circular dependency of the constructor, not to mention, the official documentation is a showdown, you want the constructor injection to support circular dependency, it does not exist, it is better to change the code.
So how does Spring support circular dependencies in the default singleton attribute injection scenario?
Spring solves circular dependency
First of all, Spring maintains three Map internally, which is commonly referred to as the third-level cache.
The author flipped through Spring documents but did not find the concept of three-level cache, which may also be a local vocabulary for easy understanding.
In the DefaultSingletonBeanRegistry class of Spring, you will be surprised to find these three Map hanging above the class:
SingletonObjects is our most familiar friend, commonly known as "singleton pool" and "container", where the cache is created to complete the singleton Bean.
SingletonFactories mapping creates the original factory of Bean
EarlySingletonObjects maps an early reference to Bean, that is, the Bean in this Map is not complete or even called "Bean", it is just an Instance.
The last two Map are actually "stepping stone" level, but when you create a Bean, you use it with the help of it, and then you clean it up.
So the author was a little confused about the word "three-level cache" earlier, probably because the comments all start with Cache of.
Why become the last two Map as stepping stones, assuming that the final Bean placed in singletonObjects is the cup you want to "cool open".
So Spring prepared two cups, singletonFactories and earlySingletonObjects, to "pour" back and forth several times, and put the hot water into a "cold boil" and put it in the singletonObjects.
No gossip, it's all condensed in the picture.
The one above is a GIF. If you haven't seen it, it may not be loaded yet. One frame per three seconds, not your computer card.
The author drew 17 diagrams to simplify the main steps of Spring. Above the GIF is the three-level cache just mentioned, and below are the main methods.
Of course, at this point, you must look at the Spring source code, or you won't understand it.
If you just want to get a general idea or interview, you can first remember the "three-tier cache" mentioned by the author above, as well as the nature that I will talk about below.
The nature of circular dependence
After understanding how Spring handles circular dependencies above, let's jump out of the mind of "reading the source code" and suppose you achieve a function with the following characteristics. What would you do?
Take some of the specified class instances as singletons
The fields in the class are also singleton instances.
Support for circular dependency
For example, suppose there is a class A:
Public class A {private B b;}
Class B:
Public class B {private An a;}
To put it bluntly, let you imitate Spring: pretend that An and B are modified by @ Component
And the fields in the class pretend to be decorated with @ Autowired and put into Map after processing.
In fact, it is very simple. The author wrote a rough code for reference:
/ * place the created bean Map * / private static Map cacheMap = new HashMap (2); public static void main (String [] args) {/ / pretend to scan the object Class [] classes = {A.class, B.class}; / / pretend to instantiate all bean for (Class aClass: classes) {getBean (aClass) } / / check System.out.println (getBean (B.class). GetA () = = getBean (A.class)); System.out.println (getBean (A.class). GetB () = = getBean (B.class));} @ SneakyThrows private static T getBean (Class beanClass) {/ / this article replaces bean's naming convention String beanName = beanClass.getSimpleName () .toLowerCase () with a simple lowercase class name. / / if it is already a bean, return if (cacheMap.containsKey (beanName)) {return (T) cacheMap.get (beanName) directly;} / / instantiate the object itself Object object = beanClass.getDeclaredConstructor () .newInstance (); / / put it into the cache cacheMap.put (beanName, object) / / create and inject all fields as bean to be injected into the current bean Field [] fields = object.getClass () .getDeclaredFields (); for (Field field: fields) {field.setAccessible (true); / / get class Class fieldfieldClass = field.getType (); String fieldBeanName = fieldClass.getSimpleName (). ToLowerCase () / / if the bean to be injected is already in the cache Map, then the value from the cache Map can be injected into the field / / if the cache does not continue to create the field.set (object, cacheMap.containsKey (fieldBeanName)? CacheMap.get (fieldBeanName): getBean (fieldClass));} / / attribute filling is completed, return return (T) object;}
The effect of this code is to deal with the circular dependency, and after the processing is completed, the complete "Bean" is put in the cacheMap.
This is the essence of "circular dependency", not "how Spring solves circular dependency".
The reason for giving this example is to find that a small number of people fall into the quagmire of "reading the source code" and forget the nature of the problem.
In order to see the source code and look at the source code, the result has been unable to understand, but forget what the essence is.
If you really don't understand, you might as well write the basic version first and reverse why Spring should be implemented in this way. The effect may be better.
What? The essence of the problem is two sum!
Do you have any deja vu after reading the code I just wrote? Yes, it is similar to two sum's problem solving.
I don't know what kind of two sum is. I'd like to introduce it to you:
Two sum is the exercise website leetcode serial number 1, that is, most people's algorithm introduction to the first question.
Often ridiculed by people, there is a method of the company, was appointed by the interviewer, come together. Then let's go through the formalities with a two sum.
The question is: given an array, given a number. Returns two indexes in the array that can be added to get the specified number.
For example, given nums = [2,7,11,15], target = 9
So return [0,1], because 2 + 7 = 9
The optimal solution to this problem is to iterate through + HashMap:
Class Solution {public int [] twoSum (int [] nums, int target) {Map map = new HashMap (); for (int I = 0; I < nums.length; iTunes +) {int complement = target-nums [I]; if (map.containsKey (complement)) {return new int [] {map.get (complement), I} } map.put (nums [I], I);} throw new IllegalArgumentException ("No two sum solution");} / / author: LeetCode / / Link: https://leetcode-cn.com/problems/two-sum/solution/liang-shu-zhi-he-by-leetcode-2/ Source: LeetCode
First go to Map to find the number you need, save the current number in Map without it, and return it together if you find the number you need.
Is it the same as the code above?
First look for Bean in the cache. If not, instantiate the current Bean and put it in Map. If you need to rely on the current Bean, you can get it from Map.
At this point, the study on "how to understand Spring circular dependency in java" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!
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: 208
*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.