“This is the 15th day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021.”
1. Introduction
This paper is mainly a continuation of the Spring IOC container initialization principle analysis (section 6). In this article we mainly talk about detailed preInstantiateSingletons the getBean () (String name) method and the AccessController doPrivileged () method, Other methods in preInstantiateSingletons() have already been analyzed, if you are interested, check them out.
2.getBean(String name)
As usual we directly paste the source code first
This method is a bit long, so let’s look at the introduction of the method:
Returns an instance of the specified bean, which can be shared or independent. Brief Introduction to parameters:
- Name: The name of the bean to retrieve
- RequiredType: The type of the bean to retrieve
- Args: Args parameter used to build bean instances (only at creation time)
- TypeCheckOnly: indicates whether type check is performed
I’m going to cut it out for you because it’s so long
1. The first piece of code for doGetBean
-
RansformedBeanName: Returns the bean name, removing the factory dereference prefix if necessary, and resolving the alias to the canonical name. The processed name returned here corresponds directly to the key in singletonObjects.
-
GetSingleton (beanName) ¶ getSingleton(beanName) ¶ getSingleton(beanName) ¶ getSingleton(beanName) ¶
-
IsSingletonCurrentlyInCreation (beanName) : returns the specified singleton beans in current is created
-
GetObjectForBeanInstance () : The previously returned sharedInstance is the original bean, not necessarily what we want. The object that gets the given bean instance can be either the bean instance itself or an object created in a FactoryBean.
- If it is a FactoryBean name, it returns beanInstance instanceof Nullbean and throws an exception if it is not a FactoryBean name
- Where name does not start with ‘&’, it is returned if it is not a FactoryBean.
- If it is a FactoryBean then look down and try to fetch it from the FactoryBean singleton object cache. If it is not empty, return it
- Force to FactoryBean, as determined above, must be of type FactoryBean.
-
When MBD = = null, save BeanDefinition map can take to the beanName BeanDefinition, call getMergedLocalBeanDefinition (beanName)
-
Determine if the MDB is empty and if it was created by the system, and then call the getObjectFromFactoryBean () method.
-
The main function of the first block is when sharedInstance! = null and args == NULL gets the bean object
2. The second block of doGetBean code
Now let’s move on to sharedInstance! = null and args == null, the rest is handled here.
-
IsPrototypeCurrentlyInCreation (beanName), check whether there is anyThe prototype patternIf there is a direct throw exception, Spring cannot resolve it. RototypesCurrentlyInCreation saved is archetypal pattern is creating object, as it contains the beanName indicating circular dependencies,How to resolve loop dependencies in singleton mode
-
Checks if the specified beanDefinition exists in the current container
- The parent container of the current container is not null and the beanDefinition corresponding to the beanName cannot be found in the Map that holds the beanDefinition.
- Parse the original name of the beanName
- When parentFactory instanceof AbstractBeanFactory is recursively searched in the parent container
- Otherwise, when args is not null, delegate the parent container to look by name and parameter
- Otherwise, if requiredType is not null, delegate the parent container to find by name and type
- Otherwise, assign the parent to find the play name
- TypeCheckOnly: indicates whether type check is required. Enter if no type check is required
This part of the code is mainly used to create beans specified by the tag to the container when type judgments are not needed.
- This. aredyCreated: Saves the name of the bean that has been created
- Enclosing mergedBeanDefinitions: save beanName – > RootBeanDefinition
3. The third block of doGetBean code
- We first get the Bean definition of the parent class, and the subclass incorporates the public properties of the parent class,GetMergedLocalBeanDefinition talked about in the previous article 4.1, and then check the given merge bean definition
- Mbd.getdependson () : Obtain the name of the Bean on which the current Bean depends. If it is not null, extract each dependent Bean IsDependent (beanName dependentBeanName) : checking depends on the bean called beanName depend on whether the beans of famous for dependentBeanNamed, (namely judging dependentBeanName BeanName dependent or not)
- AlreadySeen: Checked. This saves all checked Beannames
- DependentBeans if the current beanName has already returned false in alreadySeen, otherwise extract the name of the beans that depend on it.
- Return true if a dependentBeans contains a dependentBeanName, otherwise iterate over the dependentBeans and add the beanName to the alreadySeen. The recursion determines whether a dependentBeanName is dependent on each beanName in a dependentBeans
- When it has such a cyclic dependency, it throws an exception, which is why singleton pattern constructors rely on each other too much for Spring to resolve.
- RegisterDependentBean (DEP, beanName) : The bean to which the specified bean is injected
- Dep: Specifies the bean
- BeanName: dependent bean
- This. dependentBeanMap: Saves a beanNames collection that depends on the specified bean
- Enclosing dependenciesForBeanMap: save the specified bean dependencies beanNames collection
- Update this. DependentBeanMap (key = canonicalName); if null, create a LinkedHsahSet. Add dependentBeanName to the mix. (This. DependentBeanMap of the bean that the bean depends on when creating the current bean)
- Then lock enclosing dependenciesForBeanMap, here is actually, the current create bean enclosing dependenciesForBeanMap update, it relies on canonicalName
- getBean(dep)
- Dep: The bean on which the currently created bean depends, which is created first.
4. The fourth block of doGetBean code
This section of the generation mainly completes the bean instantiation, originally wanted to finish this article, but if you want to go into details, it is too much, so this article is mainly about the general, the next article I will look at this section of the code in detail
- First determine if it is a singleton, and if it is, instantiate the singleton
- Determine if it is model mode, and if it is, create an object each time
- Otherwise, fetching its scope also creates an instance object and returns it
5. The fifth block of doGetBean code
-
IsInstance (Object obj) is a native method of the Class Class that checks whether a bean can be converted to a requiredType method
-
When requiredType is not null and the bean cannot be converted to requiredType
- Get the user-defined type converter. If not, Spring will return the default SimpleTypeConverter type converter.
- ConvertIfNecessary (bean,requiredType) : Convert the bean to requiredType. If it is custom, you need to implement the interface and override the method. If it is the default SimpleTypeConverter type converter, it calls: Org. Springframework. Beans. TypeConverterSupport# convertIfNecessary (java.lang.object, Java. Lang. Class), there is time to tell me the additional behind this
- Return the bean on success or throw an exception on failure.
GetBean (name) : getBean(name); getBean(name);
3. AccessController.doPrivileged(PrivilegedAction action,AccessControlContext context)
PreInstantiateSingletons () : preInstantiateSingletons() : preInstantiateSingletons() : preInstantiateSingletons
4. To summarize
That’s all for today. The next article will focus on the singleton pattern, prototype pattern, and other scope object creation details mentioned above.