Spring单例Bean生命周期源码解析和循环依赖解决

文章目录

  • Bean概述
  • Bean加载
    • AbstractBeanFactory
      • getSingleton方法
      • createBean方法
  • Bean创建
    • createBean方法
      • 实例化前置处理阶段
    • doCreateBean方法
      • 实例化Bean阶段
        • 实例化策略(策略模式)
          • 策略接口定义
          • 简单实例化策略实现
          • Cglib实例化策略实现
      • RootBeanDefinition加工
      • 循环依赖解决
        • 循环依赖案例
        • 两个缓存能否解决循环依赖
    • populateBean方法
      • 实例化后置处理阶段
      • 属性赋值前阶段
      • 属性赋值阶段
    • initializeBean方法
      • Aware接口的回调
      • 初始化前置处理阶段
      • 初始化方法回调
        • Bean初始化执行顺序
      • 初始化后置处理器阶段
    • 注册销毁Bean方法
  • Bean初始化完成阶段
  • Bean销毁
    • Bean销毁前执行顺序
  • 总结
    • Bean生命周期扩展总结
    • 用一张图描述Bean生命周期过程

Bean概述

Spring 底层 IoC 容器默认实现类是 DefaultListableBeanFactory,该类继承层级如下。
Spring单例Bean生命周期源码解析和循环依赖解决_第1张图片

  • 顶层接口BeanFactory 是 Spring 底层 IoC 容器,提供依赖查找单个 Bean 的功能。
  • 抽象类AbstractBeanFactory基础实现类,Bean 的创建过程交其由子类实现。
  • AbstractAutowireCapableBeanFactory 抽象类,继承 AbstractBeanFactory,实现 AutowireCapableBeanFactory 接口,完成 Bean 的创建过程。

注意:我们在阅读源码重要理解其设计思想。所以当我阅读源码时,忽略很多对异常的处理,这样更关注源码核心功能。

Bean加载

AbstractBeanFactory

BeanFactory 的基础实现类,实现BeanFactory接口依赖查找方法来获取 Bean 对象。通过名字获取Bean的方法实现如下:

package org.springframework.beans.factory.support;

public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
    ...
    //通过beanName获取Bean实例对象 
    @Override
	public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);
	}
    ...     
}

该方法有很多重载,最终都会调用doGetBean方法,用于获取Bean对象核心实现。方法如下:

//AbstractBeanFactory类
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, 
  @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
  ...
  //我们只关心加载bean核心代码,开始创建 Bean,不同模式创建方式不同      
  if (mbd.isSingleton()) { //单例模式创建Bean
	 sharedInstance = getSingleton(beanName, () -> {
	   try {
			 return createBean(beanName, mbd, args);
		  } catch (BeansException ex) {					 
			destroySingleton(beanName);
			throw ex;
		  }
	   });
	   bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
	}
    //此处给忽略,更多关注对单例bean处理,详情看Spring源码。
    else if (mbd.isPrototype()) { //原型模式创建bean
        .... 
    }else{ // 其它模式创建Bean
        ....
    }
    ...
}

首先会从缓存中Bean,如果没有对应的 Bean,根据不同模式开启创建Bean对象,最终都会调用createBean方法创建Bean,主要区别是存储范围不同。

  • 单例模式。一个 BeanFactory容器中有且仅有一个实例。
  • 原型模式。每次依赖查找和依赖注入生成新 Bean 对象。
  • 其它模式如下:
    1. request 作用域会将 Bean 存储在 ServletRequest 上下文中;
    2. session 作用域会将 Bean 存储在 HttpSession 中;
    3. application 作用域会将 Bean 存储在 ServletContext 中。

getSingleton方法

单例模式下加载Bean实例。代码如下:

package org.springframework.beans.factory.support;

public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
  //一级缓存,保存的是完整bean实例(已经实例化和初始化)
  private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
  
  //三级缓存,保存的是半成品的bean实例(已经实例化还未初始化)
  private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
    
  //二级缓存,保存的半成品的bean引用,用于bean可能被AOP代理
  private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
 
  //用于当前bean是否正在创建
  private final Set<String> singletonsCurrentlyInCreation =
			Collections.newSetFromMap(new ConcurrentHashMap<>(16));
  //注册单例beanName集合
  private final Set<String> registeredSingletons = new LinkedHashSet<>(256);  
  
  //用于存放单例Bean销毁disposable实例
  private final Map<String, Object> disposableBeans = new LinkedHashMap<>();
    
  public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    synchronized (this.singletonObjects) {
      //从一级缓存singletonObjects集合中获取bean
      Object singletonObject = this.singletonObjects.get(beanName);
		if (singletonObject == null) {
		   if (this.singletonsCurrentlyInDestruction) {
			   throw  new BeanCreationNotAllowedException(...);
			}
            //将 `beanName` 标记为单例模式正在创建
			beforeSingletonCreation(beanName);
			boolean newSingleton = false;
			try {
               //调用createBean方法,创建 Bean
			   singletonObject = singletonFactory.getObject();
			   newSingleton = true;
			}
			finally {
                //将 `beanName` 标记为不在创建中,
				afterSingletonCreation(beanName);
			}
            //如果是单例模式bean,在singletonObjects集合中缓存,并移除早起暴漏bean集合
			if (newSingleton) {
				addSingleton(beanName, singletonObject);
			 }
		}
	  return singletonObject;   
    }    
  }
}

