Spring的Bean生命周期要从容器的创建过程开始,这篇笔记只是备忘一下,否则看源码这将是一件没有任何意义的事情。
容器的创建可以从这里开始看
public class MainTest7 {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig7.class);
}
}
点击到new AnnotationConfigApplicationContext里面可以发现有这3个方法,下面目录就是具体代码描述
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
register(annotatedClasses);
refresh();
}
文章目录
1. 上下文初始化
this():进行一些context的初始化工作,为后续refresh做准备
2. 注册配置类
register(Class<?>… annotatedClasses):注册一个或者多个配置类,比如被@Configuration注解标注的类
3. 刷新容器(refresh方法)
3.1 BeanFactory的创建及预准备工作
3.1.1 prepareRefresh():刷新前的预处理
1. initPropertySources():初始化一些配置文件的属性
2. getEnvironment().validateRequiredProperties():检验属性的合法性等
3. earlyApplicationEvents = new LinkedHashSet():保存容器中的一些早期的事件
3.1.2 obtainFreshBeanFactory(): 获取BeanFactory
1. refreshBeanFactory():刷新创建BeanFactory,设置序列化ID
2. getBeanFactory():返回刚才GenericApplicationContext创建的BeanFactory对象
3. 将创建的BeanFactory(DefaultListableBeanFactory)返回
3.1.3 prepareBeanFactory(beanFactory):BeanFactory的预准备工作,对BeanFactory进行一些设置
1. 设置BeanFactory的类加载器、支持表达式解析器…
2. 添加部分BeanPostProcessor,如【ApplicationContextAwareProcessor】
3. 设置忽略的自动装配的接口:【EnvironmentAware】、【EmbeddedValueResolverAware】…
4. 注册可以解析的自动装配:我们能直接在任何组件中自动注入:【BeanFactory】、【ResourceLoader】、【ApplicationEventPublisher】、【ApplicationContext】
5. 添加BeanPostProcessor【ApplicationListenerDetector】
6. 添加AspectJ的BeanPostProcessor【LoadTimeWeaverAwareProcessor】;
7. 给BeanFactory中注册一些能用的组件:environment【ConfigurableEnvironment】、systemProperties【Map<String, Object>】、systemEnvironment【Map<String, Object>】
3.1.4 postProcessBeanFactory(beanFactory):BeanFactory准备工作完成后进行的后置处理工作
1. 这是一个”protected“修饰的方法,子类通过重写这个方法来在BeanFactory创建完成后做进一步的设置
3.2 执行BeanFactory后置处理器流程
3.2.1 invokeBeanFactoryPostProcessors(beanFactory):执行BeanFactoryPostProcessor
1. 获取所有的BeanDefinitionRegistryPostProcessor
2. 获取实现了PriorityOrdered优先级接口的BeanDefinitionRegistryPostProcessor,将其存入currentRegistryProcessors数组中
3. sortPostProcessors(currentRegistryProcessors, beanFactory):对所有BeanDefinitionRegistryPostProcessor进行排序
4. registryProcessors.addAll(currentRegistryProcessors):注册所有BeanDefinitionRegistryPostProcessor
5. invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup()):执行所有BeanDefinitionRegistryPostProcessor
6. 在获取实现了Ordered优先级接口的BeanDefinitionRegistryPostProcessor,重复步骤同上面的 3 ~ 5
7. 对没有实现任何优先级接口的BeanDefinitionRegistryPostProcessor,重复步骤同上面的 3 ~ 5
8. 处理完BeanDefinitionRegistryPostProcessor之后才会处理BeanFactoryPostProcessor,处理过程和BeanDefinitionRegistryPostProcessor相同
3.3 注册Bean的后置处理器
3.3.1 registerBeanPostProcessors(beanFactory):注册BeanPostProcessor(Bean的后置处理器)
不同接口类型的BeanPostProcessor,在Bean创建前后的执行时机是不一样的
1. 获取所有的 BeanPostProcessor:后置处理器都默认可以通过PriorityOrdered、Ordered接口来执行优先级
2. 先注册PriorityOrdered优先级接口的BeanPostProcessor,把每一个BeanPostProcessor添加到BeanFactory中,通过beanFactory.addBeanPostProcessor(postProcessor);
3. 再注册实现Ordered接口的BeanPostProcessor并加入BeanFactory
4. 接着注册没有实现任何优先级接口的
5. 最终注册MergedBeanDefinitionPostProcessor
6. 继续注册ApplicationListenerDetector在Bean创建完成后检查是否是ApplicationListener,如果是则调用applicationContext.addApplicationListener((ApplicationListener<?>) bean)方法将其添加进容器中
3.4 注册国际化组件
3.4.1 initMessageSource():初始化MessageSource组件(做国际化功能;消息绑定,消息解析)
1. 获取BeanFactory查看容器中是否有id为messageSource的,类型是MessageSource的组件
如果有赋值给messageSource,如果没有自己创建一个DelegatingMessageSource
2. 把创建好的MessageSource注册在容器中,以后获取国际化配置文件的值的时候,可以自动注入MessageSource
3.4 注册事件派发器
3.4.1 initApplicationEventMulticaster();初始化事件派发器
1. 从BeanFactory获取类型为ApplicationEventMulticaster的applicationEventMulticaster;
2. 如果上一步没有获取成功;则创建一个SimpleApplicationEventMulticaster将创建的ApplicationEventMulticaster添加到BeanFactory中,以后可自动注入
3.5 子容器初始化bean
onRefresh():子类容器重写这个方法,在容器刷新的时候可以自定义逻辑
3.6 注册监听器
将所有ApplicationListener注册进行注册
1. getApplicationEventMulticaster().addApplicationListener(listener):拿到所有ApplicationListener并注册
2. getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName):从BeanFactory获取所有类型为ApplicationListener的bean并注册
3. getApplicationEventMulticaster().multicastEvent(earlyEvent):派发早期事件
3.7 完成BeanFactory初始化,实例化Bean
finishBeanFactoryInitialization(beanFactory):初始化所有剩下的单实例bean;
- beanFactory.preInstantiateSingletons():初始化后剩下的单实例bean
- 获取Bean的定义信息;RootBeanDefinition
- 如果Bean不是抽象的,是单实例的,不是懒加载:
- 判断是否是FactoryBean;是否是实现FactoryBean接口的Bean(FactoryBean是创建对象的模板)
- 如果不是工厂Bean。则利用getBean(beanName);创建对象getBean(beanName) —> doGetBean(name, null, null, false);
1. 先获取缓存中保存的单实例Bean。如果能获取到说明这个Bean之前被创建过(所有创建过的单实例Bean都会被缓存起来)【Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256)】
2. 缓存中获取不到,开始Bean的创建对象流程
3. 标记当前bean已经被创建
4. 获取Bean的定义信息
5. 获取当前Bean依赖的其他Bean,如果有按照getBean()把依赖的Bean先创建出来
6. 启动单实例Bean的创建流程
1. createBean(beanName, mbd, args);
2. Object bean = resolveBeforeInstantiation(beanName, mbdToUse):让BeanPostProcessor先拦截返回代理对象;
3. 如果前面的InstantiationAwareBeanPostProcessor没有返回代理对象;调用4)
4. Object beanInstance = doCreateBean(beanName, mbdToUse, args):创建Bean
1. 【创建Bean实例】;createBeanInstance(beanName, mbd, args);利用工厂方法或者对象的构造器创建出Bean实例
2. applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);调用MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition(mbd, beanType, beanName);
3. 【Bean属性赋值】populateBean(beanName, mbd, instanceWrapper);
1.赋值之前先拿到InstantiationAwareBeanPostProcessor后置处理器:postProcessAfterInstantiation();
2.再拿到InstantiationAwareBeanPostProcessor后置处理器:postProcessPropertyValues()
3.最后应用Bean属性的值;为属性利用setter方法等进行赋值;
4. 【Bean初始化】initializeBean(beanName, exposedObject, mbd);
1.【执行Aware接口方法】invokeAwareMethods(beanName, bean);执行xxxAware接口的方法
2.【在初始化之前应用 Bean 后处理器】applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
3.【调用初始化方法】invokeInitMethods(beanName, wrappedBean, mbd);
1. 是否是InitializingBean接口的实现;执行接口规定的初始化;
2. 是否自定义初始化方法;
4.【初始化后应用 Bean 后处理器】applyBeanPostProcessorsAfterInitialization
5. 注册Bean的销毁方法;
5. 将创建的Bean添加到缓存中singletonObjects; - 所有Bean都利用getBean创建完成以后;检查所有的Bean是否是SmartInitializingSingleton接口的;如果是;就执行afterSingletonsInstantiated();
3.8 完成
finishRefresh():最后一步,发布相应事件
更多看这里吧😁
Spring Bean生命周期详解
本文详细剖析了Spring容器的创建过程以及Bean的生命周期,从上下文初始化、注册配置类到刷新容器,涵盖BeanFactory的创建、后置处理器的执行、国际化组件注册、事件派发器初始化等多个关键步骤。深入理解这些流程对于源码阅读至关重要。
1086

被折叠的 条评论
为什么被折叠?



