二、浅析Spring Bean的生命周期(源码分析)

527 阅读7分钟

浅析Spring系列

一、浅析Spring启动流程

二、浅析Spring Bean的生命周期

三、浅析Spring循环依赖

四、浅析Spring事件

五、浅析Spring AOP

六、浅析Spring MVC


Spring Bean的生命周期

Bean的创建过程非常复杂,考虑到分析主流程为目的,因此本文会重点关注单例Bean的生命周期,以及穿插在过程中的接口处理(如BeanPostProcessor接口)。Bean的生命周期整体上可以分为四个阶段:

  1. 实例化:Instantiation
  2. 设置属性:Populate
  3. 初始化:Initialization
  4. 销毁:Destruction

0. 概述

Bean的创建入口在AbstracrBeanFactory的抽象方法createBean上,具体到代码会在AbstractAutowireCapableBeanFactory的doCreateBean方法上

//AbstractAutowireCapableBeanFactory#doCreateBean
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
      throws BeanCreationException {

   // 实例化bean
   BeanWrapper instanceWrapper = null;
   if (mbd.isSingleton()) {
      instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
   }
   if (instanceWrapper == null) {
      instanceWrapper = createBeanInstance(beanName, mbd, args);
   }
 
   // Initialize the bean instance.
   Object exposedObject = bean;
   // Bean属性赋值
   populateBean(beanName, mbd, instanceWrapper);
   // Bean初始化
   exposedObject = initializeBean(beanName, exposedObject, mbd);
  
   //注册销毁方法
   registerDisposableBeanIfNecessary(beanName, bean, mbd);
   return exposedObject;
}

1. 实例化 Instantiation

createBeanInstance方法内部有几种实例化方式:

  1. 通过Supplier接口
  2. 通过工厂方法(如:static方法创建)
  3. 通过构造器创建
  4. 通过无参构造器创建
//AbstractAutowireCapableBeanFactory#createBeanInstance
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);

   // 1. Supplier创建
   Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
   if (instanceSupplier != null) {
      return obtainFromSupplier(instanceSupplier, beanName);
   }
   // 2. 工厂方法创建
   if (mbd.getFactoryMethodName() != null) {
      return instantiateUsingFactoryMethod(beanName, mbd, args);
   }

   // 3. 构造器创建
   // Candidate constructors for autowiring?
   Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
   if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
         mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
      return autowireConstructor(beanName, mbd, ctors, args);
   }

   // Preferred constructors for default construction?
   ctors = mbd.getPreferredConstructors();
   if (ctors != null) {
      return autowireConstructor(beanName, mbd, ctors, null);
   }
   // 4. 无参构造器创建
   // No special handling: simply use no-arg constructor.
   return instantiateBean(beanName, mbd);
}

在instantiateBean中会通过实例化策略进行实例化:实例化可以是基于反射,也可以是CGLIB。

//AbstractAutowireCapableBeanFactory#instantiateBean
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
   
    Object beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
     
    BeanWrapper bw = new BeanWrapperImpl(beanInstance);
    initBeanWrapper(bw);
    return bw;
}

2. 设置属性 Populate

设置属性的内容比较多且复杂,此处关注主要流程即可。

2.1 依赖注入

此处主要考虑@Value、@Autoware这种方式的属性设置。

主要还是依赖BeanPostProcessor扩展来实现设置属性,子接口InstantiationAwareBeanPostProcessor会处理属性相关的内容,主要接口为postProcessProperties,而postProcessPropertyValues接口在Spring 5.1.x中被标记为废弃,就不重点分析。调用BeanPostProcessor逻辑如下:

//AbstractAutowireCapableBeanFactory#populateBean
for (BeanPostProcessor bp : getBeanPostProcessors()) java{
	if (bp instanceof InstantiationAwareBeanPostProcessor) {
		InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
		PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
		if (pvsToUse == null) {
			if (filteredPds == null) {
				filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
			}
			pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
			if (pvsToUse == null) {
				return;
			}
		}
		pvs = pvsToUse;
	}
}