注意:过滤掉一些代码。更关注核心实现。

主要功能如下:

  1. 从 singletonObjects 单例 Bean 的缓存集合中获取 Bean,存在则直接返回,否则开始创建
  2. 将 beanName 标记为单例模式正在创建
  3. 【核心】创建 Bean,实际调用 AbstractAutowireCapableBeanFactory#createBean(…) 方法
  4. 将 beanName 标记为不在创建中
  5. 是新创建的单例模式 Bean,则在 singletonObjects 中进行缓存,并移除早起暴漏bean的二级缓存和三级缓存集合,并注册beanName到registeredSingletons集合中

createBean方法

该方法是抽象方法,交由子类AbstractAutowireCapableBeanFactory实现。

//AbstractBeanFactory类
protected abstract Object createBean(String beanName, RootBeanDefinition mbd, 
   @Nullable Object[] args) throws BeanCreationException;
			

Bean创建

createBean方法

​ 对于不同作用域的 Bean,底层都会调用 AbstractAutowireCapableBeanFactory 的 createBean(…) 方法进行创建,创建 Bean 的过程涉及到 Bean 生命周期的大部分阶段,例如实例化阶段、属性赋值阶段、Aware 接口回调阶段、初始化阶段都是在这个方法中完成的。该方法定义如下。

package org.springframework.beans.factory.support;

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
		implements AutowireCapableBeanFactory {
   //创建bean实例的策略
   private InstantiationStrategy instantiationStrategy = 
                 new CglibSubclassingInstantiationStrategy();
   @Override 
   protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)  throws BeanCreationException {
      RootBeanDefinition mbdToUse = mbd;
      //获取 `mbd` 对应的 Class 对象
      Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
      if (resolvedClass != null && !mbd.hasBeanClass() &&
         mbd.getBeanClassName() != null) {
         //复制 `mbd`,并设置 Class 对象,动态解析出来的 Class 对象不被共享
		 mbdToUse = new RootBeanDefinition(mbd);
		 mbdToUse.setBeanClass(resolvedClass);
	   }
       //实例化阶段的前置处理,执行所有InstantiationAwareBeanPostProcessor的 postProcessBeforeInstantiation方法
	   Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
       //如果没有返回对象,正常实例化Bean对象
	   if (bean != null) {
		  return bean;
	   }
       Object beanInstance = doCreateBean(beanName, mbdToUse, args);
       return beanInstance; 
   }
}

主要功能如下:

  1. 获取 mbd 对应的 Class 对象。
  2. 实例化前阶段,给调用者扩展返回一个代理对象时机。
  3. 调用doCreateBean核心方法实例化Bean对象。

实例化前置处理阶段

调用所有 InstantiationAwareBeanPostProcessor接口的实例化前方法,如果这里返回对象不是 null 的话,直接返回,可以通过这种方式提前返回一个代理对象。实例化之前给调用者扩展返回一个代理对象(自定义实例化逻辑)例如AbstractAutoProxyCreator类自定义TargetSource会返回非空代理对象。方法实现如下:

//AbstractAutowireCapableBeanFactory类 
//通过resolveBeforeInstantiation方法调用
protected Object applyBeanPostProcessorsBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
    //获取所有BeanPostProcessor接口实现类是循环遍历
    for (BeanPostProcessor bp : getBeanPostProcessors()) {
        //BeanPostProcessor接口实现类是InstantiationAwareBeanPostProcessor类型
        if (bp instanceof InstantiationAwareBeanPostProcessor类型) {
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
     //{@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation}
				Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
				if (result != null) {
					return result;
				}
        }
    }
}

该方法主要功能如下:

  1. 获取所有BeanPostProcessor后置处理器接口实现类并循环遍历。
  2. 如果是InstantiationAwareBeanPostProcessor类型后置处理器调用实例化前方法。

doCreateBean方法

该方法是创建Bean的核心方法,包含Bean的实例化、属性填充、初始化等Bean创建生命周期大部分实现。方法如下:

