As mentioned earlier in combing through the source code for SpringBean creation, draw a flow chart of the interfaces involved. Now fill in the hole. Meanwhile, I was mainly focused on Spring’s code logic (so I can’t read it myself now). In this rereading series, we start with the overall structure, and if it is not particularly important to the logic, we do not focus on some of the details of the logic.

A, DefaultListableBeanFactory

1, structure,

For SpringMVC Bean container core class is the implementation of the DefaultListableBeanFactory, then we’ll look at the hierarchy

The inheritance of class we need to pay attention to DefaultSingletonBeanRegistry, AbstractBeanFactory, including DefaultSingletonBeanRegistry class is a singleton Bean of the deposit, AbstractBeanFactory is the entire logical processing of getting a Bean.

Let’s look directly at the process of obtaining beans. The sequence diagram drawn below is not a standard sequence diagram, but just an overview of the process, so if you want to draw a standard sequence diagram, please study the resources.

Ii. Stage 1 (Extend direct object instance creation)

Can be generated directly by the InstantiationAwareBeanPostProcessor interface beans here, but the Spring annotations is that the interface is generally for use within the Spring framework, and is not recommended to use this interface directly. If must expand, the recommended InstantiationAwareBeanPostProcessorAdapter interface

public abstract class InstantiationAwareBeanPostProcessorAdapter implements SmartInstantiationAwareBeanPostProcessor {
Copy the code

You can see the SmartInstantiationAwareBeanPostProcessor interface is realized.

1. Extensible interface

This stage can expand interface ` ` InstantiationAwareBeanPostProcessor, official recommends InstantiationAwareBeanPostProcessorAdapter `

2. Flow chart

This is the first stage of getting the Bean, and you can see that it passesInstantiationAwareBeanPostProcessorTo generate the Bean, and you can see that it calls the other extension interfaceBeanPostProcessorThe interface.

3. Introduction of the overall process

Class

requiredType). Class

requiredType (Class

requiredType) can also be used as the input parameter, but it will be converted to name


@Override
public Object getBean(String name) throws BeansException {
   return doGetBean(name, null, null, false);
}
Copy the code
@Override
public <T> T getBean(Class<T> requiredType) throws BeansException {
   return getBean(requiredType, (Object[]) null);
}
Copy the code

2) We can see that it calls the doGetBean method

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
      @Nullable final Object[] args, boolean typeCheckOnly)
Copy the code

3) Then you can see that if it is a singleton, it calls the getSingleton method to get the corresponding Bean instance, but it is created by the createBean method

if (mbd.isSingleton()) {
   sharedInstance = getSingleton(beanName, () -> {
      try {
         return createBean(beanName, mbd, args);
      }
      catch (BeansException ex) {
         // Explicitly remove instance from singleton cache: It might have been put there
         // eagerly by the creation process, to allow for circular reference resolution.
         // Also remove any beans that received a temporary reference to the bean.
         destroySingleton(beanName);
         throwex; }}); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); }Copy the code

. 4), then through mbdToUse prepareMethodOverrides hasMethodOverrides () call () method to determine processing < lookup method – > tag.

@Override protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { RootBeanDefinition mbdToUse = mbd; Class<? > resolvedClass = resolveBeanClass(mbd, beanName); . // Prepare method overrides. try { mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean ! = null) { return bean; } } catch (Throwable ex) { ........ } try { Object beanInstance = doCreateBean(beanName, mbdToUse, args); return beanInstance; }... }Copy the code
public void prepareMethodOverrides(a) throws BeanDefinitionValidationException {
   // Check that lookup methods exists.
   if (hasMethodOverrides()) {
      Set<MethodOverride> overrides = getMethodOverrides().getOverrides();
      synchronized (overrides) {
         for(MethodOverride mo : overrides) { prepareMethodOverride(mo); }}}}protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
		intcount = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName()); .else if (count == 1) {
			// Mark override as not overloaded, to avoid the overhead of arg type checking.
			mo.setOverloaded(false); }}Copy the code

5), and then through resolveBeforeInstantiation think you could get to a Bean.

Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
Copy the code

6), through the hasInstantiationAwareBeanPostProcessors () method to look have InstantiationAwareBeanPostProcessors interface implementation class, if you have, Call the interface postProcessBeforeInstantiation method, if the interface has create return Bean, call the BeanPostProcessor interface postProcessAfterInitialization method again, This completes the creation of the Bean.

@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
   Object bean = null;
   if(! Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {// Make sure bean class is actually resolved at this point.
      if(! mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { Class<? > targetType = determineTargetType(beanName, mbd);if(targetType ! =null) {
            bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
            if(bean ! =null) { bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } } mbd.beforeInstantiationResolved = (bean ! =null);
   }
   return bean;
}
Copy the code
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class
        beanClass, String beanName) {
   for (BeanPostProcessor bp : getBeanPostProcessors()) {
      if (bp instanceof InstantiationAwareBeanPostProcessor) {
         InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
         Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
         if(result ! =null) {
            returnresult; }}}return null;
}
Copy the code
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
      throws BeansException {

   Object result = existingBean;
   for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
      Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
      if (current == null) {
         return result;
      }
      result = current;
   }
   return result;
}
Copy the code

We see if it is at this stage by InstantiationAwareBeanPostProcessor interface produced Bean returned, Then it will only call the BeanPostProcessor interface postProcessAfterInitialization method, won’t call its such as some Aware interface.

If above did not produce by InstantiationAwareBeanPostProcessor Bean, will then to invoke doCreateBean (beanName mbdToUse, args) method.

3. Stage 2 (Extend constructor to create instance)

1. Extensible interface

Here are the interfaces that can be extended:

1. Supplier to BeanDefinition

BeanDefinition <factory-method> factory method

3, SmartInstantiationAwareBeanPostProcessor, this also is recommended adapter InstantiationAwareBeanPostProcessorAdapter to expand

2. Flow chart

3. Overall process

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
      throws BeanCreationException {... instanceWrapper = createBeanInstance(beanName, mbd, args); }finalObject bean = instanceWrapper.getWrappedInstance(); Class<? > beanType = instanceWrapper.getWrappedClass(); .// Allow post-processors to modify the merged bean definition.
   synchronized (mbd.postProcessingLock) {
      if(! mbd.postProcessed) {try {
            applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
         }
         catch (Throwable ex) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                  "Post-processing of merged bean definition failed", ex);
         }
         mbd.postProcessed = true; }}...// Initialize the bean instance.
   Object exposedObject = bean;
   try {
      populateBean(beanName, mbd, instanceWrapper);
      exposedObject = initializeBean(beanName, exposedObject, mbd);
   }
   catch(Throwable ex) { .......... }...return exposedObject;
}
Copy the code

CreateBeanInstance (beanName, MBD, args); createBeanInstance(beanName, MBD, args); For example, through the final Object bean = instanceWrapper. GetWrappedInstance (); Get this comb out.

Now let’s look at the createBeanInstance method

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
   // Make sure bean class is actually resolved at this point.Class<? > beanClass = resolveBeanClass(mbd, beanName); . Supplier<? > instanceSupplier = mbd.getInstanceSupplier();if(instanceSupplier ! =null) {
      return obtainFromSupplier(instanceSupplier, beanName);
   }

   if(mbd.getFactoryMethodName() ! =null)  {
      returninstantiateUsingFactoryMethod(beanName, mbd, args); }...// Need to determine the constructor...Constructor<? >[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);if(ctors ! =null|| mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || ! ObjectUtils.isEmpty(args)) {return autowireConstructor(beanName, mbd, ctors, args);
   }
   // No special handling: simply use no-arg constructor.
   return instantiateBean(beanName, mbd);
}
Copy the code
@Nullable
publicSupplier<? > getInstanceSupplier() {return this.instanceSupplier;
}
Copy the code
protected BeanWrapper obtainFromSupplier(Supplier
        instanceSupplier, String beanName) {... Object instance; instance = instanceSupplier.get(); . BeanWrapper bw =new BeanWrapperImpl(instance);
   initBeanWrapper(bw);
   return bw;
}
Copy the code

As you can see, it will first generate an instance object through Supplier.

3) If the Supplier is not extended by the BeanDefinition. I’m going to determine if it has a FactoryMethodName, and I’m going to create the instance using the factory method.

if (mbd.getFactoryMethodName() ! = null) { return instantiateUsingFactoryMethod(beanName, mbd, args); }Copy the code
protected BeanWrapper instantiateUsingFactoryMethod(
      String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {

   return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
}
Copy the code
public BeanWrapper instantiateUsingFactoryMethod(
      final String beanName, final RootBeanDefinition mbd, @Nullable final Object[] explicitArgs) {

   BeanWrapperImpl bw = new BeanWrapperImpl();
   this.beanFactory.initBeanWrapper(bw); .try{ Object beanInstance; .else {
         beanInstance = this.beanFactory.getInstantiationStrategy().instantiate(
               mbd, beanName, this.beanFactory, factoryBean, factoryMethodToUse, argsToUse);
      }
      bw.setBeanInstance(beanInstance);
      returnbw; }... }Copy the code
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
      @Nullable Object factoryBean, final Method factoryMethod, @Nullable Object... args) {... Object result = factoryMethod.invoke(factoryBean, args);if (result == null) {
            result = new NullBean();
         }
         returnresult; }... }Copy the code
<bean id="listInstance" class="org.springframework.beans.factory.xml.FactoryMethods"
     factory-method="listInstance"/>
Copy the code
private static List listInstance(a) {
   return Collections.EMPTY_LIST;
}
Copy the code

These are the processes that generate instances through the FactoryMethod method.

4) If it does not extend the factory method as well, then the constructor will formally generate the Bean instance. But there will be an extension interface.

(5), we first look at determineConstructorsFromBeanPostProcessors beanClass, beanName) method

@Nullable
protectedConstructor<? >[] determineConstructorsFromBeanPostProcessors(@NullableClass<? > beanClass, String beanName)throws BeansException {

   if(beanClass ! =null && hasInstantiationAwareBeanPostProcessors()) {
      for (BeanPostProcessor bp : getBeanPostProcessors()) {
         if (bp instanceofSmartInstantiationAwareBeanPostProcessor) { SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp; Constructor<? >[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);if(ctors ! =null) {
               returnctors; }}}}return null;
}
Copy the code
@Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
   Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
   this.beanPostProcessors.remove(beanPostProcessor);
   this.beanPostProcessors.add(beanPostProcessor);
   if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
      this.hasInstantiationAwareBeanPostProcessors = true;
   }
   if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
      this.hasDestructionAwareBeanPostProcessors = true; }}Copy the code

Can see here provides SmartInstantiationAwareBeanPostProcessor interface for your development to build a custom constructor. To call its determineCandidateConstructors method.

@Nullable
defaultConstructor<? >[] determineCandidateConstructors(Class<? > beanClass, String beanName)throws BeansException {

   return null;
}
Copy the code

6), if there is no use SmartInstantiationAwareBeanPostProcessor interface returns a custom constructor, you call instantiateBean (beanName, MBD) method to call itself a default constructor.

protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
   try {
      Object beanInstance;
      final BeanFactory parent = this;
      if(System.getSecurityManager() ! =null) {
         beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
               getInstantiationStrategy().instantiate(mbd, beanName, parent),
               getAccessControlContext());
      }
      else {
         beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
      }
      BeanWrapper bw = new BeanWrapperImpl(beanInstance);
      initBeanWrapper(bw);
      return bw;
   }
   catch (Throwable ex) {
      throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex); }}Copy the code
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
   // Don't override the class with CGLIB if no overrides.
   if(! bd.hasMethodOverrides()) { .........finalClass<? > clazz = bd.getBeanClass();if (clazz.isInterface()) {
               throw new BeanInstantiationException(clazz, "Specified class is an interface"); }... constructorToUse = clazz.getDeclaredConstructor(); .return BeanUtils.instantiateClass(constructorToUse);
   }
   else {
      // Must generate CGLIB subclass.
      returninstantiateWithMethodInjection(bd, beanName, owner); }}Copy the code

Here you can see if there is a way to rewrite, will be to produce the Bean through additional carding, namely CglibSubclassingInstantiationStrategy class, now we are in the midst of a SimpleInstantiationStrategy classes.

public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationStrategy {
Copy the code

4. Process summary

There are three main points at this stage to generate instance objects:

1) Generate instances through Supplier (if any custom extensions exist)

<factory-method> <factory-method> (if there is a custom extension)

3), by constructing methods: one is through SmartInstantiationAwareBeanPostProcessor interface to return the custom constructors, if there is no custom, via the default constructor to create the Bean instance.

Stage 3 (Extend instance properties & Instance modification)

1. Flow chart

2. Overall process

At this point, a Bean instance object without attribute assignment has been created through the previous second phase, and it is now time to populate the Bean’s attribute content.

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
      throws BeanCreationException {...finalObject bean = instanceWrapper.getWrappedInstance(); Class<? > beanType = instanceWrapper.getWrappedClass(); .// Allow post-processors to modify the merged bean definition.
   synchronized (mbd.postProcessingLock) {
      if(! mbd.postProcessed) {try {
            applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
         }
         catch (Throwable ex) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                  "Post-processing of merged bean definition failed", ex);
         }
         mbd.postProcessed = true; }}...// Initialize the bean instance.
   Object exposedObject = bean;
   try{ populateBean(beanName, mbd, instanceWrapper); exposedObject = initializeBean(beanName, exposedObject, mbd); }...// Register bean as disposable.
	try{ registerDisposableBeanIfNecessary(beanName, bean, mbd); }...return exposedObject;
}
Copy the code

1), applyMergedBeanDefinitionPostProcessors (MBD, beanType, beanName)

protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class
        beanType, String beanName) {
   for (BeanPostProcessor bp : getBeanPostProcessors()) {
      if (bp instanceofMergedBeanDefinitionPostProcessor) { MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp; bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName); }}}Copy the code

Can see here is to call * * * * postProcessMergedBeanDefinition MergedBeanDefinitionPostProcessor interface method to expand. This method has a RootBeanDefinition input, so you can use that RootBeanDefinition to manipulate some properties.

​ 2)、populateBean(beanName, mbd, instanceWrapper)

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {...if(! mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {for (BeanPostProcessor bp : getBeanPostProcessors()) {
         if (bp instanceof InstantiationAwareBeanPostProcessor) {
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            if(! ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { continueWithPropertyPopulation =false;
               break; }}}}if(! continueWithPropertyPopulation) {return; }...boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
   booleanneedsDepCheck = (mbd.getDependencyCheck() ! = RootBeanDefinition.DEPENDENCY_CHECK_NONE); .if (hasInstAwareBpps) {
         for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
               InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
               pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
               if (pvs == null) {
                  return;
               }
            }
         }
      }
     ........
    if(pvs ! =null) {
			// Set the attributes of bwapplyPropertyValues(beanName, mbd, bw, pvs); }}Copy the code

Can see here mainly through expanding InstantiationAwareBeanPostProcessor interface. Its postProcessAfterInstantiation method can determine to down to attribute assignment or not. If it can call its postProcessPropertyValues method again, this interface can operate the PropertyValues.

default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
   return true;
}
Copy the code
@Nullable
default PropertyValues postProcessPropertyValues( PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
   return pvs;
}
Copy the code

​ 3)、initializeBean(beanName, exposedObject, mbd)

This method initializes the Bean instance, essentially running some other extended interface. At this point, we’ve already assigned the corresponding property

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {... invokeAwareMethods(beanName, bean); } Object wrappedBean = bean;if (mbd == null| |! mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); }try {
      invokeInitMethods(beanName, wrappedBean, mbd);
   }
   catch (Throwable ex) {
      throw newBeanCreationException( (mbd ! =null ? mbd.getResourceDescription() : null),
            beanName, "Invocation of init method failed", ex);
   }
   if (mbd == null| |! mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); }return wrappedBean;
}
Copy the code

InvokeAwareMethods (Final String beanName, final Object bean)

private void invokeAwareMethods(final String beanName, final Object bean) {
   if (bean instanceof Aware) {
      if (bean instanceof BeanNameAware) {
         ((BeanNameAware) bean).setBeanName(beanName);
      }
      if (bean instanceof BeanClassLoaderAware) {
         ClassLoader bcl = getBeanClassLoader();
         if(bcl ! =null) { ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl); }}if (bean instanceof BeanFactoryAware) {
         ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this); }}}Copy the code

Here you can see the BeanNameAware, BeanClassLoaderAware, and BeanFactoryAware interfaces that handle extensions.

5), applyBeanPostProcessorsBeforeInitialization (wrappedBean, beanName)

@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
      throws BeansException {

   Object result = existingBean;
   for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
      Object current = beanProcessor.postProcessBeforeInitialization(result, beanName);
      if (current == null) {
         return result;
      }
      result = current;
   }
   return result;
}
Copy the code

Began to call the BeanPostProcessor interface postProcessBeforeInitialization method here.

@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
   return bean;
}
Copy the code

In this interface you can handle the Bean instance yourself.

​ 6)、invokeInitMethods(beanName, wrappedBean, mbd)

protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
      throws Throwable {

   boolean isInitializingBean = (bean instanceof InitializingBean);
   if (isInitializingBean && (mbd == null| |! mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {...else{ ((InitializingBean) bean).afterPropertiesSet(); }}if(mbd ! =null&& bean.getClass() ! = NullBean.class) { String initMethodName = mbd.getInitMethodName();if(StringUtils.hasLength(initMethodName) && ! (isInitializingBean &&"afterPropertiesSet".equals(initMethodName)) && ! mbd.isExternallyManagedInitMethod(initMethodName)) { invokeCustomInitMethod(beanName, bean, mbd); }}}Copy the code
protected void invokeCustomInitMethod(String beanName, final Object bean, RootBeanDefinition mbd)
      throws Throwable { String initMethodName = mbd.getInitMethodName(); .else {
      try{ ReflectionUtils.makeAccessible(initMethod); initMethod.invoke(bean); . }}Copy the code

This is to run initMethod, which can be extended using the InitializingBean interface or handled with the

tag (also equivalent to the @postconstruct annotation). Note that the name of init-method cannot be afterPropertiesSet, which means it cannot have the same name as the method of the InitializingBean interface, otherwise you cannot run custom init-method methods.

7), applyBeanPostProcessorsAfterInitialization (wrappedBean, beanName)

@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
      throws BeansException {

   Object result = existingBean;
   for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
      Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
      if (current == null) {
         return result;
      }
      result = current;
   }
   return result;
}
Copy the code

Can be seen in by running Aware interface – > BeanPostProcessor interface postProcessBeforeInitialization () – > InitializingBean interface, It will go to the last call the BeanPostProcessor interface postProcessAfterInitialization ().

(8), registerDisposableBeanIfNecessary beanName, bean, MBD)

protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) { AccessControlContext acc = (System.getSecurityManager() ! =null ? getAccessControlContext() : null);
   if(! mbd.isPrototype() && requiresDestruction(bean, mbd)) {if (mbd.isSingleton()) {
         // Register a DisposableBean implementation that performs all destruction
         // work for the given bean: DestructionAwareBeanPostProcessors,
         // DisposableBean interface, custom destroy method.
         registerDisposableBean(beanName,
               new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
      }
Copy the code
public static boolean hasApplicableProcessors(Object bean, List<BeanPostProcessor> postProcessors) {
   if(! CollectionUtils.isEmpty(postProcessors)) {for (BeanPostProcessor processor : postProcessors) {
         if (processor instanceof DestructionAwareBeanPostProcessor) {
            DestructionAwareBeanPostProcessor dabpp = (DestructionAwareBeanPostProcessor) processor;
            if (dabpp.requiresDestruction(bean)) {
               return true; }}}}return false;
}
Copy the code
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {...public void registerDisposableBean(String beanName, DisposableBean bean) {
     synchronized (this.disposableBeans) {
       this.disposableBeans.put(beanName, bean); }}Copy the code

Finally here can also DestructionAwareBeanPostProcessor interface to determine its need to be added to the disposableBeans.

At this point, the creation of the Bean instance is complete.

Let’s look at Bean destruction

V. Stage IV (Destruction)

1, add to disposableBeans stage judgment

About the destruction of Bean, it is useful to the upper DestructionAwareBeanPostProcessor interface, but its InitDestroyAnnotationBeanPostProcessor interface is used to management, We have this method above for requiresDestruction(Object Bean, RootBeanDefinition MBD) to determine whether it needs to be added to disposableBeans.

protected boolean requiresDestruction(Object bean, RootBeanDefinition mbd) {
   return(bean.getClass() ! = NullBean.class && (DisposableBeanAdapter.hasDestroyMethod(bean, mbd) || (hasDestructionAwareBeanPostProcessors() && DisposableBeanAdapter.hasApplicableProcessors(bean, getBeanPostProcessors())))); }Copy the code

You can see that it has three or conditions:

1) One is to judge whether to implement the DisposableBean interface

public static boolean hasDestroyMethod(Object bean, RootBeanDefinition beanDefinition) {
   if (bean instanceof DisposableBean || bean instanceof AutoCloseable) {
      return true; }... }Copy the code
public static boolean hasApplicableProcessors(Object bean, List<BeanPostProcessor> postProcessors) {
   if(! CollectionUtils.isEmpty(postProcessors)) {for (BeanPostProcessor processor : postProcessors) {
         if (processor instanceof DestructionAwareBeanPostProcessor) {
            DestructionAwareBeanPostProcessor dabpp = (DestructionAwareBeanPostProcessor) processor;
            if (dabpp.requiresDestruction(bean)) {
               return true; }}}}return false;
}
Copy the code
public class InitDestroyAnnotationBeanPostProcessor
		implements DestructionAwareBeanPostProcessor.MergedBeanDefinitionPostProcessor.PriorityOrdered.Serializable {...@Override
	public boolean requiresDestruction(Object bean) {
   	return findLifecycleMetadata(bean.getClass()).hasDestroyMethods();
	}
Copy the code

2), the second is through InitDestroyAnnotationBeanPostProcessor rewrite requiresDestruction method.

public boolean hasDestroyMethods(a) {
   Collection<LifecycleElement> checkedDestroyMethods = this.checkedDestroyMethods; Collection<LifecycleElement> destroyMethodsToUse = (checkedDestroyMethods ! =null ? checkedDestroyMethods : this.destroyMethods);
   return! destroyMethodsToUse.isEmpty(); }Copy the code
private class LifecycleMetadata {...private final Collection<LifecycleElement> initMethods;
   private finalCollection<LifecycleElement> destroyMethods; .public LifecycleMetadata(Class
        targetClass, Collection
       
         initMethods, Collection
        
          destroyMethods)
        
        {

      this.targetClass = targetClass;
      this.initMethods = initMethods;
      this.destroyMethods = destroyMethods;
   }
Copy the code

This class also has initMethods.

private LifecycleMetadata buildLifecycleMetadata(finalClass<? > clazz) {... ReflectionUtils.doWithLocalMethods(targetClass, method -> {if(initAnnotationType ! =null) {
            if(method.getAnnotation(initAnnotationType) ! =null) {
               LifecycleElement element = newLifecycleElement(method); currInitMethods.add(element); . }if(destroyAnnotationType ! =null) {
            if(method.getAnnotation(destroyAnnotationType) ! =null) {... }}); initMethods.addAll(0, currInitMethods); destroyMethods.addAll(currDestroyMethods); .return new LifecycleMetadata(clazz, initMethods, destroyMethods);
}
Copy the code
public CommonAnnotationBeanPostProcessor(a) {
   setOrder(Ordered.LOWEST_PRECEDENCE - 3);
   setInitAnnotationType(PostConstruct.class);
   setDestroyAnnotationType(PreDestroy.class);
   ignoreResourceType("javax.xml.ws.WebServiceContext");
}
Copy the code
public void setInitAnnotationType(Class<? extends Annotation> initAnnotationType) {
   this.initAnnotationType = initAnnotationType;
}
public void setDestroyAnnotationType(Class<? extends Annotation> destroyAnnotationType) {
   this.destroyAnnotationType = destroyAnnotationType;
}
Copy the code

This is the destroy-method method.

2. Destruction stage

public void destroySingletons(a) {
   synchronized (this.singletonObjects) {
      this.singletonsCurrentlyInDestruction = true;
   }
   String[] disposableBeanNames;
   synchronized (this.disposableBeans) {
      disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
   }
   for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
      destroySingleton(disposableBeanNames[i]);
   }
Copy the code

You can see that you are going through the Bean instance that you added to disposableBeans earlier, and then destroying it using the destroySingleton method.

public void destroySingleton(String beanName) {...synchronized (this.disposableBeans) {
      disposableBean = (DisposableBean) this.disposableBeans.remove(beanName);
   }
   destroyBean(beanName, disposableBean);
}
Copy the code
protected void destroyBean(String beanName, @Nullable DisposableBean bean) {...// Actually destroy the bean now...
   if(bean ! =null) {
      try{ bean.destroy(); }... }Copy the code

And here we can see it’s gonna be forced to DisposableBean, because if you have destroy-Method alone that doesn’t have an interface it’s already been handled and in order to DisposableBeanAdapter, the adapter mode is used.

At this point, some of the interfaces involved in the entire singleton Bean creation and destruction process are combed out.