📕我是廖志伟,一名Java开发工程师、《Java项目实战——深入理解大型互联网企业通用技术》(基础篇)、(进阶篇)、(架构篇)清华大学出版社签约作家、Java领域优质创作者、CSDN博客专家、阿里云专家博主、51CTO专家博主、产品软文专业写手、技术文章评审老师、技术类问卷调查设计师、幕后大佬社区创始人、开源项目贡献者。
📘拥有多年一线研发和团队管理经验,研究过主流框架的底层源码(Spring、SpringBoot、SpringMVC、SpringCloud、Mybatis、Dubbo、Zookeeper),消息中间件底层架构原理(RabbitMQ、RocketMQ、Kafka)、Redis缓存、MySQL关系型数据库、 ElasticSearch全文搜索、MongoDB非关系型数据库、Apache ShardingSphere分库分表读写分离、设计模式、领域驱动DDD、Kubernetes容器编排等。不定期分享高并发、高可用、高性能、微服务、分布式、海量数据、性能调优、云原生、项目管理、产品思维、技术选型、架构设计、求职面试、副业思维、个人成长等内容。
🌾阅读前,快速浏览目录和章节概览可帮助了解文章结构、内容和作者的重点。了解自己希望从中获得什么样的知识或经验是非常重要的。建议在阅读时做笔记、思考问题、自我提问,以加深理解和吸收知识。阅读结束后,反思和总结所学内容,并尝试应用到现实中,有助于深化理解和应用知识。与朋友或同事分享所读内容,讨论细节并获得反馈,也有助于加深对知识的理解和吸收。💡在这个美好的时刻,笔者不再啰嗦废话,现在毫不拖延地进入文章所要讨论的主题。接下来,我将为大家呈现正文内容。
文章目录
- Bean生命周期
- 1. 实例化阶段:创建Bean的“空壳”
- 2. 属性注入阶段:给Bean“装配零件”
- 3. Aware接口回调:让Bean“认识环境”
- 4. BeanPostProcessor前置处理:统一“质检”
- 5. 初始化阶段:激活Bean的“功能”
- 6. BeanPostProcessor后置处理:最终“包装”
- 7. 运行阶段:Bean正式“上岗”
- 8. 销毁阶段:Bean的“善后工作”
- 现实世界类比
Bean生命周期
[实例化] → [属性注入] → [Aware回调] → [BeanPostProcessor前置处理] → [初始化] → [BeanPostProcessor后置处理] → [就绪可用] → [销毁]
1. 实例化阶段:创建Bean的“空壳”
触发时机:当Spring容器启动,或首次请求某个Bean时。
核心动作:
- 调用Bean的构造方法(如new UserServiceImpl()),生成一个“空壳”对象。
- 若使用工厂方法(如@Bean标注的方法),则执行工厂方法返回对象。
典型场景:
- 构造器中打印日志:“用户服务实例已创建”。
- 若构造器中有资源预加载(如加载本地文件),此时会执行。
2. 属性注入阶段:给Bean“装配零件”
触发时机:实例化完成后,立即进行。
核心动作:
- 通过@Autowired、@Value或XML的标签,给Bean的属性赋值。
- 注入其他Bean(如Service注入DAO)、基本类型值(如端口号)、集合等。
典型场景:
- 数据库连接池Bean在此阶段设置URL、用户名、密码。
- 微服务中,Feign客户端Bean在此阶段注入负载均衡器。
3. Aware接口回调:让Bean“认识环境”
触发时机:属性注入完成后,初始化前。
核心动作:
- Spring调用Bean实现的Aware接口方法,传递容器相关信息。
常见接口:
- BeanNameAware → 告知Bean它在容器中的名字(如userService)。
- ApplicationContextAware → 告知Bean它所属的Spring容器。
- EnvironmentAware → 让Bean获取环境变量(如开发/生产配置)。
典型场景:
- 动态获取其他Bean:例如,支付服务通过ApplicationContextAware拿到容器,根据业务类型实时获取不同的支付处理器。
- 读取环境变量:例如,根据EnvironmentAware判断当前是测试环境还是生产环境,切换日志级别。
4. BeanPostProcessor前置处理:统一“质检”
触发时机:Aware回调完成后,初始化逻辑执行前。
核心动作:
- Spring遍历所有BeanPostProcessor,执行postProcessBeforeInitialization()方法。
- 可对Bean进行修改(如替换属性值)或增强(如添加监控逻辑)。
典型场景:
- 属性校验:检查数据库配置Bean的URL是否为空,若为空则抛出异常。
- 日志标记:给所有Bean添加唯一ID,方便链路追踪。
- 注解解析:解析@PostConstruct注解,为后续初始化做准备。
5. 初始化阶段:激活Bean的“功能”
触发时机:前置处理完成后。
核心动作(按顺序执行):
- @PostConstruct注解方法:标记在Bean的某个方法上,Spring自动调用。例如:启动后加载缓存、注册监听器。
- InitializingBean接口的afterPropertiesSet():接口定义的初始化方法,Spring自动调用。例如:数据库连接池在此方法中创建物理连接。
- 自定义init-method:通过XML或@Bean(initMethod=“init”)指定的初始化方法。例如:启动后台线程、初始化计数器。
典型场景:
- 缓存预热:商品服务Bean初始化时,从数据库加载热门商品到Redis。
- 连接池就绪:数据库连接池Bean在初始化阶段创建10个初始连接。
6. BeanPostProcessor后置处理:最终“包装”
触发时机:初始化完成后,Bean投入使用前。
核心动作:
- Spring遍历所有BeanPostProcessor,执行postProcessAfterInitialization()方法。
- 生成代理对象:例如,为@Transactional标注的Service类生成AOP代理,实现事务管理。
- 功能增强:例如,为Bean添加性能监控、熔断降级逻辑。
典型场景:
- AOP代理:普通的UserService对象被包装为代理对象,方法调用前后自动记录日志。
- 缓存拦截:在代理对象中,为查询方法添加缓存逻辑(如先查Redis,再查数据库)。
7. 运行阶段:Bean正式“上岗”
触发时机:后置处理完成后,Bean放入Spring容器。
核心动作:
- 通过applicationContext.getBean()获取Bean,或被其他Bean依赖注入。
- Bean执行业务逻辑,如Controller调用Service,Service调用DAO。
典型场景:
- 用户请求到达Controller,调用UserService的createUser()方法。
- 微服务中,Feign客户端Bean发起HTTP调用其他服务。
8. 销毁阶段:Bean的“善后工作”
触发时机:Spring容器关闭时(如调用context.close())。
核心动作(按顺序执行):
- @PreDestroy注解方法:标记在Bean的某个方法上,Spring自动调用。例如:关闭网络连接、释放文件句柄。
- DisposableBean接口的destroy():接口定义的销毁方法,Spring自动调用。例如:数据库连接池关闭所有连接。
- 自定义destroy-method:通过XML或@Bean(destroyMethod=“close”)指定的销毁方法。例如:停止定时任务、清理临时文件。
典型场景:
- 连接池Bean销毁时,释放所有数据库连接。
- 消息队列监听器Bean销毁时,关闭消费者线程。
现实世界类比
实例化 → 工厂生产一台手机(硬件组装)。
属性注入 → 安装操作系统和预装软件(赋予基础功能)。
Aware回调 → 手机连接Wi-Fi,获取网络权限(感知外部环境)。
BeanPostProcessor前置处理 → 质检员检查硬件是否合格。
初始化 → 用户首次开机,完成系统设置(激活功能)。
BeanPostProcessor后置处理 → 安装保护壳和贴膜(增强防护)。
运行阶段 → 用户正常使用手机。
销毁阶段 → 手机关机,释放电量(清理资源)。
小白生命周期记忆口诀:“先造空壳,再装零件,认识环境,质检过关,开机初始化,包装上市,干活,最后退休”。
📥博主的人生感悟和目标
希望各位读者大大多多支持用心写文章的博主,现在时代变了,信息爆炸,酒香也怕巷子深,博主真的需要大家的帮助才能在这片海洋中继续发光发热,所以,赶紧动动你的小手,点波关注❤️,点波赞👍,点波收藏⭐,甚至点波评论✍️,都是对博主最好的支持和鼓励!
- 💂 博客主页: Java程序员廖志伟
- 👉 开源项目:Java程序员廖志伟
- 🌥 哔哩哔哩:Java程序员廖志伟
- 🎏 个人社区:Java程序员廖志伟
- 🔖 个人微信号:
SeniorRD
📙经过多年在CSDN创作上千篇文章的经验积累,我已经拥有了不错的写作技巧。同时,我还与清华大学出版社签下了四本书籍的合约,并将陆续出版。这些书籍包括了基础篇、进阶篇、架构篇的📌《Java项目实战—深入理解大型互联网企业通用技术》📌,以及📚《解密程序员的思维密码–沟通、演讲、思考的实践》📚。具体出版计划会根据实际情况进行调整,希望各位读者朋友能够多多支持!
🔔如果您需要转载或者搬运这篇文章的话,非常欢迎您私信我哦~