spring中的@Configuration注解详解


一、概述与核心作用

@Configuration是Spring框架中用于定义配置类的核心注解,旨在替代传统的XML配置方式,通过Java代码实现Bean的声明、依赖管理及环境配置。其核心作用包括:

  1. 标识配置类:标记一个类为Spring的配置类,容器启动时会自动解析其中的Bean定义。
  2. 定义Bean:通过@Bean注解的方法声明Spring管理的Bean实例。
  3. 依赖管理:支持通过构造函数或字段注入其他Bean,实现依赖关系的自动装配。
  4. 条件化配置:结合@Conditional等注解,根据环境或属性动态决定Bean的创建。
  5. 模块化配置:通过@Import导入其他配置类,实现配置的分层与复用。

二、底层实现原理

  1. 配置类解析机制
    Spring通过ConfigurationClassPostProcessor后置处理器解析@Configuration类,分为三个阶段:

    • 解析阶段:扫描类中的@Bean方法及依赖关系,生成BeanDefinition对象。

    • 注册阶段:将BeanDefinition注册到IoC容器中。

    • 验证阶段:检查配置的合法性(如循环依赖)。

  2. 单例保证与代理机制
    Spring默认使用CGLIB动态代理为配置类生成子类,确保:

    • @Bean方法调用返回同一实例(单例模式)。

    • 避免直接调用@Bean方法导致多次实例化问题。

  3. 条件化配置实现
    结合@Conditional注解,通过实现Condition接口的matches()方法,根据环境变量、属性文件等条件动态加载Bean。


三、使用示例与语法

  1. 基本配置类

    @Configuration
    public class AppConfig {@Beanpublic MyService myService() {return new MyServiceImpl();}
    }
    
    • @Bean方法返回的实例由Spring管理,默认单例。
  2. 依赖注入示例

    @Configuration
    public class ServiceConfig {@Autowiredprivate DataSource dataSource;@Beanpublic UserService userService() {return new UserServiceImpl(dataSource);}
    }
    

    • 支持字段注入或构造函数注入依赖。

  3. 条件化Bean定义

    @Configuration
    public class EnvConfig {@Bean@ConditionalOnProperty(name = "env.mode", havingValue = "dev")public DataSource devDataSource() {return new DevDataSource();}
    }
    
    • 仅在env.mode=dev时创建该Bean。

四、高级特性与最佳实践

  1. 模块化配置
    将不同功能的配置拆分到多个类(如DataConfigWebConfig),通过@Import组合:

    @Configuration
    @Import({DataConfig.class, ServiceConfig.class})
    public class MainConfig {}
    
  2. 外部化属性配置
    使用@PropertySource加载属性文件,并通过@Value注入:

    @Configuration
    @PropertySource("classpath:application.properties")
    public class AppConfig {@Value("${app.name}")private String appName;
    }
    
  3. 避免硬编码与手动实例化
    • 优先通过@ComponentScan自动扫描组件,减少显式@Bean定义。

    • 禁止在配置类中手动new Bean(),否则绕过Spring生命周期管理。

  4. 处理有参构造函数
    • 若配置类存在有参构造,需通过@Bean方法显式实例化或使用@Autowired依赖注入:

    @Configuration
    public class MyConfig {@Beanpublic MyBean myBean(String param) {return new MyBean(param);}
    }
    

五、注意事项与常见问题

  1. 循环依赖
    配置类中若Bean A依赖Bean B,且B也依赖A,需通过@Lazy延迟加载或重构代码结构。

  2. 代理模式的影响
    若需禁用CGLIB代理(如测试场景),可通过@Configuration(proxyBeanMethods = false)关闭,但需注意单例失效风险。

  3. 多环境配置
    结合@Profile注解区分不同环境的Bean定义(如开发、生产)。


六、@Configuration注解与@Component注解的区别

在Spring框架中,@Configuration@Component都是用于定义Spring Bean的注解,但它们在用途、行为和设计目的上有显著的区别。以下是两者的主要区别:

