spring --bean的生命周期
bean生命周期 概述
protected <T> T doGetBean( String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
bean的生命周期从调用BeanFactory的doGetBean开始,到这个bean被销毁,可以总结为以下七个阶段
- 处理名称,检查缓存
- 处理父子容器
- 处理dependsOn
- 选择Scope策略
- 创建bean
- 类型转换处理
- 销毁bean
1.处理名称,检查缓存
-
-
对 FactoryBean 也会特殊处理,如果以 & 开头表示要获取 FactoryBean 本身,否则表示要获取其产品
-
这里针对单例对象会检查一级、二级、三级缓存
-
singletonFactories 三级缓存,存放单例工厂对象
-
earlySingletonObjects 二级缓存,存放单例工厂的产品对象
-
如果发生循环依赖,产品是代理;无循环依赖,产品是原始对象
-
-
2. 处理父子容器
-
如果当前容器根据名字找不到这个 bean,此时若父容器存在,则执行父容器的 getBean 流程
-
父子容器的 bean 名称可以重复
3. 处理 dependsOn
-
如果当前 bean 有通过 dependsOn 指定了非显式依赖的 bean,这一步会提前创建这些 dependsOn 的 bean
-
所谓非显式依赖,就是指两个 bean 之间不存在直接依赖关系,但需要控制它们的创建先后顺序
4. 选择 scope 策略
-
对于 singleton scope,首先到单例池去获取 bean,如果有则直接返回,没有再进入创建流程
-
对于 prototype scope,每次都会进入创建流程
-
对于自定义 scope,例如 request,首先到 request 域获取 bean,如果有则直接返回,没有再进入创建流程
5.1 创建 bean - 创建 bean 实例
|
要点 | 总结 |
---|---|
AutowiredAnnotationBeanPostProcessor | 识别 @Autowired 及 @Value 标注的成员,封装为 InjectionMetadata 进行依赖注入 |
CommonAnnotationBeanPostProcessor | 识别 @Resource 标注的成员,封装为 InjectionMetadata 进行依赖注入 |
resolveDependency | 用来查找要装配的值,可以识别:① Optional;② ObjectFactory 及 ObjectProvider;③ @Lazy 注解;④ @Value 注解(${ }, #{ }, 类型转换);⑤ 集合类型(Collection,Map,数组等);⑥ 泛型和 @Qualifier(用来区分类型歧义);⑦ primary 及名字匹配(用来区分类型歧义) |
AUTOWIRE_BY_NAME | 根据成员名字找 bean 对象,修改 mbd 的 propertyValues,不会考虑简单类型的成员 |
AUTOWIRE_BY_TYPE | 根据成员类型执行 resolveDependency 找到依赖注入的值,修改 mbd 的 propertyValues |
applyPropertyValues | 根据 mbd 的 propertyValues 进行依赖注入(即xml中 <property name ref|value/> ) |
5.3 创建 bean - 初始化
要点 | 总结 |
---|---|
内置 Aware 接口的装配 | 包括 BeanNameAware,BeanFactoryAware 等 |
扩展 Aware 接口的装配 | 由 ApplicationContextAwareProcessor 解析,执行时机在 postProcessBeforeInitialization |
@PostConstruct | 由 CommonAnnotationBeanPostProcessor 解析,执行时机在 postProcessBeforeInitialization |
InitializingBean | 通过接口回调执行初始化 |
initMethod | 根据 BeanDefinition 得到的初始化方法执行初始化,即 <bean init-method> 或 @Bean(initMethod) |
创建 aop 代理 | 由 AnnotationAwareAspectJAutoProxyCreator 创建,执行时机在 postProcessAfterInitialization |
-
判断依据
-
如果实现了 DisposableBean 或 AutoCloseable 接口,则为可销毁 bean
-
如果自定义了 destroyMethod,则为可销毁 bean
-
如果采用 @Bean 没有指定 destroyMethod,则采用自动推断方式获取销毁方法名(close,shutdown)
-
如果有 @PreDestroy 标注的方法
-
-
存储位置
-
singleton scope 的可销毁 bean 会存储于 beanFactory 的成员当中
-
自定义 scope 的可销毁 bean 会存储于对应的域对象当中
-
prototype scope 不会存储,需要自己找到此对象销毁
-
-
6. 类型转换处理
-
如果 getBean 的 requiredType 参数与实际得到的对象类型不同,会尝试进行类型转换
7. 销毁 bean
-
销毁时机
-
singleton bean 的销毁在 ApplicationContext.close 时,此时会找到所有 DisposableBean 的名字,逐一销毁
-
自定义 scope bean 的销毁在作用域对象生命周期结束时
-
prototype bean 的销毁可以通过自己手动调用 AutowireCapableBeanFactory.destroyBean 方法执行销毁
-
-
同一 bean 中不同形式销毁方法的调用次序
-
优先后处理器销毁,即 @PreDestroy
-
其次 DisposableBean 接口销毁
-
最后 destroyMethod 销毁(包括自定义名称,推断名称,AutoCloseable 接口 多选一)
-
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!