Spring dependency injection source code reading notes

### 1. Call stack

A typical Spring dependency injection call stack:

1. DefaultListableBeanFactory:getBean()
2. AbstractBeanFactory:doGetBean()
3. AbstractAutowireCapableBeanFactory:createBean()
4. AbstractAutowireCapableBeanFactory:createBeanInstance()
5. SimpleInstantiationStategy:instantiate ()
6. AbstractAutowireCapableBeanFactory:populateBean()
7. AbstractAutowireCapableBeanFactory:applyPropertyValues()
8. BeanDefinitionValueResolver:resolveValueIfNecessary()
9. BeanDefinitionValueResolver:resolveReference()

### 2. Dependency injection process

1. getBean: The entry of dependency injection, processing parameter calls doGetBean()
2. doGetBean: Check whether a bean needs to be created and get the beanDefinition;
    * **Singleton Bean processing**, which can be obtained from the Singleton cache, so there is no need to create it. The process of finding the cache: first look it up from `singletonObjects`; if it is not found, and it is a bean being created, it is looked up from `earlySingletonObjects`; if it is still not found, it is obtained through `singletonFactories`.
    * **Circular dependency detection for prototype mode beans**, if it is detected that it is being created (existing in `prototypesCurrentlyInCreation`[`threadLocal`]), an exception is thrown, because at this time, it is very likely that a circular dependency has occurred.
    * **Recursively look up beanDefinition**, if the definition of the bean does not exist in the current BeanFactory, then recursively call getBean to the parent beanFactory until it is found.
    * **Merge the parent BeanDefinition to get the RootBeanDefinition**, if the acquired bean definition is a child bean definition, getMergedLocalBeanDefinition will merge it with the parent bean definition into a root bean definition
    * **Validity check of RootBeanDefinition**: whether `abstract`
    ** explicitly declared dependsOn in the bean definition, initializes (recursively) **: and registers dependencies, throws an exception if a circular dependency is detected.
    * **Auxiliary processing for creating beans**
        * Singleton bean:
            1. `singletonObjects` is locked
            2. Add beanName to `singletonsCurrentlyInCreation`
            3. ***Create Bean***
            4. Remove beanName from `singletonsCurrentlyInCreation`
            5. Unlock `singletonObjects`
            6. If an instance is created in the process, put it in Import `singletonObjects`, `registeredSingletons`, and remove
            from `singletonFactories`, `earlySingletonObjects` Except
            8. Handle `FactoryBean`
        * prototype mode beans:
            1. Add beanName to `prototypesCurrentlyInCreation`
            2. ***Create Bean***
            3. Remove beanName from `prototypesCurrentlyInCreation`
            4. Handle `FactoryBean`
        * rest of the scope bean handling:
            1. Check whether the scope exists
            2. Call the scope.get() method and pass in the getObject() callback. The processing in the callback is basically the same as under the prototype.
            3. Process `FactoryBean`
    * **Process the return data type**, check whether it can be converted to a requiredType
3. createBean: create a bean instance, initialize the instance, call postprocessors, etc.
    * **parse out the Class type**, that is Parse out a Class<?> and assign it to rootBeanDefinition. But it cannot be copied directly, and a new rootBeanDefinition needs to be copied, because mergedBeanDefinition is shared, and there may be dynamically resolved class types, and direct assignment may be problematic.
    * **Preprocess the override method**, detect whether the overridden method exists, and judge whether it is overload.
    * **Call postprocessors once** Call `postProcessBeforeInstantiation` of `InstantiationAwareBeanPostProcessor`, which may return a bean proxy. If the proxy of the bean is returned, then it will directly execute the postProcessAfterInitialization method of the beanProcessor and return.
    * **Call the hook method doCreateBean**
4. doCreateBean
    * **Remove the bean with the same name from the cache** Remove the bean with the same name from the `factoryBeanInstanceCache`
    * ***Create Bean instance*** *createBeanInstance*
    * **Call postprocessors once **Call `postProcessMergedBeanDefinition` of `MergedBeanDefinitionPostProcessor`
    * **Singleton circular dependency processing: The newly created instance (uninitialized) will be processed in advance, Put in the cache** If it is a Singleton Bean and allow circular dependencies, put the newly created instance into `singletonFactories` and `registeredSingletons`, and remove the bean of the same name from `earlySingletonObjects`
    * **Bean initialization* * *populateBean*, use the property values ​​in the bean definition to initialize the obtained bean instance
    * **Execute the initialization of the Spring extension** *initializeBean*
        * `invokeAwareMethods` If the bean implements some sub-interfaces of Aware, such as BeanNameAware, the corresponding Set the properties of the bean to the bean
        * **Call postprocessors once** Call the postProcessBeforeInitialization method of BeanPostProcessor
        * `invokeInitMethods` 
            * If the bean implements the `InitializingBean` interface, execute the afterPropertiesSet() callback
            * If the init-method is explicitly customized in the bean definition, an initMethod callback will be executed (invoked by reflection)
        * **Postprocessors are called once** Call the postProcessAfterInitialization method of BeanPostProcessor
    * **Register the bean destruction method callback**
5 .createBeanInstance: Use a different strategy to create a bean instance
    * **factory method**: If the factory-mothod is explicitly declared in the bean definition, call the **factory method** to create the instance.
    * **Constructor** : Select the appropriate constructor to instantiate
    * **CGLIB** : Use CGLIB to instantiate
6. populateBean
    * **Get the property values ​​of the bean definition**
    * **Call postprocessors** call ` The `postProcessAfterInstantiation` method of InstantiationAwareBeanPostProcessor
    ** ** handles autowire injection** `autowireByName` or `autowireByType`
    ** calls postprocessors once ** calls the `postProcessPropertyValues` method of `InstantiationAwareBeanPostProcessor`
    * **Injecting properties** applyPropertyValues, injecting property values, resolves references to other beans in the bean factory at runtime.
        * Get BeanDefinitionValueResolver.
        * Create a new list of PropertyValues ​​as a container for parsed PropertyValues. Must be a deep copy, otherwise it will modify the property values ​​in the original bean definition.
        * Resolve property value: resolveValueIfNecessary()
          has different conversion methods for different types of value objects. For example, if the value is of type RuntimeBeanReference, recursively call the getBean method to obtain the bean.
        * Use BeanWrapper's setPropertyValues ​​method to assign values ​​to bean properties in batches. Finally, the setXXX() method of the bean is called to assign the value. ### 3.



Execution order of postprocessors and key methods




4. 【`InstantiationAwareBeanPostProcessor`】`postProcessAfterInstantiation()`
5. ***autowireByName***;***autowireByType***
6. 【`InstantiationAwareBeanPostProcessor`】`postProcessPropertyValues()`
7. ***applyPropertyValues***
8. 【`BeanPostProcessor`】`postProcessPropertyValues()`
9. 【`InstantiationAwareBeanPostProcessor`】`postProcessBeforeInitialization()`
10. ***invokeInitMethods***
11. 【`InstantiationAwareBeanPostProcessor`】`postProcessAfterInitialization()`

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325330464&siteId=291194637