SpringBean生命周期
SpringBean生命周期(~)
BeanDefinition的相关知识
Bean和BeanDefinition的关系
BeanDefinition就是Bean的一个元数据 由BeanDefinition得到的Bean
BeanDefinition是Bean在spring中的定义形态
BeanDefinition 存放到 BeanDefinitionMap的过程
在启动后 通过调用 Refresh方法,得到BeanDefinition对象,
然后通过调用refresh()方法中的invokeBeanFactoryPostProcessors(beanFactory)方法;通过拿到BeanFactory的后置处理器
拿到BeanFactory,然后通过实现BeanDefinitionRegistry中的registerBeanDefinition方法将BeanDefinition通过点put到BeanDefinitionMap中
原视频链接
源码
BeanDefinition 存放到 BeanDefinitionMap的过程 源码解析
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
Set<String> processedBeans = new HashSet();
ArrayList regularPostProcessors;
ArrayList registryProcessors;
int var9;
ArrayList currentRegistryProcessors;
String[] postProcessorNames;
if (beanFactory instanceof BeanDefinitionRegistry) {
/**将beanFactory强转成BeanDefinitionRegistry*/
BeanDefinitionRegistry registry = (BeanDefinitionRegistry)beanFactory;
regularPostProcessors = new ArrayList();
registryProcessors = new ArrayList();
Iterator var6 = beanFactoryPostProcessors.iterator();
while(var6.hasNext()) {
BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)var6.next();
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor)postProcessor;
/**通过这个方法去调用里面的registry方法去调用BeanDefinitionRegistry接口中的registerBeanDefinition方法*/
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
} else {
regularPostProcessors.add(postProcessor);
}
}
}
简述:
实例化(instantiateBean) —— 属性赋值(populateBean)—— 初始化(init) —— 销毁(destroy)
详细:
创建bean
如何扫描创建bean的?
- run()
- refreshContext()
- refresh()
- preInstantiateSingletons() 也就是bean对象的一个提前初始化
- doGetBean()
- createBean()
- 通过xml
/注解@(Bean)。。等等方式注册bean
他们都是在spring的 **application中的refresh方法**中用loadBeanDefinitions进行加载
//SpringApplication下的
import org.springframework.boot.SpringApplication;
SpringApplication类中 refresh方法
protected void refresh(ConfigurableApplicationContext applicationContext) {
applicationContext.refresh();
}
底层调用的是 public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {} 中的refresh方法
- 通过BeanDefinitionRegistry里面的BeanFactory和Registry进行后置处理
获得一个SpringBean的一个BeanDefinition对象
(有两个关键的属性:BeanName和BeanType) - 进行提前初始化调用getBean()方法
实例化(instantiateBean)
传入一个BeanName 通过 beanname去找到Bean对应的BeanType,通过反射 返回一个Object对象——也就是bean对象
BeanPostProcessors 代理 的注册功能,方便后期bean的一个拓展 (他是一个拓展点)
// Give BeanPostProcessors a chance to neturn a proxy instead of the target bean instance.
给BeanPostProcessors一个机会,将代理替换为目标bean实例。
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
// 拓展点,如何替换之前的bean?
-
通过BeanDefinitionRegistry
我们通过拿到BeanDefinitionRegistry对象,然后remove掉之前的bean的BeanDefinition对象,然后去注册我们自己的一个实现类的BeanDefinition
-
通过PostProcessors
通过PostProcessors判断是不是我们的beanname,然后return一个代理类
属性赋值 populateBean
- set
- construct
- @Resource autowireByName
- @AutoWire autowireByType
- 如果通过@AutoWire注入的时候有两个想同类型的bean,我们就要结合@Qualifier("BeanName")注入想要的bean
- 三级缓存解决循环依赖的问题
- 有aop的前提。
初始化(initializeBean)
调用三个aware方法
- BeanNameAware
- BeanFactoryAware
- ApplicationContextAware
BeanPostProcessor处理(拓展点)
而该接口下有两个方法
一个是前置处理postProcessBeforeInitialization
一个是后置处理postProcessAfterInitialization
里面的Init-Method (去实现相关接口)
其中 InitializingBeanj接口就是属于InitMethod
销毁(destroy)
与初始化相似
实现DisposableBean接口
调用destroy-method方法 (去实现相关接口)
注:
其中很多中间件框架的一些代码实现都是在实现InitializingBean和DisposableBean两个接口的时候进行
详细可以看这篇文章:spring生命周期详解
spring源码讲解
SpringBean的生命周期详解
- 进入到刷新的refresh方法
----------------------以下过程都是在finishBeanFactoryInitialization()方法中的preInstantiateSingletons()方法中进行------------------------------
- finishBeanFactoryInitialization(),完成bean工厂的初始化,初始化所有非懒加载bean
** 实例化 **
- preInstantiateSingletons(),实例化所有单例bean
- getBean()---->doGetBean(),判断该对象是否有初始化过,如果没有,就注入到IOC容器中
- 会使用BeanDifinition的isSingleton()方法对BeanDefinition进行判断,如果对象是单例情况下,调用createBean()
- resolveBeforeInstantiation()的applyBeanPostProcessorsBeforeInstantiation(),在实例化对象之前做增强
- 通过调用 doCreateBean() 里面的 createBeanInstance() 方法,利用反射实例化对象,拿到Bean的一个实例 BeanInstance
- createBeanInstance(),
** 属性赋值 **
- populateBean()的ibp.postProcessAfterInstantiation(),在实例化对象之后做增强
- populateBean()的applyPropertyValue()给对象的set方法赋值,autowireByName,autowireByType 属性赋值
** 初始化 **
- 执行doCreateBean()的 / initializeBean() /
- initializeBean()的invokeAwareMethods(),判断bean是否实现Aware的相关接口,如果实现了,则执行回调
- initializeBean()的applyBeanPostProcessorsBeforeInitialization(),需实现BeanPostProcessor接口,对初始化方法的前置增强
- invokeAwareInterfaces()检查是否实现ApplicationContextAware接口,如果有则回调bean的setApplicationContext()
- initializeBean()的invokeInitMethods()执行bean的初始化方法afterPropertiesSet(),需要实现InitializingBean接口。类似地,如果bean使用init-method声明了初始化方法,该方法也会被调用
- initializeBean()的applyBeanPostProcessorsAfterInitialization(),需实现BeanPostProcessor接口,对初始化方法的后置增强
** 销毁 **
17. bean已经准备就绪,可以被应用程序使用了,它们将一直驻留在应用上下文中,直到该应用上下文被销毁
18. 如果bean实现了DisposableBean接口,Spring将调用它的destroy()接口方法。同样,如果bean使用destroy-method声明了销毁方法,该方法也会被调用
obtainFreshBeanFactory() 方法总结
里面就调用了registerBeanDefinitions方法
- 该方法会解析所有 spring 配置文件(通常我们会放在 resources 目录下),将所有 配置文件中的 bean 定义封装成 BeanDefinition,加载到 BeanFactory 中
- 常见的,如果解析到 <context:component-scan base-package="" /> 注解时,会扫描 base-package 指定的目录,将该目录下使用指定注解(@Controller、@Service、@Component、@Repository)的bean 定义也同样封装成 BeanDefinition,加载到 BeanFactory 中
原文链接
本文来自博客园,作者:没有烦恼的猫猫,转载请注明原文链接:https://www.cnblogs.com/maomao777/p/16597303.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix