BeanFactory的默认实现为DefaultListableBeanFactory,其中Bean生命周期与方法映射如下,建议参考源码一起看。
一、BeanDefinition注册阶段-registerBeanDefinition
这个阶段分为两个部分:首先通过 beanName 注册 BeanDefinition ,然后再注册别名 alias。
通过 beanName 注册
处理过程如下:
1、首先 BeanDefinition 进行校验,该校验也是注册过程中的最后一次校验了,主要是对 AbstractBeanDefinition 的 methodOverrides 属性进行校验
2、根据 beanName 从缓存中获取 BeanDefinition,如果缓存中存在,则根据 allowBeanDefinitionOverriding 标志来判断是否允许覆盖,如果允许则直接覆盖,否则抛出 BeanDefinitionStoreException 异常
3、若缓存中没有指定 beanName 的 BeanDefinition,则判断当前阶段是否已经开始了 Bean 的创建阶段,如果是,则需要对 beanDefinitionMap 进行加锁控制并发问题,否则直接设置即可。
4、若缓存中存在该 beanName 或者单例 bean 集合中存在该 beanName,则调用 resetBeanDefinition() 重置 BeanDefinition 缓存。
其实整段代码的核心就在于 this.beanDefinitionMap.put(beanName, beanDefinition);
BeanDefinition 的缓存也不是神奇的东西,就是定义 map ,key 为 beanName,value 为 BeanDefinition
注册 alias
BeanDefinitionRegistry.registerAlias 完成 alias 的注册,注册 alias 和注册 BeanDefinition 的过程差不多。在最好调用了 checkForAliasCircle() 来对别名进行了检测
二、BeanDefinition合并阶段-getMergedBeanDefinition
流程如下:
1、找到父BeanDefinition,如果没有找到就直接将自身当作父BeanDefinition,找到的话就看看父BeanDefinition有没有父BeanDefinition,并且通过getMergedBeanDefinition方法得到父BeanDefinition合并之后的BeanDefinition。
2、合并BeanDefinition,通过父BeanDefinition创建出一个RootBeanDefinition对象,然后子BeanDefinition覆盖父BeanDefinition创建出来的对象(覆盖属性之类的)。
3、将合并后的BeanDefinition放入一个mergedBeanDefinitions集合中,最后将合并后的BeanDefinition返回。
在其中我们需要注意其中几个地方:
三、Bean实例化前阶段-resolveBeforeInstantiation
这个阶段是一个不常用的操作,在这个阶段我们可以生成一个代理类来替换我们生成实例。底层是通过InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation方法。
四、Bean实例化阶段-createBeanInstance
创建bean的实例,负责创建的方法为createBeanInstance,具体代码如下:
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 解析class
Class> beanClass = resolveBeanClass(mbd, beanName);
//确保class不为空,并且访问权限为public
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());
}
//配置的一种特殊的callback回调方法,通过这个callback创建bean
Supplier> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
//通过工厂方法创建
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// 一个类可能有多个构造器,所以Spring得根据参数个数、类型确定需要调用的构造器
// 在使用构造器创建实例后,Spring会将解析过后确定下来的构造器或工厂方法保存在缓存中,避免再次创建相同bean时再次解析
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
//已经解析过class的构造器
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
//已经解析过class的构造器,使用已经解析好的构造器
if (autowireNecessary) {
//构造函数自动注入
return autowireConstructor(beanName, mbd, null, null);
}
else {
//使用默认构造器
return instantiateBean(beanName, mbd);
}
}
// 需要根据参数解析、确定构造函数
Constructor>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
// 解析的构造器不为空 || 注入类型为构造函数自动注入 || bean定义中有构造器参数 || 传入参数不为空
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
//构造函数自动注入
return autowireConstructor(beanName, mbd, ctors, args);
}
// 使用默认构造器
return instantiateBean(beanName, mbd);
}
五、Bean实例化后阶段-populateBean
在完成Bean实例化后,Spring容器会给这个Bean注入相关的依赖Bean,以及属性赋值。在源码中,这一步通过类AbstractAutowireCapableBeanFactory中的populateBean
方法完成。源码解析如下:
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
// pvs是一个MutablePropertyValues实例,里面实现了PropertyValues接口,提供属性的读写操作实现,同时可以通过调用构造函数实现深拷贝
// 在本例中,里面存在一个propertyValueList,里面只有一个propertyValue:key->value="student"->RuntimeBeanReference("")
PropertyValues pvs = mbd.getPropertyValues();
if (bw == null) {
if (!pvs.isEmpty()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// 空对象直接返回
return;
}
}
// 给InstantiationAwareBeanPostProcessors最后一次机会在属性注入前修改Bean的属性值
// 具体通过调用postProcessAfterInstantiation方法,如果调用返回false,表示不必继续进行依赖注入,直接返回
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
if (!continueWithPropertyPopulation) {
return;
}
// 根据Bean配置的依赖注入方式完成注入,默认是0,即不走以下逻辑,所有的依赖注入都需要在xml文件中有显式的配置
// 如果设置了相关的依赖装配方式,会遍历Bean中的属性,根据类型或名称来完成相应注入,无需额外配置
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
// 深拷贝当前已有的配置
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// 根据名称进行注入
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// // 根据类型进行注入
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
// 结合注入后的配置,覆盖当前配置
pvs = newPvs;
}
// 容器是否注册了InstantiationAwareBeanPostProcessor
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
// 是否进行依赖检查
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {
// 过滤出所有需要进行依赖检查的属性编辑器
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
// 如果有相关的后置处理器,进行后置处理
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
// 检查是否满足相关依赖关系,对应的depends-on属性,需要确保所有依赖的Bean先完成初始化
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
// 将pvs上所有的属性填充到BeanWrapper对应的Bean实例中,注意到这一步,TestBean的student属性还是RuntimeBeanReference,即还未解析实际的Student实例
applyPropertyValues(beanName, mbd, bw, pvs);
}
六、Bean初始化阶段-initializeBean
当BeanFactory将bean创建成功,并设置完成所有它们的属性后,需要进行初始化,通过initializeBean方法进行初始化,源码如下:
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction
整个初始化流程如下:
1、调用各类感知Aware接口
2、执行applyBeanPostProcessorsBeforeInitialization初始化前的 处置操作
3、调用InitializingBean接口初始化
4、如果配置了method-init,则调用其方法初始化
5、调用applyBeanPostProcessorsAfterInitialization 初始化之后的处置操作
七、Bean销毁阶段-destroyBean
1.率先销毁所有依赖于这个单例bean的所有bean,道理很简单,如果当前单例bean被销毁了,而依赖于当前单例bean的bean对象调用单例bean时必然会出现空指针异常
2.真正开始执行单例bean的destroy()方法来销毁bean
3.containedBeanMap销毁这个单例bean中包含的其他bean对象(即引入的依赖,但是实际上这个map好像并没有用到,而且引用的bean也不应该立即销毁,因为可能有其他bean同时也在引用,或许应该检查到没有引用的时候再销毁,但是spring中好像并没有这么做)
4.从依赖bean缓存列表dependentBeanMap中(键值对,如service->controller list)删除所有相关被依赖项
5.删除依赖列表dependenciesForBeanMap(键值对,如controller -> service list)
源码如下:
protected void destroyBean(String beanName, @Nullable DisposableBean bean) {
// Trigger destruction of dependent beans first...
Set dependencies;
synchronized (this.dependentBeanMap) {
// Within full synchronization in order to guarantee a disconnected Set
dependencies = this.dependentBeanMap.remove(beanName);
}
if (dependencies != null) {
if (logger.isTraceEnabled()) {
logger.trace("Retrieved dependent beans for bean '" + beanName + "': " + dependencies);
}
for (String dependentBeanName : dependencies) {
destroySingleton(dependentBeanName);
}
}
// 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);
}
}
}
// Trigger destruction of contained beans...
Set containedBeans;
synchronized (this.containedBeanMap) {
// Within full synchronization in order to guarantee a disconnected Set
containedBeans = this.containedBeanMap.remove(beanName);
}
if (containedBeans != null) {
for (String containedBeanName : containedBeans) {
destroySingleton(containedBeanName);
}
}
// Remove destroyed bean from other beans' dependencies.
synchronized (this.dependentBeanMap) {
for (Iterator>> it = this.dependentBeanMap.entrySet().iterator(); it.hasNext();) {
Map.Entry> entry = it.next();
Set dependenciesToClean = entry.getValue();
dependenciesToClean.remove(beanName);
if (dependenciesToClean.isEmpty()) {
it.remove();
}
}
}
// Remove destroyed bean's prepared dependency information.
this.dependenciesForBeanMap.remove(beanName);
}