//AbstractAutowireCapableBeanFactory类
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
    BeanWrapper instanceWrapper = null;
    //如果是单例模式,则先尝试从 `factoryBeanInstanceCache` 缓存中获取实例对象,并从缓存中移除
	if (mbd.isSingleton()) {
		instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
	}
    //选择对应的实例化策略来创建 Bean 的实例:工厂方法、构造函数自动注入、简单初始化
	if (instanceWrapper == null) {
		instanceWrapper = createBeanInstance(beanName, mbd, args);
	}
    //获取包装的实例对象 `bean`
	Object bean = instanceWrapper.getWrappedInstance();
    //获取包装的实例对象的类型 `beanType`
	Class<?> beanType = instanceWrapper.getWrappedClass();
	if (beanType != NullBean.class) {
		mbd.resolvedTargetType = beanType;
	}
    //对 RootBeanDefinition(合并后)进行加工处理
    applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
    //设置该 RootBeanDefinition 被处理过,避免重复处理
    mbd.postProcessed = true;
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences
                        &&isSingletonCurrentlyInCreation(beanName));
	//提前暴露这个 `bean`,目的是解决单例模式 Bean 的循环依赖注入创建一个 ObjectFactory 实现类,用于返回当前已经实例化还未初始化的 `bean`,提前暴露,保存在 `singletonFactories`集合中
    if (earlySingletonExposure) {
	   addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
	}
	Object exposedObject = bean;
    try{
      populateBean(beanName, mbd, instanceWrapper);//bean属性填充
      exposedObject = initializeBean(beanName, exposedObject, mbd);//bean初始化
    }catch(Throwable ex) {
        ...
    }
    ....
    //为当前 `bean` 注册 DisposableBeanAdapter,用于 Bean 生命周期中的销毁阶段    
    registerDisposableBeanIfNecessary(beanName, bean, mbd);
    return exposedObject;//返回创建好的 `exposedObject` 对象
	
}

该方法主要功能如下:

  1. Bean实例化阶段。选择合适的实例化策略来室话 Bean 的实例。主要有工厂方法、构造函数自动注入、简单初始化。
  2. 对合并后的RootBeanDefinition进行加工处理。
  3. 提前暴露Bean。用于解决单例模式 Bean 的循环依赖注入。
  4. populateBean方法用于对Bean实例属性填充。
  5. initializeBean方法用于初始化Bean实例。
  6. 当前 bean 注册 DisposableBeanAdapter,用于单例bean销毁,且销毁时没有指定bean名字。

实例化Bean阶段

使用合适的实例化策略来创建 Bean 的实例,createBeanInstance方法实现如下:

//AbstractAutowireCapableBeanFactory类
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
	Class<?> beanClass = resolveBeanClass(mbd, beanName);
    Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
    // 如果存在 Supplier 实例化回调接口,使用给定的回调方法实例对象
    if (instanceSupplier != null) {
		return obtainFromSupplier(instanceSupplier, beanName);
	}
    //如果配置 `factory-method` 工厂方法或者通过 @Bean 标注的方法都会这里进行创建
    if (mbd.getFactoryMethodName() != null) {
		return instantiateUsingFactoryMethod(beanName, mbd, args);
	}
     //...中间忽略已经解析出合适构造方法并缓存代码....
     /**
     * <6.1> 尝试通过 SmartInstantiationAwareBeanPostProcessor 处理器的 determineCandidateConstructors 方法来找到合适的构造方法
     */
    Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
    //满足其中一个条件:找到构造方法、构造器注入、 定义了构造方法参数、传递参数
	if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
		mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
        //构造函数自动注入实例对象
		return autowireConstructor(beanName, mbd, ctors, args);
	}
    
	//尝试获取优先的构造方法
	ctors = mbd.getPreferredConstructors();
	if (ctors != null) {
		return autowireConstructor(beanName, mbd, ctors, null);
	}

	// 直接调用默认构造方法(无构造函数)返回实例对象(反射机制)
	return instantiateBean(beanName, mbd);
}

主要功能如下:

  1. 通过beanName获取Class对象。
  2. 如果存在 Supplier 实例化回调接口,使用给定的回调方法实例对象。
  3. 如果配置 factory-method 工厂方法或者通过 @Bean 标注的方法都会这里进行创建。
  4. 匹配构造函数自动注入实例对象。
  5. 如果没有匹配构造函数使用默认无参构造函数实例对象。

实例化策略(策略模式)

Spring默认使用CglibSubclassingInstantiationStrategy策略,不过Spring提供方法设置实例化策略对象。这里使用策略模式,实现如下:

