从源码分析Spring的生命周期

Posted 赵晓东-Nastu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从源码分析Spring的生命周期相关的知识,希望对你有一定的参考价值。

一、目录结构

(1)MyBeanFactoryPostProcessor

@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		System.out.println("MyBeanFactoryPostProcessor的--->"+"postProcessBeanFactory");
	}
}

(2)MyInstantiationAwareBeanPostProcessorAdapter

@Component
public class MyInstantiationAwareBeanPostProcessorAdapter implements InstantiationAwareBeanPostProcessor {
	@Override
	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		System.out.println("MyInstantiationAwareBeanPostProcessorAdapter--->"+"postProcessBeforeInstantiation");
		return null;
	}

	@Override
	public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
		System.out.println("MyInstantiationAwareBeanPostProcessorAdapter--->"+"postProcessAfterInstantiation");
		return false;
	}

	@Override
	public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
		System.out.println("MyInstantiationAwareBeanPostProcessorAdapter--->"+"postProcessPropertyValues");
		return null;
	}
}

(3)MyBeanPostProcessor

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		System.out.println("MyBeanPostProcessor---->"+"postProcessBeforeInitialization");
		return null;
	}

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		System.out.println("MyBeanPostProcessor---->"+"postProcessAfterInitialization");
		return null;
	}
}

(4)user

package com.iocbean;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class User implements ApplicationContextAware, BeanFactoryAware , BeanNameAware, InitializingBean, DisposableBean {
	@Value("1")
	private int id;
	@Value("zxd")
	private String name;
	private ApplicationContext applicationContext;
	private BeanFactory beanFactory;

	public User() {
		System.out.println("[构造器]---》实例化User");
	}

	public BeanFactory getBeanFactory() {
		return beanFactory;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		System.out.println("属性注入id");
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		System.out.println("[注入属性]注入属性name");
		this.name = name;
	}

	public ApplicationContext getApplicationContext() {
		return applicationContext;
	}

	@Override
	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
		System.out.println("[BeanFactoryAware]调用BeanFactoryAware.setBeanFactory()");
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		System.out.println("[ApplicationContextAware接口]调用ApplicationContextAware.setApplicationContext");
	}

	@Override
	public void setBeanName(String name) {
		System.out.println("【BeanNameAware接口】调用BeanNameAware.setBeanName()");
	}

	@Override
	public void destroy() throws Exception {
		System.out.println("[DiposibleBean接口]调用DiposibleBean.destory()");
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		System.out.println("【InitializingBean接口】调用InitializingBean.afterPropertiesSet()");
	}

}

(5)Test

package com.iocbean;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class TestIOC {
	public static void main(String[] args) {
		System.out.println("现在开始初始化容器");
		AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(Config.class);
		System.out.println("初始化成功");

		User bean = ac.getBean(User.class);
		System.out.println(bean.getId());
		System.out.println(bean);
	}
}

二、流程图

三、说明

首先一共有两种方式可以定义Bean,一种是通过xml的方式,另一种是通过注解的方式,加载配置文件来启动ApplicationContext,

执行ClassPathXmlApplicationContext的构造器函数,走到refresh()方法

			// Prepare this context for refreshing.
			//准备工作,记录下容器的启动时间、标记"已启动“状态处理配置文件中的占位符
			prepareRefresh();

			//这步比较关键,这步完成后,配置文件就会解析成一个个Bean定义,注册到BeanFactory中,
			//当然,这里说的Bean还没有初始化,只是配置信息都提取出来了。
			//注册也只是将这些信息都保存到了注册中心(说到底核心是一个beanName->beanDefinition的map)
			// Tell the subclass to refresh the internal bean factory.
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
	@Override
	protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
		// Create a new XmlBeanDefinitionReader for the given BeanFactory.
		XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

		// Configure the bean definition reader with this context's
		// resource loading environment.
		beanDefinitionReader.setEnvironment(getEnvironment());
		beanDefinitionReader.setResourceLoader(this);
		beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

		// Allow a subclass to provide custom initialization of the reader,
		// then proceed with actually loading the bean definitions.
		initBeanDefinitionReader(beanDefinitionReader);
		loadBeanDefinitions(beanDefinitionReader);
	}

通过beanDefinitionReader来读取。
然后到BeanDefinition,通过Spring容器来存储bean,首先进行实例化 

finishBeanFactoryInitialization

