First, the call stack
A typical spring-dependent injection call stack:
- Defaultlistablebeanfactory:getbean ()
- Abstractbeanfactory:dogetbean ()
- Abstractautowirecapablebeanfactory:createbean ()
- Abstractautowirecapablebeanfactory:createbeaninstance ()
- Simpleinstantiationstategy:instantiate ()
- Abstractautowirecapablebeanfactory:populatebean ()
- Abstractautowirecapablebeanfactory:applypropertyvalues ()
- Beandefinitionvalueresolver:resolvevalueifnecessary ()
- Beandefinitionvalueresolver:resolvereference ()
Ii. Dependency Injection Process
- Getbean: Dependency Injection of ingress, processing parameters call Dogetbean ()
- Dogetbean: Check if you need to create a bean and get beandefinition;
- the processing of a singleton bean , which can be taken from the singleton cache, does not need to be created. The process of finding the cache: find it first, if it is
singletonObjects
not found, and the bean that is being created, then find it from, and earlySingletonObjects
still not find it, by singletonFactories
getting it.
- the cyclic dependency detection of the prototype pattern Bean , if it detects that it is being created (
prototypesCurrentlyInCreation
exists in [ threadLocal
]), throws an exception because it is likely that a circular dependency has occurred.
- recursively finds Beandefinition, the Bean's definition does not exist in the current beanfactory, and Getbean is called recursively to the parent beanfactory until it is found.
- merges the parent beandefinition to get rootbeandefinition, if the bean definition obtained is a child bean definition, Then getmergedlocalbeandefinition merges it with the parent bean definition into a root bean definition
- legality detection of rootbeandefinition : whether
abstract
- The DependsOn explicitly declared in the bean definition is initialized (recursively): And the dependency is registered, and an exception is thrown if a circular dependency is detected.
- creating worker processing for beans
- Singleton Bean:
singletonObjects
Locked
- Add the Beanname to the
singletonsCurrentlyInCreation
middle
- Create Bean
singletonsCurrentlyInCreation
removing Beanname from
- Release
singletonObjects
Lock
- If an instance is created in the procedure, put it in, and
singletonObjects
registeredSingletons
remove it from singletonFactories
earlySingletonObjects
,
- If an exception occurs in the procedure, remove it from,,, and
singletonObjects
registeredSingletons
singletonFactories
earlySingletonObjects
- Processing
FactoryBean
- Prototype Pattern Bean:
prototypesCurrentlyInCreation
adding beanname to the middle
- Create Bean
prototypesCurrentlyInCreation
removing Beanname from
- Processing
FactoryBean
- The remaining scope bean processing:
- Detect if scope exists
- Call the Scope.get () method and pass in the GetObject () callback. The processing in the callback is basically consistent with the prototype.
- Processing
FactoryBean
- Process The return data type to detect if it can be converted to Requiredtype
- Createbean: Create a Bean instance, initialize the instance, call Postprocessors, etc.
- parse out the class type , i.e. parse out a class<?>, and assign to Rootbeandefinition. But can not be copied directly, need to copy a new rootbeandefinition, because Mergedbeandefinition is shared, there may be dynamically resolved class type, direct assignment may be problematic.
- preprocessing overrides the method , detects whether the overridden method exists, and determines whether it is overload.
- called once postprocessors is called
InstantiationAwareBeanPostProcessor
postProcessBeforeInstantiation
, it is possible to return a bean proxy. If the agent for the Bean is returned, it executes the Beanprocessor Postprocessafterinitialization method directly and returns.
- Call Hook Method Docreatebean
- Docreatebean
- Remove a bean from the same name from the cache with the same name
factoryBeanInstanceCache
- To create a bean instance createbeaninstance
- called again
MergedBeanDefinitionPostProcessor
by the postprocessors call.postProcessMergedBeanDefinition
- Singleton loop-dependent processing: Put the instance you just created (uninitialized) into the cache if it is a singleton bean and allow circular dependencies, you will just create a good instance, put
singletonFactories
in and registeredSingletons
earlySingletonObjects
Remove the same name bean from the
- Bean Initialization Populatebean, initializes the resulting bean instance with the property values in the bean definition
- perform the initialization of the spring extension Initializebean
invokeAwareMethods
If the bean implements some sub-interfaces of aware, such as Beannameaware, set the corresponding property to the bean
- Call The Postprocessbeforeinitialization method of Postprocessors call Beanpostprocessor again
invokeInitMethods
- If the bean implements the
InitializingBean
interface, execute the Afterpropertiesset () callback
- If Init-method is explicitly customized in the bean definition, a Initmethod callback (called by reflection) is executed once
- Call The Postprocessafterinitialization method of Postprocessors call Beanpostprocessor again
- Registering the bean Destruction method callback
- Createbeaninstance: Create a bean instance with different policies
- Factory method : If Factory-mothod is explicitly declared in the bean definition, the factory method is called to create the instance.
- Constructors : Selecting the appropriate constructor instantiation
- CGLIB : Using CGLIB instantiation
- Populatebean
- Get the property of the bean definition values
- Call once postprocessors calling
postprocessafterinstantiation
method of instantiationawarebeanpostprocessor
- handling Autowire injection
autowirebyname
or autowirebytype
- is called once postprocessors calls
instantiationawarebeanpostprocessor
Postprocesspropertyvalues
method - to inject properties Applypropertyvalues, attribute value injection, parse out the run-time bean References to other beans in the factory.
- Gets the beandefinitionvalueresolver.
- creates a new list of propertyvalue as a container for the parsed propertyvalue. Must be a deep copy, otherwise it will be modified to the property values in the original bean definition.
- Parse Property value:resolvevalueifnecessary ()
for different types of value objects, there are different convert methods, If value is of type runtimebeanreference, call the Getbean method recursively to get the bean. The
- uses the Beanwrapper Setpropertyvalues method to assign values to the bean's properties in bulk. Finally, the Setxxx () method of the calling Bean is assigned a value.
Iii. postprocessors and key method execution sequence
- "
instantiationawarebeanpostprocessor
" postprocessbeforeinstantiation ()
- createbeaninstance
- "
mergedbeandefinitionpostprocessor
" postprocessmergedbeandefinition ()
- "
instantiationawarebeanpostprocessor
" postprocessafterinstantiation ()
- autowirebyname ; autowirebytype
- "
instantiationawarebeanpostprocessor
" postprocesspropertyvalues ()
- applypropertyvalues
- "
beanpostprocessor
" postprocesspropertyvalues ()
- "
instantiationawarebeanpostprocessor
" postprocessbeforeinitialization ()
- invokeinitmethods
- "
instantiationawarebeanpostprocessor
" postprocessafterinitialization ()
Spring relies on injected source reading notes