1. 核心用途与设计目的
  • @Configuration

    • 用途:用于标记一个类是配置类,通常用于定义Bean的创建逻辑和依赖关系。
    • 设计目的:通过@Bean方法显式声明Bean,支持复杂的Bean初始化逻辑(如条件判断、依赖注入、方法调用等)。
    • 适用场景:需要集中管理Bean定义、支持编程式配置或动态配置时。
  • @Component

    • 用途:用于标记一个类是Spring管理的组件(如服务、DAO、工具类等)。
    • 设计目的:通过类扫描自动发现Bean,简化配置。
    • 适用场景:普通组件类,无需复杂初始化逻辑。

2. Bean的创建方式
  • @Configuration

    • 通过@Bean方法显式定义Bean。
    • 关键行为
      • 默认使用CGLIB代理,确保@Bean方法在同一个配置类中多次调用时返回同一个Bean实例(避免重复创建)。
      • 支持方法间的依赖注入(例如,一个@Bean方法可以调用另一个@Bean方法)。
    • 示例
      @Configuration
      public class AppConfig {@Beanpublic ServiceA serviceA() {return new ServiceA();}@Beanpublic ServiceB serviceB() {// 依赖注入serviceAreturn new ServiceB(serviceA());}
      }
      
  • @Component

    • 通过类扫描自动注册Bean。
    • 关键行为
      • 不支持@Bean方法,Bean的创建逻辑通常在类的构造函数或初始化方法中定义。
      • 如果需要依赖其他Bean,通过@Autowired注入。
    • 示例
      @Component
      public class MyService {private final Dependency dependency;@Autowiredpublic MyService(Dependency dependency) {this.dependency = dependency;}
      }
      

3. 代理机制
  • @Configuration

    • 使用CGLIB代理,确保@Bean方法在同一个配置类中多次调用时返回同一个实例
    • 示例
      @Configuration
      public class Config {@Beanpublic BeanA beanA() {return new BeanA();}@Beanpublic BeanB beanB() {// 多次调用beanA()返回同一个实例return new BeanB(beanA(), beanA()); }
      }
      
  • @Component

    • 不使用代理,直接实例化类。如果类中包含方法调用(非@Bean方法),每次调用都会创建新实例。
    • 示例
      @Component
      public class MyComponent {public BeanA createBeanA() {return new BeanA(); // 每次调用都会创建新实例}
      }
      

4. 适用场景对比
场景推荐使用原因
集中管理Bean定义@Configuration支持@Bean方法、方法间依赖、条件化配置等。
普通组件类@Component简化配置,通过类扫描自动发现。
动态Bean初始化逻辑@Configuration可以通过@Bean方法实现条件判断、环境依赖等复杂逻辑。
静态Bean定义@Component适合无复杂逻辑的组件类。
测试或Mock配置@Configuration方便在测试中覆盖或替换Bean。

5. 其他相关注解
  • @Component的派生注解
    • @Service@Repository@Controller等都是@Component的特化版本,功能相同,但语义更明确。
  • @Configuration的扩展
    • @Profile:结合@Configuration实现条件化配置。
    • @Import:导入其他配置类。

6. 总结
  • @Configuration:用于配置类,支持@Bean方法和复杂Bean初始化逻辑,适合集中管理Bean定义。
  • @Component:用于普通组件类,通过类扫描自动注册,适合简单组件。

选择建议

  • 如果需要定义Bean的创建逻辑或管理依赖关系,使用@Configuration
  • 如果只是标记一个普通类为Spring Bean,使用@Component或其派生注解(如@Service)。

总结

@Configuration注解是Spring实现Java-Based配置的核心工具,通过动态代理、条件化加载和模块化设计,简化了Bean管理与依赖注入流程。合理使用其特性可显著提升代码的可维护性与灵活性,同时需注意避免循环依赖和硬编码问题。


spring中的@bean注解详解

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/79141.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

7.计算机网络相关术语

7. 计算机网络相关术语 ACK (Acknowledgement) 确认 ADSL (Asymmetric Digital Subscriber Line) 非对称数字用户线 AP (Access Point) 接入点 AP (Application) 应用程序 API (Application Programming Interface) 应用编程接口 APNIC (Asia Pacific Network Informatio…

Hadoop 集群基础指令指南

目录 🧩 一、Hadoop 基础服务管理指令 ▶️ 启动 Hadoop ⏹️ 关闭 Hadoop 🧾 查看进程是否正常运行 📁 二、HDFS 常用文件系统指令 🛠️ 三、MapReduce 作业运行指令 📋 四、集群状态监控指令 💡 …

【MySQL数据库】事务

目录 1,事务的详细介绍 2,事务的属性 3,事务常见的操作方式 1,事务的详细介绍 在MySQL数据库中,事务是指一组SQL语句作为一个指令去执行相应的操作,这些操作要么全部成功提交,对数据库产生影…

一、OrcaSlicer源码编译

一、下载 1、OrcaSlicer 2.3.0版本的源码 git clone https://github.com/SoftFever/OrcaSlicer.git -b v2.3.0 二、编译 1、在OrcaSlicer目录运行cmd窗口,输入build_release.bat 2、如果出错了,可以多运行几次build_release.bat 3、在OrcaSlicer\b…

港口危货储存单位主要安全管理人员考试精选题目

港口危货储存单位主要安全管理人员考试精选题目 1、危险货物储存场所的电气设备应符合( )要求。 A. 防火 B. 防爆 C. 防尘 D. 防潮 答案:B 解析:港口危货储存单位存在易燃易爆等危险货物,电气设备若不防爆&…

格雷希尔用于工业气体充装站的CZ系列气罐充装转换连接器,其日常维护有哪些

格雷希尔气瓶充装连接器,长期用于压缩气体的快速充装和压缩气瓶的气密性检测,需要进行定期的维护,为每一次的充装提供更好的连接。下列建议的几点维护准则适用于格雷希尔所有充注接头,请非专业人士不要随意拆卸连接器。 格雷希尔气…

Java 多线程进阶:什么是线程安全?

在多线程编程中,“线程安全”是一个非常重要但又常被误解的概念。尤其对于刚接触多线程的人来说,不理解线程安全的本质,容易写出“偶尔出错”的代码——这类 bug 往往隐蔽且难以复现。 本文将用尽可能通俗的语言,从三个角度解释线…

MSO-Player:基于vlc的Unity直播流播放器,支持主流RTSP、RTMP、HTTP等常见格式

MSO-Player 基于libVLC的Unity视频播放解决方案 支持2D视频和360度全景视频播放的Unity插件 📑 目录 🎥 MSO-Player 📋 功能概述🚀 快速入门📚 关键组件📝 使用案例🔌 依赖项📋 注意…

navicat中导出数据表结构并在word更改为三线表(适用于navicat导不出doc)

SELECTCOLUMN_NAME 列名,COLUMN_TYPE 数据类型,DATA_TYPE 字段类型,IS_NULLABLE 是否为空,COLUMN_DEFAULT 默认值,COLUMN_COMMENT 备注 FROMINFORMATION_SCHEMA.COLUMNS WHEREtable_schema db_animal(数据库名) AND table_name activity(…

docker学习笔记6-安装wordpress

一、创建自定义网络、查看网络 docker netword create blog docker network ls 二、 启动mysql容器 启动命令: docker run -d -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD123456 \ -e MYSQL_DATABASEwordpress \ -v mysql-data:/var/lib/mysql \ -v /app/myconf:/etc…

03_Mybatis-Plus LambadaQueryWrapper 表达式爆空指针异常

&#x1f31f; 03_MyBatis-Plus LambdaQueryWrapper 爆出空指针异常的坑点分析 ❓ 场景描述 来看一段常见的 MyBatis-Plus 查询写法&#xff0c;是否存在问题&#xff1f; Page<VideoInfoVo> videoInfoVosPage videoMapper.selectPage(page, new LambdaQueryWrapper&…

WEB安全--社会工程--SET钓鱼网站

1、选择要钓鱼的网站 2、打开kali中的set 3、启动后依次选择&#xff1a; 4、输入钓鱼主机的地址&#xff08;kali&#xff09;和要伪装的网站域名&#xff1a; 5、投放钓鱼网页&#xff08;服务器域名:80&#xff09; 6、获取账号密码

Ethan独立开发产品日报 | 2025-04-29

1. mrge 代码审查的光标 mrge 是一个由人工智能驱动的代码审查平台&#xff0c;能够自动审核拉取请求&#xff08;PR&#xff09;&#xff0c;为人工审查员提供超级能力。它是像 cal.com 和 n8n 这样快速发展的团队的首选工具。 关键词&#xff1a;mrge, 代码审查, AI驱动, …

ubuntu22.04 qemu arm64 环境搭建

目录 创建 安装 Qemu 启动 # 进入qemu虚拟机后执行 qemu编译器安装 创建 qemu-img create ubuntu22.04_arm64.img 40G 安装 qemu-system-aarch64 -m 4096 -cpu cortex-a57 -smp 4 -M virt -bios QEMU_EFI.fd -nographic -drive ifnone,fileubuntu-22.04.5-live-server-a…

安全生产知识竞赛宣传口号160句

1. 安全生产是责任&#xff0c;每个人都有责任 2. 安全生产是保障&#xff0c;让我们远离危险 3. 安全生产是团结&#xff0c;共同守护每一天 4. 注重安全&#xff0c;守护明天 5. 安全生产无小事&#xff0c;关乎千家万户 6. 安全第一&#xff0c;人人有责 7. 安全生产无差别&…

Python 虚拟环境管理:venv 与 conda 的选择与配置

文章目录 前言一、虚拟环境的核心价值1.1 依赖冲突的典型场景1.2 隔离机制实现原理 二、venv 与 conda 的架构对比2.1 工具定位差异2.2 性能基准测试&#xff08;以创建环境 安装 numpy 为例&#xff09; 三、venv 的配置与最佳实践3.1 基础工作流3.2 多版本 Python 管理 四、…

【自然语言处理与大模型】如何获取特定领域的微调数据集?

在特定领域中&#xff0c;数据集通常由提出需求的一方提供。然而&#xff0c;在某些情况下&#xff0c;如果他们未能提供所需的数据&#xff0c;或者你正在独立开展一个项目&#xff0c;并且需要相应的数据来推进工作&#xff0c;这时你应该怎么办呢&#xff1f;本文提供一种思…

Map系列之ConcurrentHashMap源码分析:高并发场景下的性能密码

引言&#xff1a;当线程安全成为刚需 1.1 并发时代的Map困境 经典案例&#xff1a;电商秒杀系统超卖事故分析&#xff08;附线程堆栈截图&#xff09;传统方案缺陷&#xff1a;synchronizedMap的吞吐量陷阱&#xff08;JMH测试数据对比&#xff09;ConcurrentHashMap的定位&a…

URP - 序列图动画的实现

效果&#xff1a; 【太妃糖耶】更新了一条视频&#xff0c;快来围观&#xff01; 序列图动画的实现 首先先了解下序列图样式的纹理图片 如上图一可在Shader中使用该图片制作燃烧的火的动画&#xff0c;但是如何实现呢&#xff1f;接下来一起来看一下吧 序列图动画的实现原理大…

python中 str.strip() 是什么意思

在 Python 中&#xff0c;str.strip() 是字符串&#xff08;str&#xff09;类型的一个方法&#xff0c;用于移除字符串两端的空白字符&#xff08;默认情况下&#xff09;或指定字符&#xff0c;并返回处理后的新字符串。 语法&#xff1a; str.strip([chars])chars&#xf…