当前位置:网站首页>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()
边栏推荐
- Go Technology Daily (2022-02-14) - go language slice interview real questions 8 consecutive questions
- 每周推荐短视频:警惕“现象”与“问题”相互混淆
- The R language cartools package divides the data, the scale function scales the data, the KNN function of the class package constructs the k-nearest neighbor classifier, and the table function calcula
- Relational database management system of easyclick
- Blue Bridge Cup real problem: word analysis
- R语言使用epiDisplay包的dotplot函数通过点图的形式可视化不同区间数据点的频率、使用pch参数自定义指定点图数据点的形状
- Lumiprobe biomolecular quantification - qudye Protein Quantification Kit
- Static timing analysis (STA) in ic/fpga design
- 磁盘的基本知识和基本命令
- 力扣每日一题-第32天-1232. 缀点成线
猜你喜欢

每周推荐短视频:警惕“现象”与“问题”相互混淆

What designs are needed in the architecture to build a general monitoring and alarm platform

研究了11种实时聊天软件,我发现都具备这些功能…

1. "Create your own NFT collections and publish a Web3 application to show them." what is NFT

Halcon图片标定,使得后续图片处理过后变成与模板图片一样

Image acquisition and playback of coaxpress high speed camera based on pxie interface

解决方案:可以ping别人,但是别人不能ping我

Lumiprobe 生物分子定量丨QuDye 蛋白定量试剂盒

Mysql database of easyclick

Write an open source, convenient and fast database document query and generation tool with WPF
随机推荐
Mise en place d'une plate - forme générale de surveillance et d'alarme, quelles sont les conceptions nécessaires dans l'architecture?
Write it down once Net travel management background CPU Explosion Analysis
Must see, time series analysis
Relational database management system of easyclick
Lumiprobe non fluorescent alkyne EU (5-ethynyluridine)
研究了11种实时聊天软件,我发现都具备这些功能…
Image acquisition and playback of coaxpress high speed camera based on pxie interface
关于企业中台规划和 IT 架构微服务转型
实现一个Prometheus exporter
LiveData postValue会“丢”数据
如何运营好技术相关的自媒体?
用WPF写一款开源方便、快捷的数据库文档查询、生成工具
R language uses the transmute function of dplyr package to calculate the moving window mean value of the specified data column in dataframe data, and uses ggplot2 package to visualize the line graph b
Thread forced join, thread forced join application scenarios
搭建一个通用监控告警平台,架构上需要有哪些设计
app发版后的缓存问题
How to change guns for 2D characters
How does factor analysis calculate weights?
Leetcode-128 longest continuous sequence
如何运营好技术相关的自媒体?