生命周期及相关流程
- 准备阶段。围绕bean信息的加载器的创建、bean定义信息的存储、bean工厂的创建展开
- 首先需要加载不同的bean读取器为后面beanDefinition的读取做准备。bean的加载离不开三种方式:xml方式,读取并解析xml标签及属性来加载bean;注解方式,扫描指定文件夹及子目录中的文件,将被对应注解(@Component、@Controller、@Configuration、@Service、@Repository)标注的类作为bean加载;类全限定名直接导入;这几种方式的加载需要几个读取器和一个扫描器XmlBeanDefinitionReader、AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner
- 创建beanFactory。DefaultListableBeanFactory beanFactory = this.createBeanFactory();
- 加载beanDefinition。this.loadBeanDefinitions(beanFactory);
- 基于不同的实现类创建beanDefinitionReader并初始化
- 通过beanDefinitionReader加载beanDefinition。reader.loadBeanDefinitions(configResources);
- 创建BeanDefinition。AbstractBeanDefinition bd = BeanDefinitionReaderUtils.createBeanDefinition(parent, className, this.getBeanClassLoader());
- 加载beanDefinition。将对应的Class赋值给BeanDefinition的beanClass属性,并加载或初始化其他属性,例如懒加载标志位
- 注册beanDefinition。而后将beanName和beanDefinition通过键值对的方式保存到一个map中,并挂载到BeanDefinitionRegistry(实际上beanFactory就实现了BeanDefinitionRegistry,这里就是挂载到beanFactory上)的beanDefinitionMap属性上。this.getRegistry().registerBeanDefinition(beanName, bd);
- 将beanFactory挂载到上下文中。this.beanFactory = beanFactory;
- bean的生命周期。如果不能从缓存中取到bean的实例,则需要创建bean实例,通过调用链getBean->doGetBean->createBean->doCreateBean,来获取bean
- 实例化。根据beanName从beanFactory的beanDefinitionMap中取出BeanDefinition,然后基于beanDefinition中的beanClass和其他属性进行反射创建。
- 属性赋值。给bean的属性赋初始值,这一步会进行依赖注入,在此利用三级缓存解决了循环依赖问题。
- 初始化。有四个扩展点
- XXXAware
- 初始化前
- 初始化
- 初始化后
准备阶段
从run方法开始
从run方法开始,逐步解析定位到bean生命周期逻辑。进入主启动类


这里主要用于启动spring的事件监听器,用于监听容器各个生命周期的各个事件,这个可以不管
SpringApplicationRunListeners listeners = this.getRunListeners(args);
listeners.starting();
创建spring容器类
context = this.createApplicationContext();
加载不同的beanDefinitionReader
在上下文的准备阶段,对bean创建有主要影响的就是beanDefinitionLoader的加载
this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);


众所周知bean的加载方式离不开三种方式:
- xml方式
- 注解方式
- 类限定名直接导入
基于这三种加载方式,需要各种不同的BeanDefinitionLoader,包括AnnotatedBeanDefinitionReader、XmlBeanDefinitionReader、ClassPathBeanDefinitionScanner,提前加载这些类为获取bean的class类做准备
到这上下文准备阶段(prepareContext)的bean加载准备就完成了
在refreshContext方法中同样需要为bean的创建做一些准备工作
this.refreshContext(context);
直接定位到里层的refresh()方法,它的三个实现类都会走AbstractApplicationContext中同步代码块的逻辑,这里面就包括了bean的生命周期的相关逻辑


创建beanFactory
在bean生命周期之前,需要提前创建beanFactory并初始化
其中在创建beanFacotry时会加载beanDefinition为后面bean的生命周期做准备:
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();

继续在refreshBeanFactory中定位beanDefinitions的处理逻辑:

加载beanDefinition
loadBeanDefinitions()函数会基于对应的reader加载beanDefinition,这里我们看loadBeanDefinitions的其中一个实现类AbstractXmlApplicationContext中的loadBeanDefinitions

继续看更深的实现逻辑



这里看PropertiesBeanDefinitionReader的loadBeanDefinitions(Resource resource)的方法实现

继续往下,主要看看BeanDefinition的生成逻辑,这里props是一个bean name与类全限定名的map


最后定位到registerBeanDefinition方法

看到createBeanDefinition方法的处理逻辑

如果classLoader不为空,会给beanDefinition的BeanClass赋值对应的class,其实就是拿到beanDefinition的Class;如果为空则给BeanClassName赋值

而这里注册器的作用就是存放beanDefinition的map

