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