默认情况下,存在以下几个InstantiationAwareBeanPostProcessor ,对应postProcessProperties逻辑如下

  • ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor:当Bean实现了EnhancedConfiguration接口,会注入BeanFactory实例。没有属性相关的逻辑
  • CommonAnnotationBeanPostProcessor:会处理@WebServiceRef、@EJB、@Resource这三个注解的注入。注入逻辑为构建InjectionMetadata(实际为WebServiceRefElement、EjbRefElement、ResourceElement三个不同的子类),然后调用inject方法。
  • AutowiredAnnotationBeanPostProcessor:会处理@Autowired、@Autowired、@javax.inject.Inject这三个注解的注入。注入逻辑为构建InjectionMetadata(实际为子类AutowiredFieldElement针对属性;AutowiredMethodElement针对方法),然后调用inject方法。

以下内容主要分析AutowiredFieldElement的inject方法实现:主要两个操作

  1. 通过BeanFactory解析依赖获取依赖的值。依赖解析内部较为负责,此处不深入分析。
  2. 通过反射设置属性值。
//AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement#inject
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
   Field field = (Field) this.member;
   Object value;
   DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
   desc.setContainingClass(bean.getClass());
   Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
   Assert.state(beanFactory != null, "No BeanFactory available");
   TypeConverter typeConverter = beanFactory.getTypeConverter();
   //通过BeanFactory解析依赖
   value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
   //通过反射设置属性
   if (value != null) {
      ReflectionUtils.makeAccessible(field);
      field.set(bean, value);
   }
}

2.2 属性设置

在populateBean方法内,如果PropertyValues对象不为空的情况下,还会进行属性设置,调用applyPropertyValues方法。主要有三个逻辑:

  1. 解析属性值:会有一些特殊的类进行判断,如:NullBean则直接返回null值。如果是字段串的话,会通过Expression进行解析。
  2. 类型转换:最终会调用到TypeConverterDelegate的convertIfNecessary方法中。在没有自定义PropertyEditor的情况下,会先用ConversionService进行转换。关于PropertyEditor、ConversionService本文不重点阐述,此处知道有该逻辑即可。
  3. 设置属性值:内部逻辑比较复杂,此处知道有该逻辑即可。
//AbstractAutowireCapableBeanFactory#applyPropertyValues
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
    //解析属性值
	Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
	//类型转换
	Object convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
	//设置属性
	bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}

3. 初始化 Initialization

3.1 执行Aware方法

按先后顺序,会分别调用BeanNameAware接口、BeanClassLoaderAware接口、BeanFactoryAware接口

//AbstractAutowireCapableBeanFactory#initializeBean
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    invokeAwareMethods(beanName, bean);  
}
//AbstractAutowireCapableBeanFactory#invokeAwareMethods
private void invokeAwareMethods(String beanName, 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 调用BeanPostProcessor接口postProcessBeforeInitialization方法

此为Bean的扩展机制,可以通过该方法把Bean的实例给替换。而Spring内部更是通过此接口来扩展一些功能,内置的BeanPostProcessor及功能如下:

  • ApplicationContextAwareProcessor:Aware接口调用,调用顺序如下:EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware
  • ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor:调用ImportAware接口
  • PostProcessorRegistrationDelegrate$BeanPostProcessorChecker:不处理
  • CommonAnnotationBeanPostProcessor:调用@PostConstruct注解方法
  • AutowiredAnnotationBeanPostProcessor:不处理
  • ApplicationListenerDetector:不处理
//AbstractAutowireCapableBeanFactory#initializeBean
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
	Object wrappedBean = bean;
	if (mbd == null || !mbd.isSynthetic()) {
		wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
	}
}
//AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
      throws BeansException {

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

3.3 调用init方法

会先调用InitializingBean接口的afterPropertiesSet方法

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

   boolean isInitializingBean = (bean instanceof InitializingBean);
   if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
         ((InitializingBean) bean).afterPropertiesSet();  
   }
}

然后再调用自定义初始化方法

//AbstractAutowireCapableBeanFactory#invokeInitMethods
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd){

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

会先获取初始化方法Method,然后设置可访问,最后通过反射进行调用

//AbstractAutowireCapableBeanFactory#invokeCustomInitMethod
protected void invokeCustomInitMethod(String beanName, Object bean, RootBeanDefinition mbd)
      throws Throwable {

   String initMethodName = mbd.getInitMethodName();
   Assert.state(initMethodName != null, "No init method set");
   Method initMethod = (mbd.isNonPublicAccessAllowed() ?
         BeanUtils.findMethod(bean.getClass(), initMethodName) :
         ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));

   if (initMethod == null) {
      if (mbd.isEnforceInitMethod()) {
         throw new BeanDefinitionValidationException("Could not find an init method named '" +
               initMethodName + "' on bean with name '" + beanName + "'");
      }
         return;
      }
   }
  
   Method methodToInvoke = ClassUtils.getInterfaceMethodIfPossible(initMethod);

   ReflectionUtils.makeAccessible(methodToInvoke);
   methodToInvoke.invoke(bean);
}

