[Spring] Bean life cycle source code analysis part Attribute filling and initialization process

1. Infer the constructor before instantiation

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean

image-20220403104229519

Created a BeanWrapper object to report instantiated beans

start instantiation

instanceWrapper = createBeanInstance(beanName, mbd, args);

image-20220403104722942

follow up

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance

image-20220403104803001

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

image-20220403105138275

If it is not a prototype bean, the method that inferred the constructor will be executed

Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);

image-20220403105258260

image-20220403105344834

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

image-20220403105509464

Then call getPreferredConstructors to get the default constructor

ctors = mbd.getPreferredConstructors();

image-20220403105619176

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

image-20220403105913726

beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);

Let's first see what the returned instantiation strategy is

image-20220403110042850

The default creation strategy is: CglibSubclassingInstantiationStrategy

2. Instantiate beans

跟进 org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate

image-20220403110258931

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

image-20220403110623024

Turn on violent reflection in the BeanUtils.instantiateClass method, and finally the constructor object calls the newInstance method to complete the instantiation

image-20220403110841317

It can be seen that it has been instantiated

回到 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean方法

image-20220403111419852

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);

image-20220403111643781

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

image-20220403112121449

The parameter of calling addSingletonFactory has another lombad expression, which is used a lot

addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));

image-20220403112256280

follow up

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.addSingletonFactory

image-20220403112433721

`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

image-20220403113143498

Then the doCreateBean method looks down, and then calls populateBean(beanName, mbd, instanceWrapper) to enter the attribute filling stage

image-20220403113642811

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

image-20220403113857627

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

image-20220403120849770

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

image-20220403121147250

5. Attribute filling stage

The real property filling method applyPropertyValues(beanName, mbd, bw, pvs);

applyPropertyValues(beanName, mbd, bw, pvs);

image-20220403121420005

Follow up on applyPropertyValues

image-20220403121534423

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 方法

image-20220403122213607

The initialization method is executed immediately after the property is filled

Then look at the initialization method

exposedObject = initializeBean(beanName, exposedObject, mbd);

image-20220403122307427

follow up

image-20220403122323649

Called three aware callback methods BeanNameAware -> BeanClassLoaderAware -> BeanFactoryAware

image-20220403122631719

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

image-20220403122821818

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);

image-20220403123223622

First, determine whether the InitializingBean interface is implemented. If it is implemented, the afterPropertiesSet method will be executed.

image-20220403123324702

Determine if there is an initialization method specified, and if so, execute the specified initialization method through reflection

image-20220403123421602

After the initialization method is executed, go back to the initializeBean method, continue down, and execute the post-method of the BeanPostProcessor.image-20220403123618646

9. Execute postProcessAfterInitialization of BeanPostProcessor after initialization

applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

image-20220403123737843

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)

image-20220403124304428

Continue down if there is a circular dependency

Come to the getSingleton(beanName, false) method

image-20220403124337224

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

image-20220403125446954

The afterSingletonCreation method will be called to remove the beanName from the beanName collection being created

image-20220403125722699

image-20220403125630910

Then call addSingleton(beanName, singletonObject); to add the current bean to the singleton buffer pool

image-20220403125754389

`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.

Guess you like

Origin blog.csdn.net/JAVAlife2021/article/details/123935985