当前位置: 首页 > news >正文

关于 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/

初始化阶段的回调

  1. InitializingBean 接口
    InitializingBean 是 Spring 提供的一个接口,当 Bean 实现该接口时,Spring 容器在实例化 Bean 后会自动调用其 afterPropertiesSet() 方法,用于执行初始化逻辑。

    import org.springframework.beans.factory.InitializingBean;public class MyBean implements InitializingBean {@Overridepublic void afterPropertiesSet() throws Exception {// 执行初始化逻辑}
    }
    
  2. @PostConstruct 注解
    @PostConstruct 是一个标准的 Java 注解,用于在 Bean 初始化之后执行特定的方法。当一个方法被 @PostConstruct 注解标记时,Spring 容器会在实例化 Bean 后立即调用该方法。

    import javax.annotation.PostConstruct;public class MyBean {@PostConstructpublic void init() {// 执行初始化逻辑}
    }
    

销毁阶段的回调

  1. DisposableBean 接口
    DisposableBean 是 Spring 提供的一个接口,当 Bean 实现该接口时,Spring 容器在销毁 Bean 之前会自动调用其 destroy() 方法,用于执行销毁逻辑。

    import org.springframework.beans.factory.DisposableBean;public class MyBean implements DisposableBean {@Overridepublic void destroy() throws Exception {// 执行销毁逻辑}
    }
    
  2. @PreDestroy 注解
    @PreDestroy 是一个标准的 Java 注解,用于在 Bean 销毁之前执行特定的方法。当一个方法被 @PreDestroy 注解标记时,Spring 容器会在销毁 Bean 之前调用该方法。

    import javax.annotation.PreDestroy;public class MyBean {@PreDestroypublic void cleanup() {// 执行销毁逻辑}
    }
    

作用域(Scope)

在 Spring 中,Bean 的作用域决定了在容器中创建的 Bean 的可见范围和生命周期。Spring 框架提供了以下几种标准的作用域:

  1. Singleton(默认):在整个应用程序中只创建一个 Bean 实例,并在容器启动时就进行创建。所有对该 Bean 的请求都将返回同一个实例。
  2. Prototype:每次请求该 Bean 时都会创建一个新的实例。这意味着每次通过容器获取该 Bean 时,都会返回一个新的实例。
  3. Request:在每个 HTTP 请求中创建一个新的 Bean 实例,仅在 Web 应用程序上下文中有效。每个 HTTP 请求都会有自己的 Bean 实例,并且该实例仅在当前请求内有效。
  4. Session:在每个 HTTP Session 中创建一个新的 Bean 实例,也仅在 Web 应用程序上下文中有效。每个 HTTP Session 都会有自己的 Bean 实例,并且该实例仅在当前 Session 内有效。
  5. GlobalSession:在一个全局的 HTTP Session 中创建一个 Bean 实例,通常在分布式应用程序中使用。与 Session 作用域类似,但是在集群环境中只有一个 Bean 实例,仅在当前全局 Session 内有效。

生命周期管理

Spring 容器负责管理 Bean 的生命周期,确保它们在正确的时间点被创建、初始化、使用和销毁。生命周期管理主要涉及以下几个阶段:

  1. 实例化:Spring 容器根据配置信息或注解创建 Bean 的实例。
  2. 属性设置:Spring 容器将 Bean 的属性(依赖)注入到实例中。
  3. 初始化:如果 Bean 实现了 InitializingBean 接口,容器会调用其 afterPropertiesSet() 方法,或者如果在方法上使用了 @PostConstruct 注解,则在属性设置后立即调用被注解标记的方法。
  4. 使用:此时 Bean 实例已经完全初始化,可以被应用程序使用。
  5. 销毁:如果 Bean 实现了 DisposableBean 接口,容器会在销毁 Bean 之前调用其 destroy() 方法,或者如果在方法上使用了 @PreDestroy 注解,则在 Bean 销毁前调用被注解标记的方法。

自定义作用域和生命周期管理

除了上述提到的标准作用域和生命周期管理方式外,Spring 还允许开发者自定义作用域和生命周期管理策略。可以通过实现 Scope 接口来定义新的作用域,通过实现 BeanPostProcessor 接口来定义 Bean 的自定义初始化和销毁逻辑。

欢迎交流

本文主要介绍 Bean 容器注入方式和条件注册,另外有作用域和生命周期钩子函数的使用,面试中也经常会考实战开发方面的知识,大家可以去关注一下,在文末还有三个问题,欢迎小伙伴在评论多多留言!

1)Bean 容器注入方式有几个种?

2)Bean 的生命周期是怎么样的?

3)怎么实现基于条件的 Bean 注册?

相关文章:

关于 Bean 容器的注入方式,99 % 的人都答不全!

引言&#xff1a;在使用 Spring 框架开发应用程序时&#xff0c;依赖注入是一个至关重要的概念。而对于 Bean 容器的注入方式&#xff0c;虽然我们可能都有一定的了解&#xff0c;但实际上很多人在被问及这个问题时可能并不能完整地回答。本文将深入探讨 Spring 中 Bean 容器的…...

Spring的@Async注解及其用途

Spring 的 Async 注解是 Spring Framework 4.2 版本引入的功能&#xff0c;它用于支持异步方法执行。当一个方法标注了 Async&#xff0c;Spring 会在一个单独的线程中调用该方法&#xff0c;从而不会阻塞主线程的执行。 Async 注解的用途&#xff1a; 提高性能&#xff1a;通…...

JS(DOM、事件)

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

学习小心意——python的构造方法和析构方法

构造方法和析构方法分别用于初始化对象的属性和释放类占有的资源 构造方法_init_() 语法格式如下&#xff1a; class 类名:def __init__(self, 参数1, 参数2, ...):# 初始化代码self.属性1 参数1self.属性2 参数2# ... 示例代码如下 class Student:def __init__(self):s…...

GB/T 23995-2009 室内装饰装修用溶剂型醇酸木器涂料检测

溶剂型醇酸木器涂料是指以醇酸树脂为主要成膜物&#xff0c;通过氧化干燥成膜的溶剂型木器涂料适用于室内木制品表面的保护及装饰。 GB/T 23995-2009室内装饰装修用溶剂型醇酸木器涂料检测项目&#xff1a; 测试指标 测试方法 在容器中状态 GB/T 23995 细度 GB/T 6753.1 …...

Maven 中的 classifier 属性用过没?

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

Linux网络编程:传输层协议|UDP|TCP

知识引入&#xff1a; 端口号&#xff1a; 当应用层获得一个传输过来的报文时&#xff0c;这时数据包需要知道&#xff0c;自己应该送往哪一个应用层的服务&#xff0c;这时就引入了“端口号”&#xff0c;通过区分同一台主机不同应用程序的端口号&#xff0c;来保证数据传输…...

MongoDB CRUD操作:内嵌文档查询

MongoDB内嵌文档的查询 文章目录 MongoDB内嵌文档的查询使用点号.查询内嵌文档嵌套字段的相等匹配使用查询操作符进行匹配指定AND条件 嵌套文档的匹配使用 MongoDB Atlas 查询内嵌文档导航至集合指定查询过滤文档点击应用 可以使用下面几种方法查询MongoDB中的嵌入文档&#xf…...

JavaScript、Kotlin、Flutter可以开发鸿蒙APP吗?

自从去年华为宣布推出「鸿蒙Next」版本开始&#xff0c;标志着其操作系统的全面革新。鸿蒙Next将摒弃所有基于AOSP的代码&#xff0c;与Android系统彻底分离&#xff0c;实现完全自主的研发路径。通过精简约40%的冗余代码&#xff0c;鸿蒙Next致力于构建一个更高效、更流畅的系…...

刚体运动描述:欧拉角与四元数

在机器人学中&#xff0c;刚体的运动描述是非常重要的&#xff0c;特别是当我们需要精确控制机器人的姿态时。欧拉角和四元数是两种常用的描述刚体在三维空间中旋转的方法。下面将分别介绍这两种方法并给出其特点。 欧拉角 定义与特点&#xff1a; 定义&#xff1a;欧拉角是…...

一文速通23种设计模式——单例模式、工厂模式、建造者模式、原型模式、代理模式、装饰器模式、组合模式、组合模式、桥接模式、观察者模式、策略模式……

一文速通23种设计模式 写在前面 本文基于结城浩所著《图解设计模式》&#xff0c;其中所使用代码皆为Java版本。 随书代码下载地址-点击“随书下载” 全文15205字&#xff0c;全部读完需要约20分钟。 目录 一文速通23种设计模式写在前面 第一部分 适应设计模式迭代器模式 (…...

Lua 基础 04 模块

Lua 基础相关知识 第四期 require 模块&#xff0c;通常是一个表&#xff0c;表里存储了一些字段和函数&#xff0c;单独写在一个 lua 文件。 例如&#xff0c;这是一个 tools.lua 文件&#xff0c;定义了一个局部 tools 表&#xff0c;包含一个 log 函数&#xff0c;可以传…...

速递FineWeb:一个拥有无限潜力的15T Tokens的开源数据集

大模型技术论文不断&#xff0c;每个月总会新增上千篇。本专栏精选论文重点解读&#xff0c;主题还是围绕着行业实践和工程量产。若在某个环节出现卡点&#xff0c;可以回到大模型必备腔调或者LLM背后的基础模型新阅读。而最新科技&#xff08;Mamba,xLSTM,KAN&#xff09;则提…...

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…...

云端数据提取:安全、高效地利用无限资源

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

Java开发:Spring Boot 实战教程

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

【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——研判分析(蓝队中级版)

&#x1f340;文章简介&#xff1a;又到了一年一度的HW时刻&#xff0c;本文写给新手想快速进阶HW蓝中的网安爱好者们&#xff0c; 通读熟练掌握本文面试定个蓝中还是没问题的&#xff01;大家也要灵活随机应变&#xff0c;不要太刻板的回答&#xff09; &#x1f341;个人主页…...

鲁教版七年级数学下册-笔记

文章目录 第七章 二元一次方程组1 二元一次方程组2 解二元一次方程组3 二元一次方程组的应用4 二元一次方程与一次函数5 三元一次方程组 第八章 平行线的有关证明1 定义与命题2 证明的必要性3 基本事实与定理4 平行线的判定定理5 平行限的性质定理6 三角形内角和定理 第九章 概…...

带你走进在线直线度测量仪 解析测量方法!

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

15K Star 爆火!用大厂 PUA 话术逼 AI 干活,Claude 效率翻倍的黑色幽默工具

用大厂 PUA 话术逼 AI 干活&#xff1a;一个 15K Star 的黑色幽默项目如何让 Claude 效率翻倍 最近 GitHub 上火了个名字叫"PUA"的开源项目&#xff0c;短短几周从 0 到 15K Stars&#xff0c;还被各大科技媒体争相报道。 看名字的时候我以为又是哪位网友的整活之作…...

I2C设备扫描器:嵌入式系统总线拓扑发现与地址诊断工具

1. I2C设备扫描器&#xff1a;嵌入式系统中总线拓扑发现的核心工具IC&#xff08;Inter-Integrated Circuit&#xff09;总线因其仅需两根信号线&#xff08;SCL时钟线与SDA数据线&#xff09;、支持多主多从架构、内置仲裁与应答机制等特性&#xff0c;成为嵌入式系统中传感器…...

JAVA重点基础、进阶知识及易错点总结(36)Lombok 实战 + 阶段总结

&#x1f680; Java 巩固进阶 第 36 天 主题&#xff1a;Lombok 实战 阶段总结 —— 解放双手&#xff0c;高效开发&#x1f4c5; 进度概览&#xff1a;今天是 设计模式与注解阶段&#xff08;31-36 天&#xff09;的最后一天&#xff0c;也是 Java 基础巩固阶段的收官之日&a…...

解锁Intel GPU的CUDA能力:从零开始的跨硬件计算实践

解锁Intel GPU的CUDA能力&#xff1a;从零开始的跨硬件计算实践 【免费下载链接】ZLUDA CUDA on non-NVIDIA GPUs 项目地址: https://gitcode.com/GitHub_Trending/zl/ZLUDA 当实验室电脑只有Intel集成显卡却需要运行CUDA加速程序时&#xff0c;当笔记本的Iris Xe显卡面…...

降AI率工具8元和3元的,处理80%+有区别吗

“8元一千字太贵了&#xff0c;3元那个不是也能用吗&#xff1f;” 这个问题很合理&#xff0c;特别是对于字数多的毕业论文&#xff0c;价格差距相当可观。 4万字的论文&#xff1a; 8元工具&#xff1a;320元3元工具&#xff1a;约130元 差了190元。那这190元换来的是什么…...

人生苦难的本质的庖丁解牛

“人生苦难的本质”&#xff0c;常被误解为“命运的不公”、“物质的匮乏”或“肉体的疼痛”。 但本质上&#xff0c;苦难并非来自外部世界的客观事件&#xff0c;而是源于**“内在预期”与“外在实相”之间的剧烈摩擦**&#xff0c;是**“有限的自我”试图掌控“无限的无常”时…...

如何搭建终极游戏串流平台:Sunshine免费开源方案完整指南

如何搭建终极游戏串流平台&#xff1a;Sunshine免费开源方案完整指南 【免费下载链接】Sunshine Self-hosted game stream host for Moonlight. 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine 想要在任何设备上畅玩PC游戏大作&#xff1f;Sunshine开源游戏…...

OpenFBX:轻量级FBX文件解析的终极解决方案

OpenFBX&#xff1a;轻量级FBX文件解析的终极解决方案 【免费下载链接】OpenFBX Lightweight open source FBX importer 项目地址: https://gitcode.com/gh_mirrors/op/OpenFBX OpenFBX是一款轻量级开源FBX导入工具&#xff0c;专为解决3D开发中FBX文件解析难题而设计。…...

SA8775学习笔记(一)一颗 SA8775P,能不能撑起舱驾一体?从架构到实战彻底讲透(多屏+多摄+AI+安全全解析)

🚗🔥 一颗 SA8775P,能不能撑起舱驾一体?从架构到实战彻底讲透(多屏+多摄+AI+安全全解析) 🧩 一、先说结论:SA8775P不是“更强”,而是在重构整车电子架构 如果从参数看 SA8775P,很容易误判它只是“性能更强的一颗芯片”。 但放到真实整车架构里,它干的事情其实是:…...

温度通信系统 LCD显示+上位机显示 传感器使用的是ds18b20,LCD显示温度,还可以串口...

温度通信系统 LCD显示上位机显示 传感器使用的是ds18b20&#xff0c;LCD显示温度&#xff0c;还可以串口通信在pc上显示温度&#xff0c;并且有VB的上位机实时显示波形&#xff0c;实物验证成功 自己写的代码&#xff0c;注释详细 有代码有仿真 上位机显示这温度监控系统折腾了…...