Make writing a habit together! This is my first day to participate in the “Gold Digging Day New Plan · April More text challenge”, click to see the details of the activity.
1. Instantiate the inference before constructor
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean
A BeanWrapper object is created to declare the instantiated bean
Start instantiating
instanceWrapper = createBeanInstance(beanName, mbd, args);
Copy the code
To go in
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance
Gets the class type of the bean
Class<? > beanClass = resolveBeanClass(mbd, beanName);Copy the code
If the bean specifies a factory method, this if judgment is entered
Underlying get a factory method static factory methods | instantiation method 】 【 -- -- > then parsing methods into the ginseng > then performs reflection calls to create an instance - > packaging for packing object returned.Copy the code
if (mbd.getFactoryMethodName() ! = null) { return instantiateUsingFactoryMethod(beanName, mbd, args); }Copy the code
If the bean is a prototype, this branch will be taken
If it is not a prototype bean, methods that infer the constructor are executed
Constructor<? >[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);Copy the code
What is being instantiated is that Bean A does not appear to provide A constructor and will default to A no-argument constructor but Spring does not infer any constructors
Then call getPreferredConstructors, get the default constructor
ctors = mbd.getPreferredConstructors();
Copy the code
Get nothing and finally call the instantiateBean method
// No special handling: simply use no-arg constructor.
return instantiateBean(beanName, mbd);
Copy the code
The condition that gets here is that there is no callback method to create the bean && There is no factory method && the arguments to the constructor have not been parsed && there is no pre-specified default constructor
Follow up on the instantiateBean method
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
Copy the code
What is the returned instantiation policy
The default create strategies for: CglibSubclassingInstantiationStrategy
2. Instantiate the bean
Follow up the org. Springframework. Beans. Factory. Support. SimpleInstantiationStrategy. Instantiate
Get the bean’s class object, get the default constructor, to get to the constructor of the Settings to the bd, finally call BeanUtils. InstantiateClass (constructorToUse), and hand over the constructor
Come to org. Springframework. Beans. BeanUtils. InstantiateClass
InstantiateClass method in open violence reflected in BeanUtils., eventually the newInstance method complete instantiation object constructor calls
You can see it’s instantiated
Back to the org. Springframework. Beans. Factory. Support. AbstractAutowireCapableBeanFactory. DoCreateBean method
2.1 call the bean’s late MergedBeanDefinitionPostProcessor processor
The bean’s postprocessor is called again, the bean is instantiated, but the property injection is not complete
In turn call all MergedBeanDefinitionPostProcessor postProcessMergedBeanDefinition method, used to handle use annotations in the class of property, and into the cache.
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
Copy the code
3. After the Bean is instantiated, it is added to the level 3 cache
Further down, I see another triple judgment
Whether the current bean is a singleton, allows circular dependencies, and is being created is enough to move on
Calling the addSingletonFactory parameter also has a Lombad expression, which is used a lot
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
Copy the code
To go in
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.addSingletonFactory
‘If there is no beanName corresponding singleton bean in the current singleton cache pool,
! this.singletonObjects.containsKey(beanName)Copy the code
Put the Lombad expression into the level 3 cache,
this.singletonFactories.put(beanName, singletonFactory);
Copy the code
And divide beanName’s corresponding bean instance from the level 2 cache
this.earlySingletonObjects.remove(beanName);
Copy the code
‘saves the current beanName to the Set corresponding to the registered bean, indicating that it has been registered
this.registeredSingletons.add(beanName);
Copy the code
Return to addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, MBD, bean));
So let’s see what the override method does and notice it’s not called, right
Get all the post processor to judge whether true SmartInstantiationAwareBeanPostProcessor interface each call SmartInstantiationAwareBeanPostProcessor getEarlyBeanRef Erence Spring is at the heart of solving the problem of cyclic dependencies for AOP proxy objects
The doCreateBean method is then followed by a call to populateBean(beanName, MBD, instanceWrapper) to start the property filling phase
4. After the instantiation of rear InstantiationAwareBeanPostProcessor processing
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean
Instantiated call InstantiationAwareBeanPostProcessor. PostProcessAfterInstantiation () method
Seen last blog know before instantiation. Also called InstantiationAwareBeanPostProcessor postProcessBeforeInstantiation
If we rewrite the InstantiationAwareBeanPostProcessor postProcessAfterInstantiation () method, and returns false, will not fill, default is true
‘gets all properties of the bean currently being instantiated
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
Copy the code
The @autoWired method that determines the property population is neither ByName nor ByType
The current bean have rear InstantiationAwareBeanPostProcessor types of processors
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
Copy the code
Depend on the test
boolean needsDepCheck = (mbd.getDependencyCheck() ! = AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);Copy the code
If there is a rear InstantiationAwareBeanPostProcessor type of processor will enter the if judgment logic, execute the rear handler method
5. Attribute filling stage
The real property fill method applyPropertyValues(beanName, MBD, BW, PVS);
applyPropertyValues(beanName, mbd, bw, pvs);
Copy the code
Follow up applyPropertyValues
The setter method property is eventually populated by calling reflection
6. Execute three Aware callback methods before initialization
Back to the org. Springframework. Beans. Factory. Support. AbstractAutowireCapableBeanFactory. DoCreateBean method
The initialization method is executed immediately after the property is filled
Now look at the initialization method
exposedObject = initializeBean(beanName, exposedObject, mbd);
Copy the code
To go in
Three aware callback methods are called BeanNameAware -> BeanClassLoaderAware -> BeanFactoryAware
After perform three callback methods, call applyBeanPostProcessorsBeforeInitialization is a rear processor
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
Copy the code
7. Perform the BeanPostProcessor postProcessBeforeInitialization before initialization
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization
If postProcessBeforeInitialization method returns an object, then the current initializing bean will be to replace the current initializing the bean is a property value
After executing the BeanPostProcessor’s pre-initialization method, the invokeInitMethods method is executed to execute the initialization method
8. Perform initialization
invokeInitMethods(beanName, wrappedBean, mbd);
Copy the code
First determine if the InitializingBean interface is implemented. If so, the afterPropertiesSet method is executed
Checks if an initialization method is specified, and if so, the specified initialization method is executed by reflection
After the initialization method completes, go back to the initializeBean method and continue down to execute the post-method that executes the BeanPostProcessor
9. Perform the BeanPostProcessor postProcessAfterInitialization after initialization
applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
Copy the code
BeanPostProcessor. PostProcessAfterInitialization method to cow force, the proxy class is created here, AOP based on here
In the back to the org. Springframework. Beans. Factory. Support. AbstractAutowireCapableBeanFactory. DoCreateBean,
Come out from the initializeBean(beanName, exposedObject, MBD)
If you go further down if you have cyclic dependencies
Go to the getSingleton(beanName, false) method
Note getSingleton(beanName, false); Call false on the argument passed by the getSingleton method and it will not be fetched from the level 3 cache
10. Add to the singleton buffer pool
Bean is instantiated, back to the org. Springframework. Beans. Factory. Support. DefaultSingletonBeanRegistry. GetSingleton continue to go down
The afterSingletonCreation method is called to remove the beanName from the beanName collection being created
Then call addSingleton(beanName, singletonObject); Adds the current bean to the singleton buffer pool
‘puts the created singleton bean into the singleton cache pool
this.singletonObjects.put(beanName, singletonObject);
Copy the code
‘/ removed from level 3 cache
this.singletonFactories.remove(beanName);
Copy the code
‘removed from level 2 cache
this.earlySingletonObjects.remove(beanName);
Copy the code
‘to the collection of registered singleton Bean names
this.registeredSingletons.add(beanName);
Copy the code
At this point, the life cycle of a Bean in Spring is over, and the flow is quite large. In the next post, I will draw a detailed picture and explain how the three-level cache solves the problem of loop dependency