技术面:Spring (bean的生命周期、创建方式、注入方式、作用域)
技术面Spring (bean的生命周期、创建方式、注入方式、作用域)在Java企业级开发中Spring框架几乎是必问的技术栈。面试中Spring Bean的相关问题经常被用来考察候选人对框架核心的掌握程度。本文将用大量代码演示从实战角度深入解析Spring Bean的生命周期、创建方式、注入方式以及作用域。—## 一、Spring Bean 的生命周期Spring Bean的生命周期是面试中的高频考点。它描述了Bean从创建到销毁的完整过程。理解它有助于我们利用Spring提供的钩子进行自定义操作。### 1.1 生命周期流程图简化版1.实例化通过构造器或工厂方法创建Bean实例。2.属性赋值设置Bean的属性依赖注入。3.初始化调用init-method或实现InitializingBean接口。4.使用Bean就绪供应用程序调用。5.销毁容器关闭时调用destroy-method或实现DisposableBean接口。### 1.2 实战代码演示下面是一个完整的示例展示Bean生命周期中的关键点。javaimport org.springframework.beans.factory.DisposableBean;import org.springframework.beans.factory.InitializingBean;public class UserBean implements InitializingBean, DisposableBean { private String name; public UserBean() { System.out.println(1. 实例化调用构造器 UserBean()); } public void setName(String name) { this.name name; System.out.println(2. 属性赋值设置 name name); } // 实现 InitializingBean 接口 Override public void afterPropertiesSet() throws Exception { System.out.println(3. 初始化回调afterPropertiesSet() 执行); if (name null) { name 默认用户; } } // 自定义初始化方法通过 Bean 的 initMethod 指定 public void customInit() { System.out.println(3.5 自定义初始化customInit() 执行); } // 业务方法 public void greet() { System.out.println(4. 使用BeanHello, name); } // 实现 DisposableBean 接口 Override public void destroy() throws Exception { System.out.println(5. 销毁回调destroy() 执行); } // 自定义销毁方法 public void customDestroy() { System.out.println(5.5 自定义销毁customDestroy() 执行); }}XML配置applicationContext.xmlxmlbean iduserBean classcom.example.UserBean init-methodcustomInit destroy-methodcustomDestroy property namename value张三//bean运行代码javaimport org.springframework.context.support.ClassPathXmlApplicationContext;public class BeanLifecycleDemo { public static void main(String[] args) { ClassPathXmlApplicationContext context new ClassPathXmlApplicationContext(applicationContext.xml); UserBean user (UserBean) context.getBean(userBean); user.greet(); context.close(); // 触发销毁 }}输出结果1. 实例化调用构造器 UserBean()2. 属性赋值设置 name 张三3. 初始化回调afterPropertiesSet() 执行3.5 自定义初始化customInit() 执行4. 使用BeanHello, 张三5. 销毁回调destroy() 执行5.5 自定义销毁customDestroy() 执行注意afterPropertiesSet()在属性赋值后、自定义初始化方法之前执行。如果同时使用接口和XML配置接口方法优先。—## 二、Bean 的创建方式Spring支持多种创建Bean的方式常见的有三种构造器、静态工厂和实例工厂。### 2.1 构造器方式最常用默认使用无参构造器或通过constructor-arg传参。xmlbean iduser classcom.example.User constructor-arg namename value李四/ constructor-arg nameage value25//bean### 2.2 静态工厂方法适用于不需要Spring管理工厂类实例的场景。javapublic class UserFactory { // 静态方法返回Bean public static User createUser() { User user new User(); user.setName(王五); user.setAge(30); return user; }}xmlbean iduserFromFactory classcom.example.UserFactory factory-methodcreateUser/### 2.3 实例工厂方法需要先创建工厂Bean再通过它创建目标Bean。javapublic class UserInstanceFactory { // 非静态方法 public User createUser() { User user new User(); user.setName(赵六); user.setAge(28); return user; }}// 配置bean idfactory classcom.example.UserInstanceFactory/bean iduserFromInstance factory-beanfactory factory-methodcreateUser/### 2.4 注解方式推荐现代Spring开发更倾向于使用注解如Component和Bean。javaComponentpublic class User { Value(张三) private String name; // getter/setter...}// 或在配置类中Configurationpublic class AppConfig { Bean public User user() { return new User(李四, 25); }}—## 三、依赖注入方式依赖注入DI是Spring的核心功能主要有三种方式属性注入、构造器注入和setter注入。### 3.1 属性注入Field Injection通过Autowired直接注入到字段上代码最简洁但不推荐用于生产环境因为难以单元测试。javaimport org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;Componentpublic class OrderService { Autowired private UserRepository userRepository; // 直接注入 public void process() { userRepository.save(new User()); }}### 3.2 构造器注入Constructor InjectionSpring官方推荐的方式保证依赖不可变且注入时对象已完成初始化。javaComponentpublic class OrderService { private final UserRepository userRepository; // Spring自动调用构造器注入依赖 Autowired public OrderService(UserRepository userRepository) { this.userRepository userRepository; } public void process() { userRepository.save(new User()); }}注意如果类只有一个构造器Autowired可以省略Spring 4.3。### 3.3 Setter注入通过setter方法注入适合可选依赖。javaComponentpublic class OrderService { private UserRepository userRepository; Autowired public void setUserRepository(UserRepository userRepository) { this.userRepository userRepository; } public void process() { userRepository.save(new User()); }}### 3.4 注入方式对比| 方式 | 优点 | 缺点 | 适用场景 ||------|------|------|----------|| 属性注入 | 代码简洁 | 难以测试依赖不明确 | 快速原型不推荐生产 || 构造器注入 | 依赖明确不可变 | 代码稍长 | 强制依赖推荐使用 || Setter注入 | 可选依赖 | 可变可能忘记调用 | 可选依赖或循环引用 |—## 四、Bean 的作用域作用域决定了Bean的存活范围和共享方式。Spring定义了5种作用域Web环境有3种额外作用域。### 4.1 常见作用域| 作用域 | 描述 | 适用场景 ||--------|------|----------|| singleton | 默认单例整个容器共享一个实例 | 无状态Bean如Service || prototype | 每次获取都创建新实例 | 有状态Bean如User || request | 每个HTTP请求一个实例Web环境 | 请求级别的数据 || session | 每个HTTP Session一个实例Web环境 | 用户会话数据 || application | 每个ServletContext一个实例Web环境 | 全局共享数据 |### 4.2 代码演示javaimport org.springframework.context.annotation.Scope;import org.springframework.stereotype.Component;ComponentScope(singleton) // 默认就是singleton可省略public class SingletonBean { private int count 0; public void increment() { count; System.out.println(Singleton count count); }}ComponentScope(prototype) // 每次获取新实例public class PrototypeBean { private int count 0; public void increment() { count; System.out.println(Prototype count count); }}测试代码javaimport org.springframework.context.ApplicationContext;import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class ScopeDemo { public static void main(String[] args) { ApplicationContext context new AnnotationConfigApplicationContext(com.example); // 获取两次单例Bean SingletonBean s1 context.getBean(SingletonBean.class); SingletonBean s2 context.getBean(SingletonBean.class); s1.increment(); // 输出: Singleton count 1 s2.increment(); // 输出: Singleton count 2 (共享同一个实例) // 获取两次原型Bean PrototypeBean p1 context.getBean(PrototypeBean.class); PrototypeBean p2 context.getBean(PrototypeBean.class); p1.increment(); // 输出: Prototype count 1 p2.increment(); // 输出: Prototype count 1 (不同实例) }}### 4.3 作用域使用注意事项-singleton与prototype混用如果singleton Bean注入prototype Beanprototype Bean会被固化。解决方案使用Lookup注解或Provider。-Web作用域仅在Web应用如Spring MVC中生效需要配置RequestContextListener或EnableWebMvc。—## 总结本文从实战角度出发用具体代码演示了Spring Bean的四大核心概念1.生命周期实例化 → 属性赋值 → 初始化 → 使用 → 销毁提供了InitializingBean、DisposableBean接口以及init-method、destroy-method等钩子。2.创建方式构造器最常用、静态工厂、实例工厂以及注解方式Component、Bean。3.注入方式属性注入简洁但危险、构造器注入推荐、Setter注入可选依赖其中构造器注入是Spring官方推荐的最佳实践。4.作用域singleton单例默认、prototype原型、request、session、application选择合适的作用域可以提升性能和资源利用率。面试中不仅要记住概念更要能结合实际项目场景解释为什么选择某种方式。例如用构造器注入保证依赖不可变用prototype作用域处理有状态Bean等。希望本文的代码示例能帮助你在面试中脱颖而出。