3.4 调用BeanPostProcessor接口postProcessAfterInitialization方法

此为Bean的扩展机制,可以通过该方法把Bean的实例给替换。Spring内部也通过此机制扩展一些功能

  • ApplicationContextAwareProcessor:不处理
  • ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor:不处理
  • PostProcessorRegistrationDelegrate$BeanPostProcessorChecker:BeanPostProcessor检查,检测bean在所有BeanPostProcess实例化进行创建
  • CommonAnnotationBeanPostProcessor:不处理
  • AutowiredAnnotationBeanPostProcessor:不处理
  • ApplicationListenerDetector:将实现ApplicationListener接口的bean,添加到ApplicationContext里。
//AbstractAutowireCapableBeanFactory#initializeBean
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
	if (mbd == null || !mbd.isSynthetic()) {
		wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
	}
}
//AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
      throws BeansException {

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

4. 销毁 Destruction

4.1 注册销毁类

单例bean在创建的时候,会注册销毁类,便于在销毁的时候调用。销毁类用DisposableBeanAdapter适配,内部会调用真正的bean回调

//AbstractBeanFactory#registerDisposableBeanIfNecessary
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
   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.
		 //注册销毁bean
         registerDisposableBean(beanName,
               new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
      }else {
         // A bean with a custom scope...
         Scope scope = this.scopes.get(mbd.getScope());
         if (scope == null) {
            throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
         }
         scope.registerDestructionCallback(beanName,
               new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
      }
   }
}

触发单例bean执行销毁,在ConfigurableApplicationContext的close方法中。或者执行ShutdownHook(前提是有注册ShutdownHook),内部会调用destroyBeans,最终会在BeanFactory调用destroySingletons方法,内部又会调用destroyBean方法。

核心关注DisposableBean的destroy方法,根据前面注册,可以得知,它实际上就是DisposableBeanAdapter的destroy方法

protected void destroyBean(String beanName, @Nullable DisposableBean bean) {

   // Actually destroy the bean now...
   if (bean != null) {
      try {
         bean.destroy();
      }
      catch (Throwable ex) {
         if (logger.isWarnEnabled()) {
            logger.warn("Destruction of bean with name '" + beanName + "' threw an exception", ex);
         }
      }
   }
}

内部执行销毁方法分三部分,分别是:@PreDestory注解、DisposableBean接口和自定义销毁方法

4.2 执行@PreDestory

@PreDestory注解是通过BeanPostProcessor处理,实际就是CommonAnnotationBeanPostProcessor。

//DisposableBeanAdapter#destroy
public void destroy() {
   if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
      for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
         processor.postProcessBeforeDestruction(this.bean, this.beanName);
      }
   }
}

实际执行的方法是InitDestroyAnnotationBeanPostProcessor#postProcessBeforeDestruction,内部会通过封装的LifecycleMetadata类调用销毁方法。

//InitDestroyAnnotationBeanPostProcessor#postProcessBeforeDestruction
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
   LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
   metadata.invokeDestroyMethods(bean, beanName);java
}

4.3 执行DisposableBean接口

内部直接转DisposableBean接口,调用其destroy方法

//DisposableBeanAdapter#destroy
public void destroy() {
	((DisposableBean) this.bean).destroy();
}

4.4 执行自定义销毁方法

如果已经在构造器的时候获取了destroyMethod则直接调用;如果destroyMethodName 不为空,则尝试获取销毁的Method

//DisposableBeanAdapter#destroy
public void destroy() {
	if (this.destroyMethod != null) {
			invokeCustomDestroyMethod(this.destroyMethod);
		}
	else if (this.destroyMethodName != null) {
		Method methodToInvoke = determineDestroyMethod(this.destroyMethodName);
		if (methodToInvoke != null) {
				invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke));
		}
	}
}

在具体执行中,或先让该方法可以访问,然后通过反射,调用该自定义方法。

//DisposableBeanAdapter#invokeCustomDestroyMethod
private void invokeCustomDestroyMethod(final Method destroyMethod) {
    ReflectionUtils.makeAccessible(destroyMethod);
    destroyMethod.invoke(this.bean, args);

}

5. 参考链接