源碼通透-sprin-IOC-Bean的完整生命週期

Bean的完整生命週期


spring源碼版本:spring5.0
JDK版本: 1.8
我保存的源碼地址:https://gitee.com/paincupid/spring-framework.git
或者官網地址:https://github.com/spring-projects/spring-framework.git
更多源碼文章:https://github.com/arthur-dy-lee/arthur-dy-lee-note

一、生命週期順序


bean的生命週期

1、在IOC容器中,一個spring bean是通過類的構造器(class constractor)生成的

2、使用setter方法執行依賴注入

3、一旦依賴注入完成, BeanNameAware.setBeanName()被調用。在創建它的bean factory中,該bean的名字被設置

4、調用BeanClassLoaderAware.setBeanClassLoader(ClassLoader classLoader)BeanClassLoaderAware用於獲取Bean的類裝載器(即當前bean factory加載bean類使用的class loader)的回調類

5、BeanFactoryAware.setBeanFactory() BeanFactoryAware實現此接口的bean可以獲取到它們自己的Beanfactory

6、IOC容器調用BeanPostProcessor.postProcessBeforeInitialization

7、調用@PostConstruct

8、InitializingBean.afterPropertiesSet()

9、在xml文件中定義的 init-method

10、BeanPostProcessor.postProcessAfterInitialization()

11、bean實例已經準備好使用了。使用bean執行任務。