然后我们进去这个方法里面,走到最后面发现,有一个实例化剩下的非懒加载的单例对象

	//实例化剩下的所有的非懒加载的单例对象
		// Instantiate all remaining (non-lazy-init) singletons.
		beanFactory.preInstantiateSingletons();
	//如果beanName对应的bean不是FactoryBean,只是普通的bean,通过beanName获取bean实例
					getBean(beanName);
	@Override
	public Object getBean(String name) throws BeansException {
		//此方法是实际获取bean的方法,也是触发依赖注入的方法
		return doGetBean(name, null, null, false);
	}
	protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
			@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

		final String beanName = transformedBeanName(name);
		Object bean;
		// 接下来就是获取bean的对象
		// 尝试通过bean名称获取目标bean对象,比如这里的A对象
		// Eagerly check singleton cache for manually registered singletons.
		Object sharedInstance = getSingleton(beanName);
	Object singletonInstance = getSingleton(beanName);
@Nullable
	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		//尝试从缓存中获取成品的目标对象,如果存在,则直接返回
		Object singletonObject = this.singletonObjects.get(beanName);
		//如果缓存中不存在目标对象,则判断当前对象是否已经处于创建过程中,
		//第一次尝试获取A对象的实例之后,就会将A对象标记为正在创建中,因而最后再尝试获取A对象的时候这里的if就会为true
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
			synchronized (this.singletonObjects) {
				singletonObject = this.earlySingletonObjects.get(beanName);
				if (singletonObject == null && allowEarlyReference) {
					//这里的singletonFactories是一个map ,其key是bean的名称,而值是一个ObjectFactory类型的
					//对象,这里对于A和B而言,调用getObject()方法返回的就是A和B对象的实例,无论是否是半成品
					ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
					if (singletonFactory != null) {
						//获取目标对象的实例
						singletonObject = singletonFactory.getObject();
						this.earlySingletonObjects.put(beanName, singletonObject);
						this.singletonFactories.remove(beanName);
					}
				}
			}
		}
		return singletonObject;
	}

从代码中可以看出,先出一级缓存中查询是否有当前的bean对象,如果是第一次的话,没有则返回null。

接下来就是createBean了

			//这里的目标对象都是单例的
				// Create bean instance.
				if (mbd.isSingleton()) {
					//这里就尝试创建目标对象。第二个参数传的就是一个ObjectFactory类型的对象,这里是
					//使用Java8的lamada表达式写的,只要上面的getSingleton()方法返回值为空,则会调用这里的
					//getSingleton方法
					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);
							throw ex;
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}
	try {
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			if (logger.isDebugEnabled()) {
				logger.debug("Finished creating instance of bean '" + beanName + "'");
			}
			return beanInstance;
		}

没有就创建实例

		//没有就创建实例
		if (instanceWrapper == null) {
			//根据执行bean使用对应的策略创建新的实例,如:工厂方法,构造函数主动注入,简单初始化
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		//如果支持,这里就会将当前生产的半成品的bean放到singletonFactories中,
			//这个singletonFactories 就是前面第一个getSingleton()方法中所使用的singletonFactories属性,也就是说
			//这里就是封装半成品的bean的地方,而这里的getEarlyBeanReference()本质上
			//是直接将放入的第三个参数,也就是目标bean直接返回
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
//在初始化实例之后,这里就是判断当前bean是否依赖了其他的bean,如果依赖了
			//就会递归的调用getBean()方法尝试获取目标bean
			populateBean(beanName, mbd, instanceWrapper);
initializeBean(beanName, exposedObject, mbd);

//BeanNameAware,BeanFactoryAware, ApplicationContextAware

	invokeAwareMethods(beanName, bean);
applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);

InitializingBean的afterPropertiesSet<init-method>

InitializingBean的afterPropertiesSet<init-method>
applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

这就是初始化完成

四、applicationContext和beanFactory

BeanFactory在启动的时候不会去实例化Bean,中有从容器中拿Bean的时候才会去实例化;

ApplicationContext在启动的时候就把所有的Bean全部实例化了。它还可以为Bean配置lazy-init=true来让Bean延迟实例化; 

五、总结

以上是关于从源码分析Spring的生命周期的主要内容,如果未能解决你的问题,请参考以下文章

spring源码分析:spring生命周期

Spring源码分析系列-Bean的生命周期(总结篇)

Spring源码分析系列-Bean的生命周期(总结篇)

Spring源码分析系列-Bean的生命周期(总结篇)

Spring源码分析系列-Bean的生命周期(总结篇)

Spring源码分析系列-Bean的生命周期(总结篇)