Spring框架学习:Bean生命周期

本文详细解析了SpringBean的生命周期过程,重点在于初始化阶段,包括属性填充、Aware接口应用、循环引用处理及三级缓存机制。同时介绍了如何通过Aware接口获取Spring容器中的其他对象。

目录

SpringBean的生命周期

Bean实例属性填充

三级缓存

常用的Aware接口

Spring IoC容器实例化Bean总结


SpringBean的生命周期

Spring Bean的生命周期是从 Bean 实例化之后,即通过反射创建出对象之后,到Bean成为一个完整对象,最终存储到单例池中,这个过程被称为Spring Bean的生命周期。Spring Bean的生命周期大体上分为三个阶段:

  • Bean的实例化阶段:Spring框架会取出BeanDefinition的信息进行判断当前Bean的范围是否是singleton,是否不是延迟加载的,是否不是FactoryBean等,最终将一个普通的singleton的Bean通过反射进行实例化;
  • Bean的初始化阶段:Bean创建之后还仅仅是个"半成品",还需要对Bean实例的属性进行填充、执行一些Aware接口方法、执行BeanPostProcessor方法、执行InitializingBean接口的初始化方法、执行自定义初始化init方法等。该阶段是Spring最具技术含量和复杂度的阶段,Aop增强功能,Spring的注解功能等。以及Bean的循环引用问题都是在这个阶段体现的。
  • Bean的完成阶段:经过初始化阶段,Bean就成为了一个完整的Spring Bean,被存储到单例池singletonObjects中去。即完成了Spring Bean的整个生命周期。

接下来我们着重于Bean的初始化阶段进行分析,初始化过程涉及如下几个过程:

  • Bean实例的属性填充
  • Aware接口属性注入
  • BeanPostProcessor的before()方法回调
  • InitializingBean接口的初始化方法回调
  • 自定义初始化方法inti回调
  • BeanPostProcessor的after()方法回调

Bean实例属性填充

基于xml文件的实例属性填充。

<bean id="userService" class="com.zmt.service.impl.UserServiceImpl">
  <property name="userDao" ref="userDao"></property>
  <property name="name" value="张三"></property>
</bean>

在属性注入中,存在三种情况:

  • 一种基本属性注入,通过反射拿到set方法直接注入
  • 一种单项引用属性注入,如UserService中需要注入UserDao,但UserDao不需要UserService,这种从容器中执行getBean方法后通过set方法反射进去,如果容器中不存在,则先创建被注入的对象后再进行诸如操作。
  • 一种双向对象属性注入,也就是说,UserService中需要注入UserDao,UserDao需要注入UserService。这涉及到循环引用。

下面是循环引用的问题流程图

如果循环依赖的话,半成品的bean会被存储在内存中,不归Spring管控,那么在注入时,就无法从容器中获取到对应的bean,从而导致死循环不停的创建对象。解决方法是,在Spring中添加一个存储半成品bean的map,当无法从单例池中获取的对象时,从半成品中的map获取

三级缓存

所谓三级缓存,分别是单例池与两个存储半成品bean的map集合,在源码中为

这三个Map集合,分别存储的是:

  • 实例化与初始化都完成的bean,称为一级缓存
  • 缓存半成品,且对象已经被其他对象引用了,称为二级缓存
  • 缓存半成品,对象也未被引用,使用时在通过工厂创建bean,称为三级缓存

UserService和UserDao循环依赖的过程结合上述三级缓存描述一下就是

  • UserService 实例化对象,但尚未初始化,将UserService存储到三级缓存;
  • UserService 属性注入,需要UserDao,从缓存中获取,没有UserDao;
  • UserDao实例化对象,但尚未初始化,将UserDao存储到到三级缓存;
  • UserDao属性注入,需要UserService,从三级缓存获取UserService,UserService从三级缓存移入二级缓存;
  • UserDao执行其他生命周期过程,最终成为一个完成Bean,存储到一级缓存,删除二三级缓存;
  • UserService 注入UserDao;
  • UserService执行其他生命周期过程,最终成为一个完成Bean,存储到一级缓存,删除二三级缓存。

常用的Aware接口

Aware接口是一种框架辅助属性注入的一种思想,其他框架中也可以看到类似的接口。框架具备高度封装性,我们接触到的一般都是业务代码,一个底层功能API不能轻易的获取到,但是这不意味着永远用不到这些对象,如果用到了就可以使用框架提供的类似Aware的接口,让框架给我们注入该对象。

Aware接口

回调方法

作用

ServletContextAware

setServletContext(ServletContext context)

Spring框架回调方法注入ServletContext,web环境下才生效

BeanFactoryAware

setBeanFactory(BeanFactory factory)

Spring框架回调方法注入beanFactory对象

BeanNameAware

setBeanName(String beanName)

Spring框架回调方法注入当前Bean在容器中的beanName

ApplicationContextAware

setApplicationContext(Application application)

Spring框架回调方法注入ApplicationContext对象

Spring IoC容器实例化Bean总结

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zmbwcx2003

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值