public abstract class AbstractAutowireCapableBeanFactory 
     extends AbstractBeanFactoryimplements AutowireCapableBeanFactory {
    //默认实例化策略
	private InstantiationStrategy instantiationStrategy = new   CglibSubclassingInstantiationStrategy();
    //设置实例化策略来用于创建Bean实例
    public void setInstantiationStrategy(InstantiationStrategy instantiationStrategy) {
		this.instantiationStrategy = instantiationStrategy;
	}
    protected InstantiationStrategy getInstantiationStrategy() {
		return this.instantiationStrategy;
	}
}
策略接口定义
package org.springframework.beans.factory.support;

public interface InstantiationStrategy {
	//Return an instance of the bean with the given name in this factory.
	Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) throws BeansException;
    /**
    * Return an instance of the bean with the given name in this factory,
	* creating it via the given constructor.
    */
    Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,Constructor<?> ctor, Object... args) throws BeansException;
    
    /**
    * Return an instance of the bean with the given name in this factory,
    * creating it via the given factory method.
    */
    Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,@Nullable Object factoryBean, Method factoryMethod, Object... args)
			throws BeansException;
}

该接口定义三种方式实例化Bean对象

  1. 通过无参构造函数实例化Bean对象
  2. 由给出构造函数实例化对象
  3. 使用工厂方法实例化Bean。
简单实例化策略实现

SimpleInstantiationStrategy通过反射方式实例化Bean对象,类定义如下。

package org.springframework.beans.factory.support;
public class SimpleInstantiationStrategy implements InstantiationStrategy {

   //该类由子类实现
    protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName,BeanFactory owner, @Nullable Constructor<?> ctor, Object... args) {
		throw new UnsupportedOperationException("Method Injection not supported in SimpleInstantiationStrategy");
	}
}
Cglib实例化策略实现

CglibSubclassingInstantiationStrategy类通过cglib代理实现。如果bean有重写方法,则使用该类实例化对象。类定义如下:

package org.springframework.beans.factory.support;

public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationStrategy {

	@Override
	protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,@Nullable Constructor<?> ctor, Object... args) {
		// cglib实现
		return new CglibSubclassCreator(bd, owner).instantiate(ctor, args);
	}
}

RootBeanDefinition加工

调用所有 MergedBeanDefinitionPostProcessor接口postProcessMergedBeanDefinition方法。方法实现如下:

//AbstractAutowireCapableBeanFactory类
//调用所有{@link MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition 
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof MergedBeanDefinitionPostProcessor) {
				MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
				bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
			}
	 }
 }

Spring内置两个后置处理器实现MergedBeanDefinitionPostProcessor接口用于注解解析。

  • AutowiredAnnotationBeanPostProcessor 会先解析出 @Autowired 和 @Value 注解标注的属性的注入元信息,后续进行依赖注入;
  • CommonAnnotationBeanPostProcessor 会先解析出 @Resource 注解标注的属性的注入元信息,后续进行依赖注入,它也会找到 @PostConstruct 和 @PreDestroy 注解标注的方法,并构建一个 LifecycleMetadata 对象,用于后续生命周期中的初始化和销毁。

循环依赖解决

对于构造器的循环依赖,Spring 是无法解决的,只能抛出 BeanCurrentlyInCreationException 异常,表示循环依赖。对于属性循环依赖解决方式是提前暴露这个 bean,创建一个 ObjectFactory 实现类,用于返回当前已经实例化还未初始化的 bean的引用,添加到Spring三级缓存singletonFactories集合中,如下:

/**
 *  DefaultSingletonBeanRegistry类
 *  the param singletonFactory is () -> getEarlyBeanReference(beanName, mbd, bean)
 *  the param beanName is name of bean
*/
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) { 
	synchronized (this.singletonObjects) {
		if (!this.singletonObjects.containsKey(beanName)) {
           //添加到三级缓存singletonFactories集合中
			this.singletonFactories.put(beanName, singletonFactory);
           //移除二级缓存earlySingletonObjects集合中存在beanName
			this.earlySingletonObjects.remove(beanName);
           //把beanName添加到注册单例beanName集合中
			this.registeredSingletons.add(beanName);
		}
	}
}

循环依赖案例

我们假设现在有这样的场景AService依赖BService,BService依赖AService。

  1. AService首先实例化,实例化通过上述addSingletonFactory方法添加到三级缓存中。
  2. 填充属性BService,发现BService还未进行过加载,就会先去加载BService。
  3. 再加载BService的过程中,实例化后,也通过上述方法把半成品bean暴露在三级缓存。
  4. 填充属性AService的时候,这时候能够从三级缓存中拿到半成品的ObjectFactory。

当上述第4步出现循环依赖 AService时,则直接使用 ObjectFactory 的 #getObject() 方法来获取,加入二级缓存中。代码如下:

/**
 * DefaultSingletonBeanRegistry类
 * 该方法是在{@link AbstractBeanFactory.getBean()}调用,加载Bean时,通过名字从缓存中获取bean
*/
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    //从一级缓存earlySingletonObjects集合中获取Bean
	Object singletonObject = this.singletonObjects.get(beanName);
	if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
		synchronized (this.singletonObjects) {
            //尝试从二级缓存earlySingletonObjects中获取半成品bean
			singletonObject = this.earlySingletonObjects中获取bean.get(beanName);
            //如果获取Bean为空并且允许从三级缓存获取bean
			if (singletonObject == null && allowEarlyReference) {
                //尝试从三级缓存singletonFactories集合中获取bean,
				ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
				if (singletonFactory != null) {
          /**
          *  从三级缓存获取的是bean的引用{@link ObjectFactory},
          *  最终调用getEarlyBeanReference(beanName, mbd, bean)方法
          *      1. 如果没有动态代理,则返回原始bean
          *      2. 如果bean被AOP切面代理则返回的是beanProxy对象
          *   
          *  最后获取bean缓存到二级缓存`earlySingletonObjects`集合中
          */
					singletonObject = singletonFactory.getObject();
					this.earlySingletonObjects.put(beanName, singletonObject);
                    // 移除三级缓存中该bean元素
					this.singletonFactories.remove(beanName);
				}
			}
		}
	}
	return singletonObject;
}

主要功能如下:

  1. 从一级缓存singletonObjects集合中获取Bean。
  2. 如果为空,尝试从二级缓存earlySingletonObjects中获取半成品Bean,用于防止bean被多次循环依赖。
  3. 如果为空,尝试从三级缓存singletonFactories集合中获取Bean。
  4. 最后获取bean缓存到二级缓存earlySingletonObjects集合中。
  5. 移除三级缓存中bean元素。

最后 : 而此时BService注入的是已经实例化还没有初始化的实例AService对象。但是随着BService初始化完成后,A会继续进行后续的初始化操作,最终BService会注入的是一个完整的AService实例,因为在内存中它们是同一个对象。

两个缓存能否解决循环依赖

  • 如果没有二级缓存。但是有一个前提这个bean没被AOP进行切面代理,如果这个bean被AOP进行了切面代理,没有二级缓存是无法解决问题。因为每次调用getEarlyBeanReference方法返回新的代理对象。
  • 如果没有三级缓存。需要每次实例化Bean后要立即调用getEarlyBeanReference方法,虽然能解决。如果此时这个bean被AOP进行了切面代理,这就和Spring生命周期违背。Spring Bean生命周期是在Bean初始化完成后才进行AOP代理。

populateBean方法

该方法主要通过BeanWrapper中属性值填充实例化Bean对象,方法实现如下:

//AbstractAutowireCapableBeanFactory类
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    ...
   /**
   实例化阶段的后置处理, 在填充属性前,给实例化Bean扩展机会修改bean的状态。执行所有InstantiationAwareBeanPostProcessor的 postProcessAfterInstantiation方法
   */
    //mbd(RootBeanDefinition )是Spring解析出并且有实例化后置处理实例
	if (!mbd().isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
      //遍历所有的 BeanPostProcessor
	  for (BeanPostProcessor bp : getBeanPostProcessors()) {
         //如果为 InstantiationAwareBeanPostProcessor 类型
		 if (bp instanceof InstantiationAwareBeanPostProcessor) {
			 InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
             //对实例化Bean进行后置处理,修改bean的状态。注意如果返回 false,直接 `return`,不会调用后面的 InstantiationAwareBeanPostProcessor 处理器,不会填充bean属性。
			 if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
				 return;
			 }
		 }
	  }
   }
   //获取 `pvs`,用于属性填充
   PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
   ....
   PropertyDescriptor[] filteredPds = null;
	if (hasInstAwareBpps) {
	  if (pvs == null) {
		pvs = mbd.getPropertyValues();
	   }
       // 通过 InstantiationAwareBeanPostProcessor 处理器(如果有)对 `pvs` 进行处理
	   for (BeanPostProcessor bp : getBeanPostProcessors()) {
          //判断是否是 InstantiationAwareBeanPostProcessor 类型
		  if (bp instanceof InstantiationAwareBeanPostProcessor) {
			 InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
          //调用Bean后置处理器属性填充前方法对 `pvs` 进行后置处理
			 PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
			 if (pvsToUse == null) {
				if (filteredPds == null) {
					filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
				}
                //属性填充前调用,该方法过期,被postProcessProperties方法取代
				pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                // 如果处理后的 PropertyValues 对象为空,直接 `return`
				if (pvsToUse == null) {
					return;
				}
			}
		    pvs = pvsToUse;
		  }
		}
	}   
    ...
    //pvs不为空,该方法用于填充bean属性
    if (pvs != null) {
		applyPropertyValues(beanName, mbd, bw, pvs);
	}
}

主要功能如下:

  1. 实例化阶段后置处理,在填充属性前,给实例化Bean扩展机会来修改Bean的状态 。
  2. 获取 pvs {@link PropertyValues},用于属性填充。
  3. 获取Bean 的注入模式(此处代码省略,详情看源码)。
  4. 属性赋值前阶段处理,用于依赖注入注解解析。
  5. 依赖检查(此处代码省略,详情看源码)。
  6. pvs不为空,填充bean属性。

实例化后置处理阶段

实现逻辑见上述方法,用于在填充属性前,给实例化Bean扩展机会来修改Bean的状态 。主要逻辑如下:

  1. 获取所有BeanPostProcessor后置处理器接口实现类并循环遍历。
  2. 如果是InstantiationAwareBeanPostProcessor类型后置处理器调用实例化后方法。
  3. 如果返回 false,直接 return,不会执行后面属性填充前和属性填充逻辑。

属性赋值前阶段

实现逻辑见上述方法,用于在属性赋值前,用于依赖注入注解解析。主要逻辑如下:

  1. 获取所有BeanPostProcessor后置处理器接口实现类并循环遍历。

  2. 如果是InstantiationAwareBeanPostProcessor类型后置处理器调用属性处理器方法。

  3. 新老版本接口兼容,先调用新版本属性处理器方法如果返回为空,调用旧版本属性处理器方法。

  • Spring 1.2 - 5.0(旧版本):InstantiationAwareBeanPostProcessor#postProcessPropertyValues
  • Spring 5.1(新版本):InstantiationAwareBeanPostProcessor#postProcessProperties

Spring内置两个后置处理器实现InstantiationAwareBeanPostProcessor接口用于注解解析。如下:

  • AutowiredAnnotationBeanPostProcessor会解析 @Autowired 和 @Value 注解标注的属性,获取对应属性值。
  • CommonAnnotationBeanPostProcessor 解析 Resource 注解标注的属性,获取对应的属性值。

属性赋值阶段

如果 pvs 不为空, 把属性值设置到当前 Bean 对应的属性中,调用applyPropertyValues(…)方法。该方法逻辑复杂之后做专栏阶段。

initializeBean方法

该方法主要用于初始化bean实例,方法实现如下。

//AbstractAutowireCapableBeanFactory类
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
  ...
  //Aware接口的回调
  invokeAwareMethods(beanName, bean);
  Object wrappedBean = bean;
  //初始化阶段的前置处理,执行所有 BeanPostProcessor 的 postProcessBeforeInitialization 方法
  if (mbd == null || !mbd.isSynthetic()) {
     wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
   }
   /**
      调用自定义的初始化方法。
      1.调用所有实现 InitializingBean接口afterPropertiesSet方法
       {@link InitializingBeanafterPropertiesSet}
      2.调用通过 `init-method` 自定义的初始化方法(反射机制) 
   */
   try{
      invokeInitMethods(beanName, wrappedBean, mbd);  
   }catch(Throwable ex){
       throw new BeanCreationException(...)
   }
    //初始化阶段的后置处理,执行所有 BeanPostProcessor 的 postProcessAfterInitialization 方法
   if (mbd == null || !mbd.isSynthetic()) {
	 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
   }
   return wrappedBean;
}

主要功能如下:

  1. Aware接口回调。注意仅仅调用BeanNameAware、BeanClassLoaderAware 或 BeanFactoryAware接口。
  2. 初始化阶段的前置处理。
  3. 调用自定义的初始化方法。
  4. 初始化阶段的后置处理。

Aware接口的回调

invokeAwareMethods方法用于对Aware接口回调。方法如下:

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

如果目标实例 bean实现如下接口,则调用其 setXxx 方法,调用顺序依次从上到下:

  1. BeanNameAware
  2. BeanClassLoaderAware
  3. BeanFactoryAware

初始化前置处理阶段

调用所有 BeanPostProcessor 的 postProcessBeforeInitialization 方法。在Bean初始化回调前,此时Bean实例已经填充属性后。默认返回给定Bean实例,此时可以返回Bean实例是原始Bean的包装来对Bean进行扩展。方法实现如下:

//AbstractAutowireCapableBeanFactory类
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)throws BeansException {
	Object result = existingBean;
    // 循环遍历所有 BeanPostProcessor
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
       //调用初始化前置处理器方法
	   Object current = processor.postProcessBeforeInitialization(result, beanName);
	   if (current == null) {
		 return result;
	   }
       //如果返回的对象不为空,则返回新的包装对象代替原有的对象
	   result = current;
	}
	return result;
}

Spring内置两个后置处理器实现BeanPostProcessor接口postProcessBeforeInitialization方法。分别如下:

  • InitDestroyAnnotationBeanPostProcessor 用于对@PostConstruct 注解自定义初始化方法回调。该类简要实现如下:

    package org.springframework.beans.factory.annotation;
    
    /**
      CommonAnnotationBeanPostProcessor类继承该类。
    */
    public class InitDestroyAnnotationBeanPostProcessor extends ...{
    	@Override
    	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
            metadata.invokeInitMethods(bean, beanName);
        }
    }
    
  • ApplicationContextAwareProcessor用于Aware接口回调。如果目标 bean实现如下接口,则调用其 setXxx 方法,调用顺序依次从上到下:

    1. EnvironmentAware
    2. EmbeddedValueResolverAware
    3. ResourceLoaderAware
    4. ApplicationEventPublisherAware
    5. MessageSourceAware
    6. ApplicationContextAware

结合上节invokeAwareMethods对Aware接口回调,总有9个Aware接口回调。调用顺序依次从上到下,而最后六个Aware接口用于Spring Context应用上下文。

初始化方法回调

invokeInitMethods方法用于调用自定义的初始化方法。实现如下:

//AbstractAutowireCapableBeanFactory类
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd) throws Throwable {
    //判断bean是否实现InitializingBean接口
	boolean isInitializingBean = (bean instanceof InitializingBean);
    if (isInitializingBean && (mbd == null ||         !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
        //调用其 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-method` 指定的初始化方法(反射机制)
				invokeCustomInitMethod(beanName, bean, mbd);
			}
		}
}

Bean初始化执行顺序

  1. @PostConstruct 标注方法。在Bean初始化前置处理器阶段执行,详情见Bean初始化前阶段
  2. 实现InitializingBean 接口的afterPropertiesSet() 方法
  3. 调用通过 init-method 指定的初始化方法

初始化后置处理器阶段

调用所有 BeanPostProcessor 的 postProcessAfterInitialization 方法。在Bean初始化回调hou ,并且Bean实例已经填充属性后。默认返回给定Bean实例,此时也可以返回Bean实例是原始Bean的包装来对Bean进行扩展。方法实现如下:

//AbstractAutowireCapableBeanFactory类
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
	Object result = existingBean;
    //循环所有BeanPostProcessor后置处理器
	for (BeanPostProcessor processor : getBeanPostProcessors()) {
        调用初始化前置处理器方法
		Object current = processor.postProcessAfterInitialization(result, beanName);
		if (current == null) {
			return result;
		}
        //如果返回的对象不为空,则返回新的包装对象代替原有的对象
		result = current;
	}
	return result;
}

Spring内置后置处理器实现BeanPostProcessor接口postProcessAfterInitialization方法。分别如下:

  • AbstractAutoProxyCreator该类通过实现SmartInstantiationAwareBeanPostProcessor接口实现该方法。用于Spring AOP代理,此时返回AOP动态代理对象。
  • ApplicationListenerDetector该类通过DestructionAwareBeanPostProcessor接口实现该方法。如果单例Bean类型是ApplicationListener,则添加到 Spring 应用上下文ApplicationListener集合中。

注册销毁Bean方法

调用registerDisposableBeanIfNecessary方法,实现如下:

//AbstractBeanFactory类
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
    //如果不是原型模式并且需要销毁(有销毁方法)
	if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
   //如果是单例模式,创建 DisposableBeanAdapter对象封装Bean,保存在 `disposableBeans` Map 集合中
        if (mbd.isSingleton()) {
            registerDisposableBean(beanName,
		new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
        }
    }else{
     //其它模式,创建DisposableBeanAdapter对象封装 Bean,往其它模式的 Scope 对象里面注册
        Scope scope = this.scopes.get(mbd.getScope());
        scope.registerDestructionCallback(beanName,
	new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
    }
}

经过上面Bean创建的过程,实例化、属性填充、初始化等阶段,已经创建好完整的 Bean,最后直接返回。

Bean初始化完成阶段

初始化完成阶段是在AbstractApplicationContext类重写refresh方法完成的。refresh方法如下:

//AbstractApplicationContext
@Override
public void refresh() throws BeansException, IllegalStateException {
   ...   
   //主要功能实例化所有还未使用(非懒初始化)单例bean
   finishBeanFactoryInitialization(beanFactory);
   ... 
}

finishBeanFactoryInitialization方法主要用于初始化所有还未使用的的单例bean。实现如下:

//AbstractApplicationContext
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    ...
    /**
    * 主要功能实例化所有还未使用(非懒初始化)单例bean
    * preInstantiateSingletons方法是ConfigurableListableBeanFactory接口定义
    * 由DefaultListableBeanFactory实现
    **/
    beanFactory.preInstantiateSingletons();
}

