Spring的Bean生命周期源码解读

一、什么是Spring Bean的生命周期

对于普通的 Java 对象,当 new 的时候创建对象,然后该对象就能够使用了。一旦该对象不再被使用,则由 Java 自动进行垃圾回收。

而 Spring 中的对象是 bean,bean 和普通的 Java 对象没啥大的区别,只不过 Spring 不再自己去 new 对象了,而是由 IoC 容器去帮助我们实例化对象并且管理它,我们需要哪个对象,去问 IoC 容器要即可。IoC 其实就是解决对象之间的耦合问题,Spring Bean 的生命周期完全由容器控制。

二、Bean的生命周期

1、bean定义:就是从xml或者yaml中读取bean的元信息并定义成beanDefination对象
2、bean注册:将beanDefination对象按照相应的规则注册到缓存池Map中
3、实例化:把beanDefination对象实例化成真正的bean,即调用构造函数
4、依赖注入:调用setter方法,注入属性(自定义属性和容器属性)
5、初始化:用户自定义扩展阶段
6、销毁:销毁是用户能自定义扩展的阶段

三、Spring源码分析解读

spring配置文件加载(xml方式)

ApplicationContext ac = new ClassPathXmlApplicationContext("application-context.xml");

spring加载xml入口ClassPathXmlApplicationContext,点击进入内部查看

// 这是ClassPathXmlApplicationContext的构造函数
public ClassPathXmlApplicationContext(
			String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
			throws BeansException {

		super(parent); // 调用父级构造方法
		setConfigLocations(configLocations); // 设置要读取的配置文件路径
		if (refresh) { // 是否自动上下文刷新
			refresh(); // 调用上下文刷新方法
		}
	}

// 调用AbstractRefreshableConfigApplicationContext中的setConfigLocations方法
// 这个方法的作用:解析指定的数组路径,如果数组中包含特殊符号,如${var},那么在resolvePath方法中会搜寻匹配的系统变量并替换
public void setConfigLocations(@Nullable String... locations) {
		if (locations != null) {
			Assert.noNullElements(locations, "Config locations must not be null");
			this.configLocations = new String[locations.length];
			for (int i = 0; i < locations.length; i++) {
				// 解析指定路径
				this.configLocations[i] = resolvePath(locations[i]).trim();
			}
		}
		else {
			this.configLocations = null;
		}
	}

点击refresh(),进入到AbstractApplicationContext类中

@Override
public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
		//1.调用容器准备刷新的方法,获取容器的当前时间,同时给容器设置同步标识
		prepareRefresh();

		//2.创建新的bean工厂,加载配置;
		//告诉子类启动refreshBeanFactory()方法,Bean定义资源文件的载入从子类的refreshBeanFactory()方法启动
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

		//3.为BeanFactory配置容器特性,例如类加载器、事件处理器等
		prepareBeanFactory(beanFactory);

		try {
			//4.允许在子类上下文对bean工厂进行后处理(为容器的某些子类指定特殊的BeanPost事件处理器)
			postProcessBeanFactory(beanFactory);

			//5.激活各种BeanFactory处理器;
			invokeBeanFactoryPostProcessors(beanFactory);

			//6.注册拦截bean创建的bean处理器,这里只是注册,真正的调用是在getBean时候
			registerBeanPostProcessors(beanFactory);

			//7.初始化信息源,和国际化相关.
			initMessageSource();

			//8.初始化此上下文的事件多播器
			initApplicationEventMulticaster();

			//9.模板方法,它可以被覆盖以添加特定于上下文的刷新工作。
			onRefresh();

			//10.注册监听器
			registerListeners();

			//11.实例化所有剩余的(非lazy-init)单例,实例化对象
			finishBeanFactoryInitialization(beanFactory);

			// 12.清除缓存的资源信息,初始化一些声明周期相关的bean,并且发布Context已被初始化的事件
			finishRefresh();
		}

		catch (BeansException ex) {
			if (logger.isWarnEnabled()) {
				logger.warn("Exception encountered during context initialization - " +
						"cancelling refresh attempt: " + ex);
			}

			// Destroy already created singletons to avoid dangling resources.
			destroyBeans();

			// Reset 'active' flag.
			cancelRefresh(ex);

			// Propagate exception to caller.
			throw ex;
		}

		finally {
			// Reset common introspection caches in Spring's core, since we
			// might not ever need metadata for singleton beans anymore...
			resetCommonCaches();
		}
	}
}

