“This is the 22nd day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021.”

1. Introduction

The main purpose of this method is to create the bean, but only if the pre-creation of the bean has been completed. The pre-creation process of a bean is described in the Spring IOC container initializer — createBean() method.

2. DoCreateBean () the source code

Ps: Because this method is longer, I’ll break it down.

1. I’d like you to read it before I go into this paragraphBeanWrapper,

  • The main purpose of this code is to create a BeanWrapper object for the bean.
    1. If it’s a singleton, that means the object will only be created once, So we go from factoryBeanInstanceCache (in the org. Springframework. Beans. Factory. Support. AbstractAutowireCapableBeanFactory# getTypeForFactoryBean (Java. Lang. String, Org. Springframework. Beans. Factory. Support. RootBeanDefinition, Boolean), to determine when it is a single call: Org. Springframework. Beans. Factory. Support. AbstractAutowireCapableBeanFactory# getSingletonFactoryBeanForTypeCheck, Put operation), can be removed directly.
    2. If instanceWrapper is null, createBeanInstance(beanName, MBD, args) is called (more on that later) to create the BeanWrapper object.
    3. Get the BeanWrapper, the encapsulated bean instance, and the bean’s class object. When a beanType is not of NullBean type, change the resolvedTargetType in its beanDefinition

2. This part is immediately after the first part of the source code is as follows:

  • PostProcessed tag field indicates whether or not the perform of MergedBeanDefinitionPostProcessor postProcessMergedBeanDefinition method

  • applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);

  • We can see from the source code, It will obtain all the BeanPostProcessor, if the BeanPostProcessor MergedBeanDefinitionPostProcessor type will execute it PostProcessMergedBeanDefinition method, after the execution, the postProcessed set to true.

  • MergedBeanDefinitionPostProcessor: attribute merge rear post processor, usually in postProcessMergedBeanDefinition annotation scanning, attribute injection.

3. Eagerly caching singletons can solve circular references, even when lifecycle interfaces like Beanfactoryaware trigger.

  • Returns true when the bean being created is a singleton && that allows a loop reference to the current bean being created
  • If is entered when true is returned.

3.1 getEarlyBeanReference (beanName, MBD, beans)

  • To determine whether the current bean definitions of synthetic && returns are registered any InstantiationAwareBeanPostProcessors
  • EarlySingletonExposure: Whether advance exposure is required.
  • Remove all the traverse BeanPostProcessors, when it is SmartInstantiationAwareBeanPostProcessor types, execute it getEarlyBeanReference method. Gets the bean’s reference object and returns.

3.2 Default Object getEarlyBeanReference(Object bean, String beanName) (org. Springframework. Aop. Framework. Autoproxy. AbstractAutoProxyCreator# getEarlyBeanReference)

Main functions:Gets a reference for early access to a specified bean, typically used to resolve circular references.

  • Generate the key for the bean

  • If the beanname is null, the beanClass is returned directly
  • If beanClass is a subclass of FactoryBean, prefix beanName with & to return beanName.

  • Put the generated keys and beans into the map.

  • EarlyProxyReferences: Record pre-exposed beans.

  • Returns the generated proxy object, or itself. Ps :wrapIfNecessary is a method we’ll talk about later

3.3 Protected void addSingletonFactory(String beanName, ObjectFactory<? > singletonFactory)

Main functions:If necessary, add the given singleton factory to build the specified singleton. For emergency registration of singletons, such as being able to resolve circular references.

  • First check if level 1 cache is present, if level 1 cache is not present
  • Put it in level 3 cache, remove it from level 2 cache
  • Add it to the set set of registered singletons, including bean names in the order they were registered

4. The main purpose of this section is to initialize the bean instance

Ps: Both populateBean and initialzeBean are relatively important. I will talk about them in detail in the following articles

  • PopulateBean: The Spring container populates the bean, injecting the individual property values and the associated dependent beans
  • InitialzeBean: This method basically completes the bean initialization process. Call the inside of the post processor BeanPostProcessor postProcessBeforeInitialization method, called initialzingBean, call the afterPropertiesSet (), Call the init – mothod, calling the appropriate init method, call the inside of the post processor BeanPostProcessor call postProcessAfterInitialization method of implementation

5. Deal with objects that need to be exposed in advance

  • EarlySingletonExposure: Whether to advance exposure or enter if required.
  • Call getSingleton to get the singleton registered under this beanName. (ps:getSingleton details: 4.3) The earlySingletonReference is not null only if a cyclic dependency is detected.
  • ExposedObject == bean: indicates that exposedObject was not changed in the previous initialization method. Assign the earlySingletonReference to the exposedObject.
  • Otherwise, when it does not need to inject the original bean and has registered the dependent bean for the given name.
    • AllowRawInjectionDespiteWrapping: in the case of a circular reference, whether to need to inject an original bean instance, even into the bean is encapsulated in the end.
    • HasDependentBean (beanName) : Whether a dependent bean has been registered for the given name.
    • DependentBeans: Gets the name of all beans that depend on the specified bean
    • Create a set length and dependentBeans the same set, traverse dependentBeans, call removeSingletonIfCreatedForTypeCheckOnly (dependentBean) : Remove the singleton instance of the given bean name, if any, but only if it is not used for any purpose other than type checking.
    • If there is a dependentBean that has not been deleted, add it to the set. Raise an exception if the set is not null.

6. Register the bean as disposable.

  • RegisterDisposableBeanIfNecessary (beanName, bean, MBD) : Add the given bean to this factory’s list of disposable beans, register its DisposableBean interface and/or the given Destroy method, called when the factory closes (if applicable)

    • Get the accessible context
    • Determine when it is not in prototype mode and needs to be destroyed on shutdown
      • When it is a singleton pattern: register a DisposableBean implementation to perform a given bean destroyed all of the work: DestructionAwareBeanPostProcessors, DisposableBean interfaces, custom destroy method.
      • When it is another schema, the destruction logic is handed over to the custom scope
  • Return exposedObject