相关新闻

SDR++终极指南:如何用这款开源软件开启你的无线电频谱探索之旅

SDR++终极指南:如何用这款开源软件开启你的无线电频谱探索之旅

SDR终极指南:如何用这款开源软件开启你的无线电频谱探索之旅 【免费下载链接】SDRPlusPlus Cross-Platform SDR Software 项目地址: https://gitcode.com/GitHub_Trending/sd/SDRPlusPlus 你是否曾对无线电频谱中的神秘信号感到好奇?想要探索FM广…

2026/10/16 21:32:35 阅读更多 →
AgileTC:一站式敏捷测试用例管理平台,轻松提升团队协作效率

AgileTC:一站式敏捷测试用例管理平台,轻松提升团队协作效率

AgileTC:一站式敏捷测试用例管理平台,轻松提升团队协作效率 【免费下载链接】AgileTC AgileTC is an agile test case management platform 项目地址: https://gitcode.com/gh_mirrors/ag/AgileTC AgileTC是一套敏捷的测试用例管理平台&#xff0…

2026/10/17 12:08:37 阅读更多 →
ESPHome Flasher完整指南:零基础轻松刷写ESP智能设备固件

ESPHome Flasher完整指南:零基础轻松刷写ESP智能设备固件

ESPHome Flasher完整指南:零基础轻松刷写ESP智能设备固件 【免费下载链接】esphome-flasher Simple GUI tool to flash ESPs over USB 项目地址: https://gitcode.com/gh_mirrors/es/esphome-flasher 还在为ESP8266和ESP32设备的固件刷写而烦恼吗&#xff1f…