上面的代码实现的功能:
1.Spring容器的创建和配置文件的加载、解析功能;
2.初始化Spring容器相关配置;
3.实例化所有剩余的(非lazy-init)单例;

这里具体来看一下这些方法的作用:
1.prepareRefresh()方法:准备刷新上下文环境

protected void prepareRefresh() {
	// 获取当前时间
	this.startupDate = System.currentTimeMillis();
	this.closed.set(false);
	this.active.set(true);

	if (logger.isDebugEnabled()) {
		if (logger.isTraceEnabled()) {
			logger.trace("Refreshing " + this);
		}
		else {
			logger.debug("Refreshing " + getDisplayName());
		}
	}

	// 初始化上下文环境中的任何占位符属性源(留给子类实现)
	initPropertySources();

	// 验证需要的属性文件是否都已经放入环境中
	getEnvironment().validateRequiredProperties();

	// 存储预刷新状态的ApplicationListeners
	// 若雨刷in状态的ApplicationListeners为空,则将ApplicationListeners放入到预刷新状态的ApplicationListeners中
	if (this.earlyApplicationListeners == null) {
		this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
	}
	else {
		// 将ApplicationListeners重置为预刷新状态
		//若预刷新状态的ApplicationListeners不为空,则将applicationListeners清空,将预刷新状态的ApplicationListeners(earlyApplicationListeners)放入到ApplicationListeners中
		this.applicationListeners.clear();
		this.applicationListeners.addAll(this.earlyApplicationListeners);
	}

	//创建ApplicationEvents集合,一旦多播器可用,将被发布
	this.earlyApplicationEvents = new LinkedHashSet<>();
}

initPropertySources()这个方法点开发现是空的,这里可以理解为Spring框架为用户提供的扩展点,这里留一个空方法留给用户实现,给用户最大扩展Spring的能力。用户可以根据自身的需要重写initPropertySources方法,并在方法中进行个性化的属性处理及设置。

2.obtainFreshBeanFactory();bean工厂的创建和xml等配置文件的加载。

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
	// 这里使用了委派设计模式,父类定义了抽象的refreshBeanFactory()方法
	// 具体实现调用子类容器的refreshFactory()方法

	// 创建新的工厂,如果之前存在,destroyBeans()调用方法销毁;closeBeanFactory()调用方法关闭
	// 这里使用到的是AbstractRefreshableApplicationContext子类
	// //初始化BeanFactory,并进行XML文件读取,并将得到的BeanFactory记录在当前实体属性中
	refreshBeanFactory();
	// //获取上一步中新创建的工厂
	return getBeanFactory();
}

// 创建bean工厂,这里是AbstractRefreshableApplicationContext类中的refreshBeanFactory()方法
protected final void refreshBeanFactory() throws BeansException {
	// 判断beanFactory是否存在
	if (hasBeanFactory()) {
		// 存在
		// 销毁
		destroyBeans();
		// 关闭
		closeBeanFactory();
	}
	try {
		// 这里创建 DefaultListableBeanFactory 
		DefaultListableBeanFactory beanFactory = createBeanFactory();
		// 设置序列化id,若有需要就可根据这个id反序列化到这个beanFactory对象
		beanFactory.setSerializationId(getId());
		// 对IOC容器进行定制化,比如设置启动参数
		customizeBeanFactory(beanFactory);
		// 调用载入bean定义的方法,主要这里又使用了一个委派模式
		// 在当前类中只定义了抽象的loadBeanDefinitions方法,具体的实现调用子类容器
		// 初始化documentReader,并实现对xml的读取和解析
		loadBeanDefinitions(beanFactory);
		synchronized (this.beanFactoryMonitor) {
			// 设置此上下文的bean工厂
			this.beanFactory = beanFactory;
		}
	}
	catch (IOException ex) {
		throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
	}
}

// 创建一个新的DefaultListableBeanFactory ;getInternalParentBeanFactory()该方法就是获取父级工厂
protected DefaultListableBeanFactory createBeanFactory() {
	return new DefaultListableBeanFactory(getInternalParentBeanFactory());
}

// 调用的AbstractApplicationContext中的getInternalParentBeanFactory()方法获取父级工厂
// 在AbstractApplicationContext抽象类中
@Nullable
protected BeanFactory getInternalParentBeanFactory() {
	return (getParent() instanceof ConfigurableApplicationContext ?
			((ConfigurableApplicationContext) getParent()).getBeanFactory() : getParent());
}

