关于 Bean 容器的注入方式,99 % 的人都答不全!
引言:在使用 Spring 框架开发应用程序时,依赖注入是一个至关重要的概念。而对于 Bean 容器的注入方式,虽然我们可能都有一定的了解,但实际上很多人在被问及这个问题时可能并不能完整地回答。本文将深入探讨 Spring 中 Bean 容器的注入方式,包括 XML 配置方式、基于注解方式、Java 配置方式以及自动扫描方式,并提供了详细的代码示例和解析,以便读者全面了解并掌握这些方式。
题目
关于 Bean 容器的注入方式,99 % 的人都答不全!
推荐解析

1)XML配置方式
a) 基于属性注入
通过 <bean>
元素的属性来注入依赖。主要有以下几种方式:
-
构造器注入**:** 使用
<constructor-arg>
元素配置构造函数参数。<bean id="exampleBean" class="com.example.ExampleBean"><constructor-arg ref="dependencyBean" /> </bean>
-
Setter方法注入: 使用
<property>
元素配置Setter方法注入的属性。<bean id="exampleBean" class="com.example.ExampleBean"><property name="dependencyBean" ref="dependencyBean" /> </bean>
-
直接量注入: 使用
<constructor-arg>
或<property>
元素配置基本类型或字符串等直接值。<bean id="exampleBean" class="com.example.ExampleBean"><constructor-arg value="exampleValue" /> </bean>
b) 基于注解方式
使用 @Autowired
、@Inject
或 @Resource
注解在类或字段上进行依赖注入。
-
构造器注入: 在类的构造器上使用
@Autowired
注解。@Component public class ExampleBean {private DependencyBean dependency;@Autowiredpublic ExampleBean(DependencyBean dependency) {this.dependency = dependency;} }
-
Setter方法注入: 在Setter方法上使用
@Autowired
注解。@Component public class ExampleBean {private DependencyBean dependency;@Autowiredpublic void setDependency(DependencyBean dependency) {this.dependency = dependency;} }
2)Java配置方式
通过Java类来配置Bean,并使用 @Bean
注解将Bean注册到Spring容器。
@Configuration
public class AppConfig {@Beanpublic ExampleBean exampleBean() {return new ExampleBean(dependencyBean());}@Beanpublic DependencyBean dependencyBean() {return new DependencyBean();}
}
3)自动扫描方式
使用 <context:component-scan>
或 @ComponentScan
注解来自动扫描和注册带有 @Component
及其衍生注解(如 @Service
、@Repository
、@Controller
等)的Bean。
<context:component-scan base-package="com.example" />
或者在Java配置类中使用:
@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {// 配置其他Bean
}
4)注册BeanPostProcessor
实现 BeanPostProcessor
接口来在Bean初始化前后进行自定义处理,也可以用来动态注入Bean。
@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {if (bean instanceof ExampleBean) {// 自定义处理逻辑,如动态注入其他依赖}return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {return bean;}
}
基于条件的 Bean 注册
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;@Configuration
public class AppConfig {@Bean@Conditional(WindowsCondition.class) // 注册条件:Windows 操作系统public OSInfo windowsInfo() {return new OSInfo("Windows");}@Bean@Conditional(LinuxCondition.class) // 注册条件:Linux 操作系统public OSInfo linuxInfo() {return new OSInfo("Linux");}
}
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;public class WindowsCondition implements Condition {@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {String osName = System.getProperty("os.name");return osName.toLowerCase().contains("windows");}
}
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;public class LinuxCondition implements Condition {@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {String osName = System.getProperty("os.name");return osName.toLowerCase().contains("linux");}
}
其他补充
鱼聪明 AI 的回答:
鱼聪明 AI 地址:https://www.yucongming.com/

初始化阶段的回调
-
InitializingBean 接口:
InitializingBean
是 Spring 提供的一个接口,当 Bean 实现该接口时,Spring 容器在实例化 Bean 后会自动调用其afterPropertiesSet()
方法,用于执行初始化逻辑。import org.springframework.beans.factory.InitializingBean;public class MyBean implements InitializingBean {@Overridepublic void afterPropertiesSet() throws Exception {// 执行初始化逻辑} }
-
@PostConstruct 注解:
@PostConstruct
是一个标准的 Java 注解,用于在 Bean 初始化之后执行特定的方法。当一个方法被@PostConstruct
注解标记时,Spring 容器会在实例化 Bean 后立即调用该方法。import javax.annotation.PostConstruct;public class MyBean {@PostConstructpublic void init() {// 执行初始化逻辑} }
销毁阶段的回调
-
DisposableBean 接口:
DisposableBean
是 Spring 提供的一个接口,当 Bean 实现该接口时,Spring 容器在销毁 Bean 之前会自动调用其destroy()
方法,用于执行销毁逻辑。import org.springframework.beans.factory.DisposableBean;public class MyBean implements DisposableBean {@Overridepublic void destroy() throws Exception {// 执行销毁逻辑} }
-
@PreDestroy 注解:
@PreDestroy
是一个标准的 Java 注解,用于在 Bean 销毁之前执行特定的方法。当一个方法被@PreDestroy
注解标记时,Spring 容器会在销毁 Bean 之前调用该方法。import javax.annotation.PreDestroy;public class MyBean {@PreDestroypublic void cleanup() {// 执行销毁逻辑} }
作用域(Scope)
在 Spring 中,Bean 的作用域决定了在容器中创建的 Bean 的可见范围和生命周期。Spring 框架提供了以下几种标准的作用域:
- Singleton(默认):在整个应用程序中只创建一个 Bean 实例,并在容器启动时就进行创建。所有对该 Bean 的请求都将返回同一个实例。
- Prototype:每次请求该 Bean 时都会创建一个新的实例。这意味着每次通过容器获取该 Bean 时,都会返回一个新的实例。
- Request:在每个 HTTP 请求中创建一个新的 Bean 实例,仅在 Web 应用程序上下文中有效。每个 HTTP 请求都会有自己的 Bean 实例,并且该实例仅在当前请求内有效。
- Session:在每个 HTTP Session 中创建一个新的 Bean 实例,也仅在 Web 应用程序上下文中有效。每个 HTTP Session 都会有自己的 Bean 实例,并且该实例仅在当前 Session 内有效。
- GlobalSession:在一个全局的 HTTP Session 中创建一个 Bean 实例,通常在分布式应用程序中使用。与 Session 作用域类似,但是在集群环境中只有一个 Bean 实例,仅在当前全局 Session 内有效。
生命周期管理
Spring 容器负责管理 Bean 的生命周期,确保它们在正确的时间点被创建、初始化、使用和销毁。生命周期管理主要涉及以下几个阶段:
- 实例化:Spring 容器根据配置信息或注解创建 Bean 的实例。
- 属性设置:Spring 容器将 Bean 的属性(依赖)注入到实例中。
- 初始化:如果 Bean 实现了
InitializingBean
接口,容器会调用其afterPropertiesSet()
方法,或者如果在方法上使用了@PostConstruct
注解,则在属性设置后立即调用被注解标记的方法。 - 使用:此时 Bean 实例已经完全初始化,可以被应用程序使用。
- 销毁:如果 Bean 实现了
DisposableBean
接口,容器会在销毁 Bean 之前调用其destroy()
方法,或者如果在方法上使用了@PreDestroy
注解,则在 Bean 销毁前调用被注解标记的方法。
自定义作用域和生命周期管理
除了上述提到的标准作用域和生命周期管理方式外,Spring 还允许开发者自定义作用域和生命周期管理策略。可以通过实现 Scope
接口来定义新的作用域,通过实现 BeanPostProcessor
接口来定义 Bean 的自定义初始化和销毁逻辑。
欢迎交流
本文主要介绍 Bean 容器注入方式和条件注册,另外有作用域和生命周期钩子函数的使用,面试中也经常会考实战开发方面的知识,大家可以去关注一下,在文末还有三个问题,欢迎小伙伴在评论多多留言!
1)Bean 容器注入方式有几个种?
2)Bean 的生命周期是怎么样的?
3)怎么实现基于条件的 Bean 注册?
相关文章:

关于 Bean 容器的注入方式,99 % 的人都答不全!
引言:在使用 Spring 框架开发应用程序时,依赖注入是一个至关重要的概念。而对于 Bean 容器的注入方式,虽然我们可能都有一定的了解,但实际上很多人在被问及这个问题时可能并不能完整地回答。本文将深入探讨 Spring 中 Bean 容器的…...
Spring的@Async注解及其用途
Spring 的 Async 注解是 Spring Framework 4.2 版本引入的功能,它用于支持异步方法执行。当一个方法标注了 Async,Spring 会在一个单独的线程中调用该方法,从而不会阻塞主线程的执行。 Async 注解的用途: 提高性能:通…...

JS(DOM、事件)
DOM 概念:Document Object Model,文档对象模型。将标记语言的各个组成部分封装为对应的对象: Document:整个文档对象Element:元素对象Attribute:属性对象Text:文本对象Comment:注释对象 JavaScript通过DOM,就能够对HTML进行操作: 改变 HTML 元素的内…...

学习小心意——python的构造方法和析构方法
构造方法和析构方法分别用于初始化对象的属性和释放类占有的资源 构造方法_init_() 语法格式如下: class 类名:def __init__(self, 参数1, 参数2, ...):# 初始化代码self.属性1 参数1self.属性2 参数2# ... 示例代码如下 class Student:def __init__(self):s…...
GB/T 23995-2009 室内装饰装修用溶剂型醇酸木器涂料检测
溶剂型醇酸木器涂料是指以醇酸树脂为主要成膜物,通过氧化干燥成膜的溶剂型木器涂料适用于室内木制品表面的保护及装饰。 GB/T 23995-2009室内装饰装修用溶剂型醇酸木器涂料检测项目: 测试指标 测试方法 在容器中状态 GB/T 23995 细度 GB/T 6753.1 …...

Maven 中的 classifier 属性用过没?
最近训练营有小伙伴问到松哥一个关于 Maven 依赖的问题,涉及到 classifier 属性,随机问了几个小伙伴,都说工作中没用到过,因此简单整篇文章和小伙伴们分享下。 Maven 大家日常开发应该都有使用,Maven 中有一个比较好玩…...

Linux网络编程:传输层协议|UDP|TCP
知识引入: 端口号: 当应用层获得一个传输过来的报文时,这时数据包需要知道,自己应该送往哪一个应用层的服务,这时就引入了“端口号”,通过区分同一台主机不同应用程序的端口号,来保证数据传输…...
MongoDB CRUD操作:内嵌文档查询
MongoDB内嵌文档的查询 文章目录 MongoDB内嵌文档的查询使用点号.查询内嵌文档嵌套字段的相等匹配使用查询操作符进行匹配指定AND条件 嵌套文档的匹配使用 MongoDB Atlas 查询内嵌文档导航至集合指定查询过滤文档点击应用 可以使用下面几种方法查询MongoDB中的嵌入文档…...

JavaScript、Kotlin、Flutter可以开发鸿蒙APP吗?
自从去年华为宣布推出「鸿蒙Next」版本开始,标志着其操作系统的全面革新。鸿蒙Next将摒弃所有基于AOSP的代码,与Android系统彻底分离,实现完全自主的研发路径。通过精简约40%的冗余代码,鸿蒙Next致力于构建一个更高效、更流畅的系…...
刚体运动描述:欧拉角与四元数
在机器人学中,刚体的运动描述是非常重要的,特别是当我们需要精确控制机器人的姿态时。欧拉角和四元数是两种常用的描述刚体在三维空间中旋转的方法。下面将分别介绍这两种方法并给出其特点。 欧拉角 定义与特点: 定义:欧拉角是…...
一文速通23种设计模式——单例模式、工厂模式、建造者模式、原型模式、代理模式、装饰器模式、组合模式、组合模式、桥接模式、观察者模式、策略模式……
一文速通23种设计模式 写在前面 本文基于结城浩所著《图解设计模式》,其中所使用代码皆为Java版本。 随书代码下载地址-点击“随书下载” 全文15205字,全部读完需要约20分钟。 目录 一文速通23种设计模式写在前面 第一部分 适应设计模式迭代器模式 (…...
Lua 基础 04 模块
Lua 基础相关知识 第四期 require 模块,通常是一个表,表里存储了一些字段和函数,单独写在一个 lua 文件。 例如,这是一个 tools.lua 文件,定义了一个局部 tools 表,包含一个 log 函数,可以传…...

速递FineWeb:一个拥有无限潜力的15T Tokens的开源数据集
大模型技术论文不断,每个月总会新增上千篇。本专栏精选论文重点解读,主题还是围绕着行业实践和工程量产。若在某个环节出现卡点,可以回到大模型必备腔调或者LLM背后的基础模型新阅读。而最新科技(Mamba,xLSTM,KAN)则提…...
HDLBits答案汇总
一.Getting Started Getting started-CSDN博客 二.Verilog Basics-CSDN博客 Vectors-CSDN博客 Module Hierarchy-CSDN博客 Procedures-CSDN博客 More Verilog Features-CSDN博客 三.Circuits Combinational Basic-CSDN博客 Multiplexers-CSDN博客 Arithmetic-CSDN博客 Karnau…...

云端数据提取:安全、高效地利用无限资源
在当今的大数据时代,企业和组织越来越依赖于云平台存储和处理海量数据。然而,随着数据的指数级增长,数据的安全性和高效的数据处理成为了企业最为关心的议题之一。本文将探讨云端数据安全的重要性,并提出一套既高效又安全的数据提…...

Java开发:Spring Boot 实战教程
序言 随着技术的快速发展和数字化转型的深入推进,软件开发领域迎来了前所未有的变革。在众多开发框架中,Spring Boot凭借其“约定大于配置”的核心理念和快速开发的能力,迅速崭露头角,成为当今企业级应用开发的首选框架之一。 《…...

【Python3.11版本利用whl文件安装对应的dlib-19.24.1-cp311-cp311-win_amd64.whl库】
下载Python对应的安装包 找到自己Python版本对应的dlib whl库将网盘下载好的文件放在安装Python的Scripts路径下面接着在该路径输入cmdpip进行安装使用的是国内的源 找到自己Python版本对应的dlib whl库 python 3.11 对应 dlib-19.24.1-cp311-cp311-win_amd64.whl -i 也可以去…...

HW面试常见知识点2——研判分析(蓝队中级版)
🍀文章简介:又到了一年一度的HW时刻,本文写给新手想快速进阶HW蓝中的网安爱好者们, 通读熟练掌握本文面试定个蓝中还是没问题的!大家也要灵活随机应变,不要太刻板的回答) 🍁个人主页…...
鲁教版七年级数学下册-笔记
文章目录 第七章 二元一次方程组1 二元一次方程组2 解二元一次方程组3 二元一次方程组的应用4 二元一次方程与一次函数5 三元一次方程组 第八章 平行线的有关证明1 定义与命题2 证明的必要性3 基本事实与定理4 平行线的判定定理5 平行限的性质定理6 三角形内角和定理 第九章 概…...

带你走进在线直线度测量仪 解析测量方法!
在线直线度测量仪 在线直线度测量仪可安装于生产线上,进行非接触式的无损检测,能检测米直线度尺寸,对截面为圆形的产品,进性直线度检测的帮手。 测量方法 在线直线度拟采用我公司的光电测头对矫直后的棒材直线度进行测量。测量时…...

Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...

大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
css的定位(position)详解:相对定位 绝对定位 固定定位
在 CSS 中,元素的定位通过 position 属性控制,共有 5 种定位模式:static(静态定位)、relative(相对定位)、absolute(绝对定位)、fixed(固定定位)和…...

多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...