1. Infer the constructor before instantiation
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean
Created a BeanWrapper object to report instantiated beans
start instantiation
instanceWrapper = createBeanInstance(beanName, mbd, args);
follow up
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance
Get the class type of the bean
Class<?> beanClass = resolveBeanClass(mbd, beanName);
If the bean specifies a factory method, it will enter this if judgment
底层会获取工厂方法【静态工厂方法|实例化方法】--> 然后解析方法入参 --> 然后执行反射调用创建实例 --> 封装为包装对象返回.
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
If the bean is a prototype, this branch will be taken
If it is not a prototype bean, the method that inferred the constructor will be executed
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
What is being instantiated now is that bean A does not explicitly provide a constructor, a no-argument constructor will be provided by default but spring does not infer any constructor
Then call getPreferredConstructors to get the default constructor
ctors = mbd.getPreferredConstructors();
As a result, I still get nothing and finally call the instantiateBean method
// No special handling: simply use no-arg constructor.
return instantiateBean(beanName, mbd);
Condition to get here No callback method for bean creation && No factory method && Constructor parameters are not resolved && No pre-specified default constructor
Follow up the instantiateBean method
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
Let's first see what the returned instantiation strategy is
The default creation strategy is: CglibSubclassingInstantiationStrategy
2. Instantiate beans
跟进 org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate
Get the class object of the bean, get the default constructor, set the obtained constructor to bd, and finally call BeanUtils.instantiateClass(constructorToUse), and pass the constructor
to org.springframework.beans.BeanUtils.instantiateClass
Turn on violent reflection in the BeanUtils.instantiateClass method, and finally the constructor object calls the newInstance method to complete the instantiation
It can be seen that it has been instantiated
回到 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean方法
2.1 Call the bean's MergedBeanDefinitionPostProcessor post-processor
Call the bean's post-processor again, this time the bean has been instantiated, but the property injection has not been completed
Call the postProcessMergedBeanDefinition method of all MergedBeanDefinitionPostProcessors in turn to process the attributes marked with annotations in the class and put them into the cache.
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
3. After the Bean is instantiated, add it to the L3 cache
Continue to go down, and see another three consecutive judgments
Whether the current bean is a singleton, whether circular dependencies are allowed, whether it is being created, all are satisfied to continue going down
The parameter of calling addSingletonFactory has another lombad expression, which is used a lot
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
follow up
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.addSingletonFactory
`If there is no single instance bean corresponding to beanName in the current single instance cache pool,
!this.singletonObjects.containsKey(beanName)
Put the lombad expression in the L3 cache,
this.singletonFactories.put(beanName, singletonFactory);
And remove the bean instance corresponding to beanName from the second level cache
this.earlySingletonObjects.remove(beanName);
`Save the current beanName to the Set collection corresponding to the registered bean, indicating that it has been registered
this.registeredSingletons.add(beanName);
回到addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
Look at what the overriding method does. Note that it is not called at this time
Get all post-processors to determine whether the SmartInstantiationAwareBeanPostProcessor interface is implemented and call the getEarlyBeanReference of SmartInstantiationAwareBeanPostProcessor one by one. Spring solves the core of the circular dependency problem of AOP proxy objects
Then the doCreateBean method looks down, and then calls populateBean(beanName, mbd, instanceWrapper) to enter the attribute filling stage
4. Post-processing of InstantiationAwareBeanPostProcessor after instantiation
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean
Call the InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation() method after instantiation
After reading the previous blog post, I know that InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation is also called before instantiation
If we override the InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation() method and return false, the property will not be populated, the default is true
`Get all properties of the bean currently being instantiated
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
The method of judging property filling @Autowired neither belongs to ByName nor ByType
Whether the current bean has a post processor of type InstantiationAwareBeanPostProcessor
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
Dependency detection
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
If there is a post-processor of InstantiationAwareBeanPostProcessor type, it will enter the if judgment logic and execute the post-processor method
5. Attribute filling stage
The real property filling method applyPropertyValues(beanName, mbd, bw, pvs);
applyPropertyValues(beanName, mbd, bw, pvs);
Follow up on applyPropertyValues
Finally, the property is populated by calling the setter method through reflection
6. Execute three aware callback methods before initialization
回到 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean 方法
The initialization method is executed immediately after the property is filled
Then look at the initialization method
exposedObject = initializeBean(beanName, exposedObject, mbd);
follow up
Called three aware callback methods BeanNameAware -> BeanClassLoaderAware -> BeanFactoryAware
After executing the three callback methods, calling applyBeanPostProcessorsBeforeInitialization is another post-processor
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
7. Execute postProcessBeforeInitialization of BeanPostProcessor before initialization
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization
If the postProcessBeforeInitialization method returns an object, the bean currently being initialized will be replaced. The bean currently being initialized has a property value
After executing the initialization pre-method of BeanPostProcessor, the invokeInitMethods method will be executed, and the initialization method will be executed.
8. Execute the initialization method
invokeInitMethods(beanName, wrappedBean, mbd);
First, determine whether the InitializingBean interface is implemented. If it is implemented, the afterPropertiesSet method will be executed.
Determine if there is an initialization method specified, and if so, execute the specified initialization method through reflection
After the initialization method is executed, go back to the initializeBean method, continue down, and execute the post-method of the BeanPostProcessor.
9. Execute postProcessAfterInitialization of BeanPostProcessor after initialization
applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
The BeanPostProcessor.postProcessAfterInitialization method is awesome, the proxy class is created here, and AOP is based on the implementation here
在回到 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean,
out of initializeBean(beanName, exposedObject, mbd)
Continue down if there is a circular dependency
Come to the getSingleton(beanName, false) method
Pay attention to getSingleton(beanName, false); when calling the parameter passed by the getSingleton method, it will not go to the third-level cache.
10. Add to the singleton buffer pool
After the bean has been instantiated, go back to org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton and continue down
The afterSingletonCreation method will be called to remove the beanName from the beanName collection being created
Then call addSingleton(beanName, singletonObject); to add the current bean to the singleton buffer pool
`Put the created single instance bean into the singleton cache pool
this.singletonObjects.put(beanName, singletonObject);
`/ Remove from L3 cache
this.singletonFactories.remove(beanName);
`Remove from L2 cache
this.earlySingletonObjects.remove(beanName);
`Save to the registered single instance bean name collection
this.registeredSingletons.add(beanName);
So far, the life cycle of a bean in Spring has been completed, and there are many processes. The next blog post will draw a picture in detail and explain how the third-level cache solves the circular dependency problem.