看其中一个实现类的代码

registerBeanDefinition本身也只是在map中存储一个BeanName-BeanDefinition的键值对
beanDefinition处理完成后,就进入bean生命周期逻辑中了
然后继续向下定位bean的生命周期代码逻辑:





doGetBean中会调用createBean方法

createBean中又会调用doCreateBean,doCreateBean方法中包含了bean生命周期的几乎所有阶段

bean生命周期
// AbstractBeanFactory.class
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
String beanName = this.transformedBeanName(name);
Object sharedInstance = this.getSingleton(beanName);
Object bean;
if (sharedInstance != null && args == null) {
...
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
} else {
...
try {
RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
...
// 判断是否是单例
if (mbd.isSingleton()) {
// 获取单例
sharedInstance = this.getSingleton(beanName, () -> {
try {
return this.createBean(beanName, mbd, args);
} catch (BeansException var5) {
this.destroySingleton(beanName);
throw var5;
}
});
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) {
...
} else {
...
}
} catch (BeansException var26) {
this.cleanupAfterBeanCreationFailure(beanName);
throw var26;
}
}
if (requiredType != null && !requiredType.isInstance(bean)) {
...
} else {
return bean;
}
}
在这个方法中会根据三级缓存机制拿到缓存的bean,如果都没有则会执行bean的创建流程,即执行createBean()方法,createBean()的核心逻辑都在doCreateBean()方法中,所以我们想要了解bean的生命周期需要集中学习这个代码的执行逻辑。
// AbstractAutowireCapableBeanFactory.class
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
}
// 实例化
if (instanceWrapper == null) {
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
...
// 判断是否是正在创建的单例Bean
boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
if (earlySingletonExposure) {
...
// 添加到三级缓存
this.addSingletonFactory(beanName, () -> {
return this.getEarlyBeanReference(beanName, mbd, bean);
});
}
Object exposedObject = bean;
try {
// 属性赋值
this.populateBean(beanName, mbd, instanceWrapper);
// 初始化
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
} catch (Throwable var18) {
if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) {
throw (BeanCreationException)var18;
}
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18);
}
...
}
bean的生命周期中的前三个阶段在doCreateBean()中都能定位到对应的方法:
- 实例化(this.createBeanInstance(beanName, mbd, args))
- 属性赋值(this.populateBean(beanName, mbd, instanceWrapper))
- 初始化(this.initializeBean(beanName, exposedObject, mbd))
实例化

入参
传入的参数有三个,第一个beanName没什么好说的,第二个是beanDefinition,第三个是其他参数,这里我们往回追述一下beanDefinition是从哪里取的


这里首先会从AbstractBeanFactory类的mergedBeanDefinitons这个map中取

如果取不到则会返回this.getMergedBeanDefinition(beanName, this.getBeanDefinition(beanName))的返回值,其中this.getBeanDefinition(beanName)获取到的beanDefinition对象其实是从beanDefinitionMap中取的,这就跟之前beanDefinition的创建和注册对上了


当前类也的确是BeanDefinitionRegistry的实现类之一

然后getMergedBeanDefinition方法实现中返回的方法实例也是基于getBeanDefinition返回对象进行重载的

通过反射获取bean实例

if (resolved) {
return autowireNecessary ? this.autowireConstructor(beanName, mbd, (Constructor[])null, (Object[])null) : this.instantiateBean(beanName, mbd);
} else {
...
}
resolved标识位表示是否已经确定好beanDefinition的构造方法,如果为true,则判断autowireNecessary标志位,该标志位表示是否需要对构造方法进行参数的依赖注入,如果为true,反射的构造方法调用时会拿到构造方法依赖注入的入参;如果为false,则调用反射的构造函数并返回实例
属性赋值

属性赋值的参数有三:beanName、beanDefinition和instanceWrapper(刚创建的bean实例对象)
初始化
// AbstractAutowireCapableBeanFactory.class
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(() -> {
this.invokeAwareMethods(beanName, bean);
return null;
}, this.getAccessControlContext());
} else {
this.invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
// 初始化前扩展
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
}
// 初始化
try {
this.invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable var6) {
throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6);
}
// 初始化后扩展
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
这里有四个扩展点:
- xxxAware。
- 初始化前。this.applyBeanPostProcessorsBeforeInitialization(bean, beanName)。
- 初始化。afterPropertiesSet()。
- 初始化后。this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName)。会执行AOP动态代理操作并返回动态代理对象。

发表回复