12、當ApplicationContext關閉時,比如使用registerShutdownHook(),然後調用帶有``@PreDestroy`銷燬註釋的方法。

13、調用DisposableBean.destroy()

14、調用在xml中定義的 destroy-method 方法

15、在垃圾回收之前,finalize()方法被調用

下面是英文原文

A bean life cycle includes the following steps. 

1. Within IoC container, a spring bean is created using class constructor. 
2. Now the dependency injection is performed using setter method. 
3. Once the dependency injection is completed, `BeanNameAware.setBeanName()` is called. It sets the name of bean in the bean factory that created this bean. 
4. Now `BeanClassLoaderAware.setBeanClassLoader()` is called that supplies the bean class loader to a bean instance. 
5. Now `BeanFactoryAware.setBeanFactory()` is called that provides the owning factory to a bean instance. 
6. Now the IoC container calls `BeanPostProcessor.postProcessBeforeInitialization` on the bean. Using this method a wrapper can be applied on original bean. 
7. Now the method annotated with `@PostConstruct` is called. 
8. After `@PostConstruct`, the method `InitializingBean.afterPropertiesSet()` is called. 
9. Now the method specified by `init-method` attribute of bean in XML configuration is called. 
10. And then `BeanPostProcessor.postProcessAfterInitialization()` is called. It can also be used to apply wrapper on original bean. 
11. Now the bean instance is ready to be used. Perform the task using the bean. 
12. Now when the ApplicationContext shuts down such as by using registerShutdownHook() then the method annotated with @PreDestroy is called. 
13. After that `DisposableBean.destroy()` method is called on the bean. 
14. Now the method specified by `destroy-method` attribute of bean in XML configuration is called. 
15. Before garbage collection, `finalize()` method of Object is called

二、Bean的完整生命週期經歷了各種方法調用,這些方法可以劃分爲以下幾類


1、Bean自身的方法:
這個包括了Bean本身調用的方法和通過配置文件中<bean>init-methoddestroy-method指定的方法

2、Bean級生命週期接口方法:
這個包括了BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean這些接口的方法

3、容器級生命週期接口方法:
這個包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 這兩個接口實現,一般稱它們的實現類爲“後處理器”。

4、工廠後處理器接口方法:
這個包括了AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer等等非常有用的工廠後處理器  
接口的方法。工廠後處理器也是容器級的。在應用上下文裝配配置文件之後立即調用。

三、AbstractAutowireCapableBeanFactory#createBean

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
    throws BeanCreationException {
    //...
    try {
        // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
        //給BeanPostProcessors一個機會,返回代理對象替代目前bean實例。
        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
        if (bean != null) {
            return bean;
        }
    }//....
    try {
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        //....
        return beanInstance;
    }//....
}

3.1 AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation

BeanPostProcessors一個機會,返回代理對象替代目前bean實例。beanPostProcessor是可以臨時修改bean的,它的優先級高於正常實例化bean的,如果beanPostProcessor能返回,則直接返回了。

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;
}

3.1.1 AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInstantiation

調用InstantiationAwareBeanPostProcessors.postProcessBeforeInstantiation()

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) {
				return result;
			}
		}
	}
	return null;
}

AbstractAutoProxyCreator實現了BeanPostProcessor接口,BeanPostProcessor主要作用於Bean實例化後,初始化前後,所有的Bean都被作用到。InstantiationAwareBeanPostProcessor雖然是BeanPostProcessor的子接口,但它的調用時間點發生在Bean實例化前,在真正調用doCreateBean()創建bean實例之前執行postProcessBeforeInstantiation()

AbstractAutoProxyCreator#postProcessBeforeInstantiation爲自定義的TargetSource 我的做代理

public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
    //1、得到一個緩存的唯一key(根據beanClass和beanName生成唯一key)
    Object cacheKey = getCacheKey(beanClass, beanName);
    //2、如果當前targetSourcedBeans(通過自定義TargetSourceCreator創建的TargetSource)不包含cacheKey 
    if (beanName == null || !this.targetSourcedBeans.containsKey(beanName)) {
        //2.1、advisedBeans(已經被增強的Bean,即AOP代理對象)中包含當前cacheKey,返回null,即走Spring默認流程  
        if (this.advisedBeans.containsKey(cacheKey)) {
            return null;
        }
        //2.2、如果是基礎設施類(如Advisor、Advice、AopInfrastructureBean的實現)不進行處理  
        //2.2、shouldSkip 默認false,可以生成子類覆蓋,如AspectJAwareAdvisorAutoProxyCreator覆蓋(if (((AbstractAspectJAdvice) advisor.getAdvice()).getAspectName().equals(beanName)) return true;  即如果是自己就跳過)  
        if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return null;
        }
    }

    //3、開始創建AOP代理對象  
    if (beanName != null) {
        //3.1、配置自定義的TargetSourceCreator進行TargetSource創建 
        TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
        //3.2、如果targetSource不爲null 添加到targetSourcedBeans緩存,並創建AOP代理對象
        if (targetSource != null) {
            this.targetSourcedBeans.put(beanName, Boolean.TRUE);
            // specificInterceptors即增強(包括前置增強、後置增強等等)  
            Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
            //3.3、創建代理對象  
            Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
            //3.4、將代理類型放入proxyTypes從而允許後續的predictBeanType()調用獲取  
            this.proxyTypes.put(cacheKey, proxy.getClass());
            return proxy;
        }
    }
    return null;
}

所謂的customTargetSourceCreators屬性是在AbstractAutoProxyCreator中的一個TargetSourceCreator數組,用來對代理對象target的封裝類TargetSource的生成進行自定義。spring內置的TargetSourceCreator有兩個:LazyInitTargetSourceCreator和QuickTargetSourceCreator。

  • LazyInitTargetSourceCreator:創建的代理對象並沒有初始化,直到第一次調用時才進行初始化
  • QuickTargetSourceCreator:根據beanName的不同前綴創建三種常用的TargetSource類型(bean必須爲多例)
    1. CommonsPoolTargetSource:池化TargetSource,每次執行方法時從池中取代理對象,執行完方法再返回池中
    2. ThreadLocalTargetSource:線程級的TargetSource
    3. PrototypeTargetSource:多例TargetSource,每次執行方法創建新的代理對象,執行完銷燬該對象

3.1.2 BeanPostProcessor#postProcessAfterInitialization

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;
}

3.2 AbstractAutowireCapableBeanFactory#doCreateBean

實際創建指定的bean。預創建處理已經發生。此時,例如檢查{@code postprocessbeforeinstances}回調。

和默認bean實例化不同,doCreateBean使用factory methodand autowiring a constructor

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)throws BeanCreationException {
   // Instantiate the bean.
   BeanWrapper instanceWrapper = null;
   if (mbd.isSingleton()) {
      instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
   }
   if (instanceWrapper == null) {
      //-----> 3.2.1 
      instanceWrapper = createBeanInstance(beanName, mbd, args);
   }
   final Object bean = instanceWrapper.getWrappedInstance();
   Class<?> beanType = instanceWrapper.getWrappedClass();
   if (beanType != NullBean.class) {
      mbd.resolvedTargetType = beanType;
   }

   // Allow post-processors to modify the merged bean definition.
   synchronized (mbd.postProcessingLock) {
      if (!mbd.postProcessed) {
         try {
            applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
         }//....
         mbd.postProcessed = true;
      }
   }

   // Eagerly cache singletons to be able to resolve circular references
   // even when triggered by lifecycle interfaces like BeanFactoryAware.
   boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
         isSingletonCurrentlyInCreation(beanName));
   if (earlySingletonExposure) {
      //....
      addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
   }

   // Initialize the bean instance.
   Object exposedObject = bean;
   try {
      populateBean(beanName, mbd, instanceWrapper);
      //----> 3.2.2 initializeBean 
      exposedObject = initializeBean(beanName, exposedObject, mbd);
   }//....

   if (earlySingletonExposure) {
      Object earlySingletonReference = getSingleton(beanName, false);
      if (earlySingletonReference != null) {
         if (exposedObject == bean) {
            exposedObject = earlySingletonReference;
         }
         else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
            String[] dependentBeans = getDependentBeans(beanName);
            Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
            for (String dependentBean : dependentBeans) {
               if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                  actualDependentBeans.add(dependentBean);
               }
            }//....
         }
      }
   }

   // Register bean as disposable.
   try {
      registerDisposableBeanIfNecessary(beanName, bean, mbd);
   }//...
   return exposedObject;
}

3.2.1 AbstractAutowireCapableBeanFactory#createBeanInstance

創建指定的bean實例,採用合適的實例創建策略:factory method, constructor autowiring, or simple instantiation.

/**
 * Create a new instance for the specified bean, using an appropriate instantiation strategy:
 * factory method, constructor autowiring, or simple instantiation.
 */	 
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);

   if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
      throw new BeanCreationException(mbd.getResourceDescription(), beanName,
            "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
   }

   Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
   if (instanceSupplier != null) {
      return obtainFromSupplier(instanceSupplier, beanName);
   }

   if (mbd.getFactoryMethodName() != null)  {
      return instantiateUsingFactoryMethod(beanName, mbd, args);
   }

   // Shortcut when re-creating the same bean...
   boolean resolved = false;
   boolean autowireNecessary = false;
   if (args == null) {
      synchronized (mbd.constructorArgumentLock) {
         if (mbd.resolvedConstructorOrFactoryMethod != null) {
            resolved = true;
            autowireNecessary = mbd.constructorArgumentsResolved;
         }
      }
   }
   if (resolved) {
      if (autowireNecessary) {
         return autowireConstructor(beanName, mbd, null, null);
      }
      else {
         return instantiateBean(beanName, mbd);
      }
   }

   // 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);
}

3.2.2 AbstractAutowireCapableBeanFactory#initializeBean

調用BeanNameAware.setBeanName()

調用BeanClassLoaderAware.setBeanClassLoader()

調用BeanFactoryAware.setBeanFactory()

調用BeanPostProcessor.postProcessBeforeInitialization

調用 InitializingBean.afterPropertiesSet()和自定義的init()方法

調用 BeanPostProcessor.postProcessAfterInitialization

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
   if (System.getSecurityManager() != null) {
      AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
         invokeAwareMethods(beanName, bean);
         return null;
      }, getAccessControlContext());
   }
   else {
      // 初始化BeanNameAware、BeanClassLoaderAware、BeanFactoryAware  <---------------- 
      invokeAwareMethods(beanName, bean);
   }

   Object wrappedBean = bean;
   if (mbd == null || !mbd.isSynthetic()) {
      //調用BeanPostProcessor.postProcessBeforeInitialization 
      wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
   }

   try {
      //調用 InitializingBean.afterPropertiesSet()和自定義的init方法
      invokeInitMethods(beanName, wrappedBean, mbd);
   }//....
   if (mbd == null || !mbd.isSynthetic()) {
      //調用 BeanPostProcessor.postProcessAfterInitialization
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
   }

   return wrappedBean;
}
3.2.2.1 AbstractAutowireCapableBeanFactory#invokeAwareMethods

調用aware方法:

調用BeanNameAware.setBeanName()

調用BeanClassLoaderAware.setBeanClassLoader()

調用BeanFactoryAware.setBeanFactory()

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);
      }
   }
}
3.2.2.2 AbstractAutowireCapableBeanFactory#invokeInitMethods

給屬性賦值,即查看是否bean實現了InitializingBean,或者定義了intit方法,然後調用他們。

/**
  * Give a bean a chance to react now all its properties are set,
  * and a chance to know about its owning bean factory (this object).
  * This means checking whether the bean implements InitializingBean or defines
  * a custom init method, and invoking the necessary callback(s) if it does.
  */ 
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"))) {
      //....
      if (System.getSecurityManager() != null) {
         try {
            //調用InitializingBean.afterPropertiesSet() 
            AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
               ((InitializingBean) bean).afterPropertiesSet();
               return null;
            }, getAccessControlContext());
         }//...
      }
      else {
          //調用InitializingBean.afterPropertiesSet()
         ((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)) {
         //調用自定義的init方法
         invokeCustomInitMethod(beanName, bean, mbd);
      }
   }
}

現在已經找到了 這7個的調用順序:

1、BeanNameAware.setBeanName()

2、調用BeanClassLoaderAware.setBeanClassLoader()

3、調用BeanFactoryAware.setBeanFactory()

4、BeanPostProcessor.postProcessBeforeInitialization

5、<------

6、InitializingBean.afterPropertiesSet()

7、init()方法

8、 BeanPostProcessor.postProcessAfterInitialization

那麼 @PostConstruct是什麼時候被調用的呢?

3.3 CommonAnnotationBeanPostProcessor(@PostConstruct調用時機)

CommonAnnotationBeanPostProcessor繼承InitDestroyAnnotationBeanPostProcessorInitDestroyAnnotationBeanPostProcessor實現了 MergedBeanDefinitionPostProcessor 接口,MergedBeanDefinitionPostProcessor繼承了BeanPostProcessor,在調用 BeanPostProcessor.postProcessBeforeInitialization時,會調用@PostConstruct

繼承關係如下圖所示:

3.3.1 CommonAnnotationBeanPostProcessor裝入PostConstruct.class

CommonAnnotationBeanPostProcessor功能

它是BeanPostProcessor的實現類,支持通用的java註解開箱即用,尤其是在java.annotation包下的註解類。

CommonAnnotationBeanPostProcessor包括支持javax.annotation.PostConstructjavax.annotation.PreDestroy註解。

annotation-driven的中心元素是`javax.annotation.Resource,@Resource默認按照名稱方式進行bean匹配。