先忽略方法部分逻辑,关注点在Bean初始化完成方法。

通过DefaultListableBeanFactory类实现初始化完成方法preInstantiateSingletons,实现如下:

@Override
public void preInstantiateSingletons() throws BeansException {
	...
    //遍历所有单例beanName集合,对所有bean触发初始化完成处理器回调
	for (String beanName : beanNames) {
		Object singletonInstance = getSingleton(beanName);
        //bean是否实现SmartInitializingSingleton接口
		if (singletonInstance instanceof SmartInitializingSingleton) {
		 SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
         //回调afterSingletonsInstantiated方法
		 smartSingleton.afterSingletonsInstantiated();
	}
}

主要功能如下:

  1. 当所有单例bean实例化完成后, 判断bean是否实现SmartInitializingSingleton接口。
  2. 如果实现该接口,回调bean实例化完成后方法afterSingletonsInstantiated用于扩展。

Bean销毁

Bean的销毁在AbstractApplicationContext类中实现close方法。最终调用DisposableBeanAdapter类destroy方法销毁bean。该类是Bean创建过程中注册销毁Bean实例DisposableBeanAdapter,该类定义如下。

package org.springframework.beans.factory.support;

class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
	@Override
	public void destroy() {
        /**
        * 销毁阶段后置处理器,调用所有实现
        * DestructionAwareBeanPostProcessor接口postProcessBeforeDestruction方法
        * Spring内置实现类InitDestroyAnnotationBeanPostProcessor用于解析`@PreDestroy`注解
        * 调用销毁前回调方法。子类是CommonAnnotationBeanPostProcessor
        */
        if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
			for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
				processor.postProcessBeforeDestruction(this.bean, this.beanName);
			}
		}
        if (this.invokeDisposableBean) {
            //bean实现DisposableBean接口,调用其destroy回调方法
            ((DisposableBean) this.bean).destroy();
        }
        if (this.destroyMethod != null) {
             //调用通过 `destroy-method` 指定的初始化方法(反射机制)
			invokeCustomDestroyMethod(this.destroyMethod);
        }
		else if (this.destroyMethodName != null) {
			Method methodToInvoke = determineDestroyMethod(this.destroyMethodName);
			if (methodToInvoke != null) {
	invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke));
			}
		}
    }
}

Bean销毁前执行顺序

  1. @PreDestroy注解标记方法回调。

  2. 实现DisposableBean接口的destroy()方法

  3. 自定义销毁方法

注意Bean的销毁把从容器一级缓存集合中移除,并没有垃圾回收(GC)

总结

当我们显示或者隐式地调用AbstractBeanFactory.getBean(...)方法时,会触发 Bean 的加载,详情见Bean加载 。对于不同作用域的 Bean,底层都会调用 AbstractAutowireCapableBeanFactory.createBean(...)方法进行创建,该类完成Bean生命周期大部分实现,

Bean生命周期扩展总结

Bean生命周期经历实例化、实例属性填充、Aware接口回调、初始化、初始化完成、销毁等阶段,在每个阶段Spring提供扩展机制,允许我们在实际场景中进行扩展。另外Spring本身内置很多扩展类。我们在工作中也可以根据Spring生命周期扩展机制来进行扩展,来解决实际问题。总结如下:

  • 实例化阶段

    1. 实例化前置处理阶段

      实现 InstantiationAwareBeanPostProcessor接口postProcessBeforeInstantiation方法扩展

    2. 实例化Bean对象

    3. RootBeanDefinition加工阶段

      实现MergedBeanDefinitionPostProcessor接口postProcessMergedBeanDefinition方法扩展

    4. 实例化后置处理器阶段

      实现 InstantiationAwareBeanPostProcessor接口postProcessAfterInstantiation方法扩展

  • 实例属性填充阶段

    1. 属性填充前阶段
      1.1 Spring 1.2 - 5.0(旧版本):InstantiationAwareBeanPostProcessor#postProcessPropertyValues
      1.2 Spring 5.1(新版本):InstantiationAwareBeanPostProcessor#postProcessProperties
    2. 属性填充阶段
  • Aware接口回调阶段

  • 初始化阶段

    1. 初始化前置处理阶段

      实现 BeanPostProcessor接口postProcessBeforeInitialization方法扩展

    2. 初始化回调阶段

    3. 初始化后阶段

      实现 BeanPostProcessor接口postProcessAfterInitialization方法扩展

  • 初始化完成阶段

    实现 SmartInitializingSingleton接口afterSingletonsInstantiated方法扩展

  • 销毁阶段

    实现 DestructionAwareBeanPostProcessor接口postProcessBeforeDestruction方法扩展

用一张图描述Bean生命周期过程

你可能感兴趣的:(Spring源码解析,spring,后端)