2026/10/17 14:07:15 阅读更多 →

最新新闻

智能体接入工程:大模型在金融交易中的安全可控实践

智能体接入工程:大模型在金融交易中的安全可控实践

实际上手之前我们都觉得,把大模型智能体接进金融交易流程,最难的应该是模型效果。结果等项目真正推下去才发现,模型本身的推理能力反而不是瓶颈,周围那圈工程才是真正决定生死的东西。这圈工程,在这个项目里我们内部叫…

2026/10/18 18:13:54 阅读更多 →
KGCN知识图谱推荐系统实战:TensorFlow手写图卷积层

KGCN知识图谱推荐系统实战:TensorFlow手写图卷积层

简介:本资源是一个基于Python实现的高分毕业设计级电影推荐系统,融合知识图谱(KG)与图神经网络(KGCN),面向人工智能、推荐系统方向的本科生与研究生,解决传统协同过滤在冷启动与可解…

2026/10/18 18:13:54 阅读更多 →
Octop任务编排框架:中心调度与分布式执行架构解析

Octop任务编排框架:中心调度与分布式执行架构解析

1. 从“Octop”这个名字说起:它到底是什么第一次看到“Octop”这个词,我脑子里蹦出来的第一反应是“Octopus”——章鱼。八条腕足、分布式神经系统、极强的环境适应能力,这几个特征凑在一起,恰好能解释为什么有人会拿它来命名一个…

2026/10/18 18:13:54 阅读更多 →
生成对抗网络原始论文精读:目标函数、理论证明与稳定训练实战

生成对抗网络原始论文精读:目标函数、理论证明与稳定训练实战

生成对抗网络这个方向,我在第一次读到《Generative Adversarial Nets》的时候并没有立刻觉得它“惊艳”。当时最直观的感觉是:原来生成模型还能这样定义——不直接去逼近数据分布,而是让两个网络互相“逼”着对方提高。这篇论文我前后读了三遍…

2026/10/18 18:13:54 阅读更多 →
CAD/CAM核心原理与数控加工落地实践:从建模、刀轨到G代码全流程解析

CAD/CAM核心原理与数控加工落地实践:从建模、刀轨到G代码全流程解析

做机械加工这行,绕不开的一对搭档就是CAD(计算机辅助设计)和CAM(计算机辅助制造)。搞懂这对搭档,基本就拿到了现代数字化加工的入场券。很多刚入行的朋友容易把CAD/CAM当成一个工具软件的名字,其…

2026/10/18 18:13:54 阅读更多 →
华为ONT固件编辑GUI工具:支持头部重写、CRC校验与分区表可视化

华为ONT固件编辑GUI工具:支持头部重写、CRC校验与分区表可视化

简介:HWFW_GUI是一款面向通信设备开发与逆向分析工程师的华为ONT固件可视化编辑工具,基于C开发,专用于解析、浏览、修改及导出华为光猫(ONT)固件镜像中的子项目(如uboot、kernel、rootfs等)&…

2026/10/18 18:12:53 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →