Bean的生命周期
一,bean生命周期概述
Spring Boot 中的 Bean 生命周期通常遵循以下过程:
- 实例化:容器根据配置或注解等信息创建 Bean 的实例。
- 属性设置:容器将依赖注入到 Bean 的属性中。
- 初始化方法调用:如果 Bean 实现了
InitializingBean
接口,或者在配置中使用@PostConstruct
注解标记了初始化方法,容器会在依赖注入完成后调用这些初始化方法。 - 使用:Bean 可以被其他 Bean 或组件使用。
- 销毁方法调用:如果 Bean 实现了
DisposableBean
接口,或者在配置中使用@PreDestroy
注解标记了销毁方法,容器在 Bean 被销毁之前会调用这些方法。
二,Bean生命周期源码
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 设置转换服务(ConversionService),如果容器中包含并且类型匹配,则进行设置
if (beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) {
beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class));
}
// 如果容器中没有嵌入式值解析器,则添加一个,用于解析属性占位符
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver((strVal) -> {
return this.getEnvironment().resolvePlaceholders(strVal);
});
}
// 获取所有实现了 LoadTimeWeaverAware 接口的 Bean 的名称,然后依次获取这些 Bean 实例
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
this.getBean(weaverAwareName);
}
// 设置临时类加载器为空,并冻结配置,确保不再允许对 Bean 工厂的配置进行修改
beanFactory.setTempClassLoader((ClassLoader)null);
beanFactory.freezeConfiguration();
// 预实例化所有单例 Bean,确保所有单例 Bean 都提前实例化
beanFactory.preInstantiateSingletons();
}
接下来进入beanFactory.preInstantiateSingletons()这个方法中:
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
// 转换bean名称
String beanName = this.transformedBeanName(name);
// 检查单例实例是否存在
Object sharedInstance = this.getSingleton(beanName);
Object beanInstance;
if (sharedInstance != null && args == null) {
// 如果单例实例存在,则返回它
if (this.logger.isTraceEnabled()) {
if (this.isSingletonCurrentlyInCreation(beanName)) {
this.logger.trace("正在返回尚未完全初始化的循环引用的单例bean'" + beanName + "'的急切缓存实例");
} else {
this.logger.trace("正在返回缓存的单例bean实例'" + beanName + "'");
}
}
// 获取bean实例对象
beanInstance = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
} else {
// 处理创建新的bean实例
// 检查原型作用域的bean是否正在创建中
if (this.isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 检查是否有父级Bean工厂以及bean定义是否存在
BeanFactory parentBeanFactory = this.getParentBeanFactory();
if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
String nameToLookup = this.originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
AbstractBeanFactory abf = (AbstractBeanFactory) parentBeanFactory;
return abf.doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
}
// 从父级Bean工厂获取bean
// 为简洁起见,省略了代码
}
// 如果不仅执行类型检查,则将bean标记为已创建
if (!typeCheckOnly) {
this.markBeanAsCreated(beanName);
}
// 开始bean创建过程
StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate").tag("beanName", name);
try {
// 检查是否指定了所需的类型
if (requiredType != null) {
Objects.requireNonNull(requiredType);
beanCreation.tag("beanType", requiredType::toString);
}
// 获取合并的bean定义
RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
this.checkMergedBeanDefinition(mbd, beanName, args);
// 处理依赖关系
// 为简洁起见,省略了代码
// 根据作用域创建bean实例
// 为简洁起见,省略了代码
} catch (BeansException var32) {
// 处理bean创建过程中的异常
beanCreation.tag("exception", var32.getClass().toString());
beanCreation.tag("message", String.valueOf(var32.getMessage()));
this.cleanupAfterBeanCreationFailure(beanName);
throw var32;
} finally {
// 结束bean创建过程
beanCreation.end();
}
}
return this.adaptBeanInstance(name, beanInstance, requiredType);
}
doGetBean()方法字面意思就是创建实例,
三,情景再现
HR:说一下Bean的生命周期?
你:Bean的生命周期总的来说有四个阶段,分别是创建对象,初始化对象,使用以及销毁,且大部分工作是交还给Bean工厂的docreateBean()方法完成的:
首先,在创建对象的过程中,先调用构造方法实例化对象,然后注入依赖,
其次,在对象创建完毕之后会做一些初始化的操作:
1.执行Aware感知接口的回调方法,
2.执行Bean后置处理器的postProcessBeforeInitializer方法
3.执行Initializerbean接口的回调
4.执行Bean后置处理器,
上述步骤之后,Bean的初始化就完成了,接下来就是程序从容器中获取Bean并使用,
最后,在销毁容器之前,会先销毁对象。