当前位置:网站首页>bean的生命周期核心步骤总结
bean的生命周期核心步骤总结
2022-07-01 18:36:00 【51CTO】
BFPP与BPP说明
后续行文为了方便,用BFPP代指BeanFactoryPostProcessor,用BPP代指BeanPostProcessor。
xml/注解方式开启spring
容器创建
refresh() 中的obtainFreshBeanFactory()
创建容器
创建的是DefaultListableBeanFactory
设置容器属性值
加载bean定义信息
包含非常多的重名重载方法,建议debug调试查看,不然容易晕。
xlm转换成document
document解析成element
parseDefaultElement(ele, delegate)
默认的指bean
delegate.parseCustomElement(ele)
自定义的指以context、aop等开头或者自定义的标签。
以上两种标签解析后的结果都封装在BeanDefinition中,获取的是GenericBeanDefinition,后续实例化用的是RootBeanDefinition,需要进行一个合并。
给容器工厂设置属性值
prepareBeanFactory(beanFactory);
设置类加载器等
postProcessBeanFactory
空方法,供子类实现。
实例化和执行BFPP
调用和执行BFPP,操作的对象是BeanFactory,可以创建、修改或者引入其他的BeanDefinition,里面有个非常重要的类,ConfigurationClassPostProcessor
ConfigurationClassPostProcessor
完成@Bean,@[email protected],@Import,@ImportSource等注解的解析
完成BPP的实例化与注册
registerBeanPostProcessors(beanFactory),完成BPP的注册与实例化,方便后续在创建bean过程完成之后调用before/after方法堆bean进行增强。
完成自定义对象的创建
finishBeanFactoryInitialization(beanFactory)
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
将需要创建的对象放到list中,逐一进行创建。
getMergedLocalBeanDefinition会将上文提到的GenericBeanDefinition转换成RootBeanDefinition
for (
String
beanName :
beanNames) {
RootBeanDefinition
bd
=
getMergedLocalBeanDefinition(
beanName);
if (
!
bd.
isAbstract()
&&
bd.
isSingleton()
&&
!
bd.
isLazyInit()) {
if (
isFactoryBean(
beanName)) {
Object
bean
=
getBean(
FACTORY_BEAN_PREFIX
+
beanName);
if (
bean
instanceof
SmartFactoryBean
<?>
smartFactoryBean
&&
smartFactoryBean.
isEagerInit()) {
getBean(
beanName);
}
}
else {
getBean(
beanName);
}
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
getBean
doGetBean
先从容器中找,如果没有再创建
createBean
doCreataBean
createBeanInstance
创建bean有多重方式
getInstanceSupplier(Supplier方式创建)
instantiateUsingFactoryMethod(FactoryMethod方式创建)
instantiateBean(默认的,反射方式创建)
instantiateBean
其实还有个BPP代理模式创建对象,但不是在createBeanInstance,而是在前面的步骤
最终调用反射进行bean的创建
注册生命周期接口
也就是applyMergedBeanDefinitionPostProcessors
// Allow post-processors to modify the merged bean definition.
synchronized (
mbd.
postProcessingLock) {
if (
!
mbd.
postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(
mbd,
beanType,
beanName);
}
catch (
Throwable
ex) {
throw
new
BeanCreationException(
mbd.
getResourceDescription(),
beanName,
"Post-processing of merged bean definition failed",
ex);
}
mbd.
postProcessed
=
true;
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
再此步骤完成@PostConstruct、@PreDestory、@Resource、@Autowire、@Value注解的解析工作。
填充属性populateBean
创建依赖的对象,循环依赖问题再此触发
进行初始化initializeBean
执行invokeAwareMethods
private
void
invokeAwareMethods(
String
beanName,
Object
bean) {
if (
bean
instanceof
Aware) {
if (
bean
instanceof
BeanNameAware) {
((
BeanNameAware)
bean).
setBeanName(
beanName);
}
if (
bean
instanceof
BeanClassLoaderAware) {
ClassLoader
bcl
=
getBeanClassLoader();
if (
bcl
!=
null) {
((
BeanClassLoaderAware)
bean).
setBeanClassLoader(
bcl);
}
}
if (
bean
instanceof
BeanFactoryAware) {
((
BeanFactoryAware)
bean).
setBeanFactory(
AbstractAutowireCapableBeanFactory.
this);
}
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
执行BPP的before方法
ApplicationAwarePostProcessors、CommonAnnotationBeanPostProcessor等
invokeInitMethods
如果实现了InitializingBean接口,需要调用afterPropertiesSet,最后一次修改属性值
执行用户自定义的init-method(invokeCustomInitMethod)
执行BPP的after方法
aop功能再此实现。

销毁对象
destroyBeans()
边栏推荐
- Lumiprobe非荧光炔烃丨EU(5-乙炔基尿苷)
- [source code analysis] model parallel distributed training Megatron (5) -- pipestream flush
- Leetcode-141环形链表
- R language ggplot2 visualization: gganimate package transition_ Time function to create dynamic scatter animation (GIF), shadow_ The wake function configures the gradient falloff tailing effect of the
- Bernoulli distribution (a discrete distribution)
- C# SelfHost WebAPI (2)
- Search 2D matrix 2
- Privacy sandbox is finally coming
- 如何运营好技术相关的自媒体?
- 每周推薦短視頻:警惕“現象”與“問題”相互混淆
猜你喜欢

Three.js学习-相机Camera的基本操作(了解向)

Mise en place d'une plate - forme générale de surveillance et d'alarme, quelles sont les conceptions nécessaires dans l'architecture?

Leetcode-141环形链表

How to find the optimal learning rate

6款红黄黑榜摄像头评测:谁最安全?谁画质好?从此让你不再踩雷

Lumiprobe non fluorescent alkyne EU (5-ethynyluridine)

Leetcode-21 combines two ordered linked lists

Sum of three numbers

实例讲解将Graph Explorer搬上JupyterLab

Memo - about C # generating barcode
随机推荐
lefse分析
创建您自己的NFT集合并发布一个Web3应用程序来展示它们(介绍)
解决方案:可以ping别人,但是别人不能ping我
Facebook聊单,SaleSmartly有妙招!
What designs are needed in the architecture to build a general monitoring and alarm platform
字节跳动数据平台技术揭秘:基于 ClickHouse 的复杂查询实现与优化
app发版后的缓存问题
Li Kou daily question - Day 32 -1232 Dotted line
12. Design of power divider for ads usage record
宏观视角看抖音全生态
R语言epiDisplay包ordinal.or.display函数获取有序logistic回归模型的汇总统计信息(变量对应的优势比及其置信区间、以及假设检验的p值)、write.csv函数保存csv
PriorityQueue的用法和底层实现原理
Thread forced join, thread forced join application scenarios
About enterprise middle office planning and it architecture microservice transformation
Must see, time series analysis
GameFramework食用指南
Li Kou daily question - Day 32 -589 N × Preorder traversal of tree
R语言使用dplyr包的transmute函数计算dataframe数据中的指定数据列的移动窗口均值、使用ggplot2包可视化移动均值与原始数据的折线图
Operation of cmake under win
12 data dimensioning processing methods