// 此上下文的父上下文,getParent()获取的就是这个属性,获取父级的上下文
@Nullable
private ApplicationContext parent;

// 来看一下,什么时候设置了父级工厂,这里就要回到ClassPathXmlApplicationContext的构造函数了
// 其中有super(parent);这段代码,作用:调用父级的构造方法,并传递一个参数ApplicationContext parent
// 点击super(parent)
public AbstractXmlApplicationContext(@Nullable ApplicationContext parent) {
	super(parent);
}

// 再次点击super(parent)
public AbstractRefreshableConfigApplicationContext(@Nullable ApplicationContext parent) {
	super(parent);
}

// 再次点击super(parent)
public AbstractRefreshableApplicationContext(@Nullable ApplicationContext parent) {
	super(parent);
}
	
//在AbstractApplicationContext抽象类中看到了setParent(parent);设置父级上下文的方法
public AbstractApplicationContext(@Nullable ApplicationContext parent) {
		this();
	setParent(parent);
}

// setParent方法如下
public void setParent(@Nullable ApplicationContext parent) {
	this.parent = parent;
	if (parent != null) {
		Environment parentEnvironment = parent.getEnvironment();
		if (parentEnvironment instanceof ConfigurableEnvironment) {
			getEnvironment().merge((ConfigurableEnvironment) parentEnvironment);
		}
	}
}

//经过上面的源码查看可以看出在实例化ClassPathXmlApplicationContext时设置了父级上下文对象,看参数可知,
//this(new String[] {configLocation}, true, null),此时设置的父级上下文对象为空,即:ApplicationContext parent = null;
//所以这里的getInternalParentBeanFactory方法获取的父级工厂就为null.所以这里创建的DefaultListableBeanFactory传递的父级工厂为null。

// 配置上一步创建的beanFactory
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
 	// 如果allowBeanDefinitionOverriding不为空,设置给beanFactory对象相应属性
	if (this.allowBeanDefinitionOverriding != null) {
		beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
	}
	// 如果allowCircularReferences不为空,设置给beanFactory对象相应属性
	if (this.allowCircularReferences != null) {
		// 是否允许bean之间存在循环依赖
		beanFactory.setAllowCircularReferences(this.allowCircularReferences);
	}
}

// 配置XmlBeanDefinitionReader,读取配置文件
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
	// 为指定的beanFactory创建一个XmlBeanDefinitionReader 
	XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

	// 为beanDefinitionReader进行环境变量设置
	beanDefinitionReader.setEnvironment(this.getEnvironment());
	beanDefinitionReader.setResourceLoader(this);
	beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

	// 对beanDefinitionReader进行设置,可以覆盖
	initBeanDefinitionReader(beanDefinitionReader);
	// 进行配置文件读取
	loadBeanDefinitions(beanDefinitionReader);
}

// XmlBeanDefinitionReader中已经将之前初始化的DefaultListableBeanFactory注册进去了,所以XmlBeanDefinitionReader所读取的
// BeanDefinitionHolder都会注册到DefaultListableBeanFactory中,也就是经过此步骤,
// 类型DefaultListableBeanFactory的变量beanFactory已经包含了所有解析好的配置.
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
Resource[] configResources = getConfigResources();
	if (configResources != null) {
		reader.loadBeanDefinitions(configResources);
	}
	String[] configLocations = getConfigLocations();
	if (configLocations != null) {
		reader.loadBeanDefinitions(configLocations);
	}
}

3.这个方法开始创建(非懒加载)对象,finishBeanFactoryInitialization();

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
	// 初始化此上下文的转换服务
	// 这是spring3以后新加的代码,为容器指定一个转换服务(ConversionService)
	// 在这对某些bean属性进行转换时使用
	if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
			beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
		beanFactory.setConversionService(
				beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
	}

	// 如果没有bean后置处理程序,则注册一个默认的嵌入式解析器
	// (例如PropertyPlaceholderConfigurer bean)在此之前注册: 此时,主要用于解析注释属性值。
	if (!beanFactory.hasEmbeddedValueResolver()) {
		beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
	}

	// 尽早初始化LoadTimeWeaverAware bean,以循序尽早注册它们的转换器。
	String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
	for (String weaverAwareName : weaverAwareNames) {
		getBean(weaverAwareName);
	}

	// 为了类型匹配,停止使用临时的类加载器
	beanFactory.setTempClassLoader(null);

	// 缓存容器中所注册的BeanDefination元数据,以防被修改
	beanFactory.freezeConfiguration();

	// 实例化所有剩余的非lazy-init单例
	beanFactory.preInstantiateSingletons();
}

// 这里调用了ConfigurableListableBeanFactory中的preInstantiateSingletons()方法
// 其实现类为DefaultListableBeanFactory(Spring初始化创建的bean工厂),所以说这个方法是spring的bean工厂中执行的,该bean工厂在经过上面XmlBeanDefinitionReader读取配置信息,已经包含了所有解析好的配置(比如在xml中配置的bean信息)
public void preInstantiateSingletons() throws BeansException {
    if (this.logger.isTraceEnabled()) {
          this.logger.trace("Pre-instantiating singletons in " + this);
      }

	  // 从bean工厂中取出,按注册顺序排列的bean定义名称集合
      List<String> beanNames = new ArrayList(this.beanDefinitionNames);
      Iterator var2 = beanNames.iterator();
	  
	  // 触发所有非惰性单例的bean的初始化
      while(true) {
          String beanName;
          Object bean;
          do {
              while(true) {
                  RootBeanDefinition bd;
                  do {
                      do {
                          do {
                              if (!var2.hasNext()) {
                                  var2 = beanNames.iterator();
								  
								  // 扫描所有的bean
                                  while(var2.hasNext()) {
                                      beanName = (String)var2.next();
                                      // 从缓存中获取对应的bean
                                      Object singletonInstance = this.getSingleton(beanName);
                                      // 判断创建的对象是否实现SmartInitializingSingleton接口
                                      if (singletonInstance instanceof SmartInitializingSingleton) {
                                          // 如果存在实现SmartInitializingSingleton接口的bean,
                                          // 那么Spring还会调用该bean的afterSingletonsInstantiated()方法
                                          SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton)singletonInstance;
                                          if (System.getSecurityManager() != null) {
                                              AccessController.doPrivileged(() -> {
                                                  smartSingleton.afterSingletonsInstantiated();
                                                  return null;
                                              }, this.getAccessControlContext());
                                          } else {
                                              smartSingleton.afterSingletonsInstantiated();
                                          }
                                      }
                                  }

                                  return;
                              }

                              beanName = (String)var2.next();
                              // 根据beanName获取对应的RootBeanDefinition信息
                              bd = this.getMergedLocalBeanDefinition(beanName);
                          } while(bd.isAbstract()); // 判断bean定义信息是否为抽象类
                      } while(!bd.isSingleton()); // 判断bean定义信息是否为单例
                  } while(bd.isLazyInit()); // 判断bean定义信息是否为懒加载

				  // 判断当前类是否为工厂bean // 如果指定名称的bean是创建容器的bean
                  if (this.isFactoryBean(beanName)) {
                      // FACTORY_BEAN_PREFIX="&",当bean名称前面加"&"符号时,
                      // 获取的是产生容器对象本身,而不是容器产生的bean
                      // 调用getBean()方法,不存在就创建,触发容器对bean实例化和依赖注入过程
                      bean = this.getBean("&" + beanName);
                      break;
                  }
				  // 调用getBean()方法,不存在就创建,触发容器对bean实例化和依赖注入过程
                  this.getBean(beanName);
              }
          } while(!(bean instanceof FactoryBean));

          FactoryBean<?> factory = (FactoryBean)bean;
          // 判断是否需要预实例化
          boolean isEagerInit;
          if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
              SmartFactoryBean var10000 = (SmartFactoryBean)factory;
              ((SmartFactoryBean)factory).getClass();
              isEagerInit = (Boolean)AccessController.doPrivileged(var10000::isEagerInit, this.getAccessControlContext());
          } else {
              isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean)factory).isEagerInit();
          }

          if (isEagerInit) {
              // 调用getBean()方法,不存在就创建,触发容器对bean实例化和依赖注入过程
              this.getBean(beanName);
          }
      }
  }

该方法实现了从bean工厂中获取注册的beanName信息,并依次遍历,若为单例对象则调用getBean方法,触发容器对Bean实例化和依赖注入过程。

最后将创建好的bean注入到这个缓存池map中

// FactoryBean的缓存池
private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<>(16);
// 单例缓存池
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

四、获取bean

我们平常使用的context.getBean(“”);
调用的屙屎ApplicationContext里的getBean方法,我们知道BeanFactory中有getBean的方法,ApplicationContext又集成BeanFactory,其实调用的就是BeanFactory中的getBean方法
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值