本文主要是找@PostConstruct,下面是部分實現代碼:

在 PostConstruct 構造中將PostConstruct.class賦值給initAnnotationType,才便調用BeanPostProcessor#postProcessBeforeInitialization

public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor
		implements InstantiationAwareBeanPostProcessor, BeanFactoryAware, Serializable {
    /**
	 * Create a new CommonAnnotationBeanPostProcessor,
	 * with the init and destroy annotation types set to
	 * {@link javax.annotation.PostConstruct} and {@link javax.annotation.PreDestroy},
	 * respectively.
	 */
	public F() {
		setOrder(Ordered.LOWEST_PRECEDENCE - 3);
		setInitAnnotationType(PostConstruct.class);
		setDestroyAnnotationType(PreDestroy.class);
		ignoreResourceType("javax.xml.ws.WebServiceContext");
	}
}

3.3.1 InitDestroyAnnotationBeanPostProcessor#postProcessBeforeInitialization

postProcessBeforeInitialization->findLifecycleMetadata->buildLifecycleMetadata->initAnnotationType中找@PostConstruct

public class InitDestroyAnnotationBeanPostProcessor
      implements DestructionAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor, PriorityOrdered, Serializable {
    @Nullable
	private Class<? extends Annotation> initAnnotationType;
    
    /**
	 * Specify the init annotation to check for, indicating initialization
	 * methods to call after configuration of a bean.
	 * <p>Any custom annotation can be used, since there are no required
	 * annotation attributes. There is no default, although a typical choice
	 * is the JSR-250 {@link javax.annotation.PostConstruct} annotation.
	 */
	public void setInitAnnotationType(Class<? extends Annotation> initAnnotationType) {
		this.initAnnotationType = initAnnotationType;
	}
    
    @Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
		try {
			metadata.invokeInitMethods(bean, beanName);
		}//...
		return bean;
	}
    
    private LifecycleMetadata findLifecycleMetadata(Class<?> clazz) {
		if (this.lifecycleMetadataCache == null) {
			// Happens after deserialization, during destruction...
			return buildLifecycleMetadata(clazz);
		}// ...
    }
    
    private LifecycleMetadata buildLifecycleMetadata(final Class<?> clazz) {
		final boolean debug = logger.isDebugEnabled();
		LinkedList<LifecycleElement> initMethods = new LinkedList<>();
		LinkedList<LifecycleElement> destroyMethods = new LinkedList<>();
		Class<?> targetClass = clazz;

		do {
			final LinkedList<LifecycleElement> currInitMethods = new LinkedList<>();
			final LinkedList<LifecycleElement> currDestroyMethods = new LinkedList<>();

			ReflectionUtils.doWithLocalMethods(targetClass, method -> {
                  //在initAnnotationType中找匹配的@PostConstruct
				if (this.initAnnotationType != null && method.isAnnotationPresent(this.initAnnotationType)) {
					LifecycleElement element = new LifecycleElement(method);
					currInitMethods.add(element);
					//..
				}
				if (this.destroyAnnotationType != null && method.isAnnotationPresent(this.destroyAnnotationType)) {
					currDestroyMethods.add(new LifecycleElement(method));
				}
			});

			initMethods.addAll(0, currInitMethods);
			destroyMethods.addAll(currDestroyMethods);
			targetClass = targetClass.getSuperclass();
		}
		while (targetClass != null && targetClass != Object.class);

		return new LifecycleMetadata(clazz, initMethods, destroyMethods);
	}
}

參考:

Spring Bean Life Cycle Tutorial

Spring Bean Life Cycle Explained

http://uule.iteye.com/blog/2094609

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章