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

Spring Boot 配置类注解@Configuration详解:从基础到实战

在 Spring Boot 开发中,配置类是替代传统 XML 配置的核心载体,通过一系列注解可实现 Bean 注册、属性绑定、条件装配等关键功能。本文将深入解析常用配置类注解,结合示例代码与实战场景,帮你彻底掌握配置类的使用技巧。

一、核心基础注解:构建配置类基石

1. @Configuration:标记配置类

作用

声明当前类为配置类,相当于传统 Spring 的applicationContext.xml文件,Spring 容器会自动扫描并加载该类中的配置。

用法与示例
import org.springframework.context.annotation.Configuration;// 标记当前类为配置类@Configurationpublic class AppConfig {// 配置内容(如@Bean注解定义Bean)}
关键注意点
+ **proxyBeanMethods 属性**:Spring Boot 2.x 新增,默认值为`true`。
// 无Bean依赖场景,设置proxyBeanMethods=false优化性能@Configuration(proxyBeanMethods = false)public class SimpleConfig {@Beanpublic User user() {return new User();}}
  • true(默认):配置类会被动态代理,类中 @Bean 方法调用时会返回容器中已存在的 Bean 实例(保证单例)。
  • false:配置类不会生成代理,@Bean 方法调用时会创建新实例,适用于无依赖的简单配置,可提升启动性能。示例:
  • @Component的区别:@Configuration本质是@Component的子类,但前者更强调 “配置功能”,且支持 proxyBeanMethods 特性。

2. @Bean:注册 Bean 实例

作用
在配置类中定义方法,方法返回值会被注册为 Spring 容器中的 Bean,默认 Bean 名称为方法名。
用法与示例
import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class BeanConfig {// 注册名为"userService"的Bean,类型为UserService@Beanpublic UserService userService() {return new UserService();}// 自定义Bean名称,同时指定初始化和销毁方法@Bean(name = "orderService",  // 自定义Bean名称initMethod = "init",    // 初始化方法(对应OrderService的init())destroyMethod = "destroy" // 销毁方法(对应OrderService的destroy()))public OrderService createOrderService() {return new OrderService();}}// 对应Bean类class OrderService {public void init() {System.out.println("OrderService初始化");}public void destroy() {System.out.println("OrderService销毁");}}
关键注意点
+ Bean 的作用域:默认是单例(`singleton`),可通过`@Scope`注解修改(如`@Scope("prototype")`多例)。 + 依赖注入:@Bean 方法可通过参数注入容器中已存在的 Bean,示例:

@Beanpublic OrderService orderService(UserService userService) {// 注入UserService依赖OrderService orderService = new OrderService();orderService.setUserService(userService);return orderService;}

二、依赖导入注解:组合多配置资源

1. @Import:直接导入配置类 / Bean

作用
在一个配置类中导入其他配置类、普通类或特定接口实现类,无需被导入类标注`@Configuration`。
用法与示例
(1)导入配置类
// 配置类1@Configurationpublic class DbConfig {@Beanpublic DataSource dataSource() {return new HikariDataSource();}}// 配置类2:导入DbConfig,无需再扫描DbConfig@Configuration@Import(DbConfig.class)public class AppMainConfig {// 可直接使用DbConfig中注册的DataSource}
(2)导入普通类(自动注册为 Bean)
// 普通类(无任何注解)public class LogService {public void log() {System.out.println("日志输出");}}// 配置类导入普通类,LogService会被注册为Bean@Configuration@Import(LogService.class)public class AppConfig {}
(3)导入 ImportSelector 实现类(动态导入)
// 自定义ImportSelector,指定要导入的类public class MyImportSelector implements ImportSelector {@Overridepublic String\[] selectImports(AnnotationMetadata importingClassMetadata) {// 返回要导入的类的全限定名数组return new String\[]{"com.example.service.CacheService"};}}// 配置类导入Selector@Configuration@Import(MyImportSelector.class)public class AppConfig {}

2. @ImportResource:导入 XML 配置

作用
兼容传统 Spring XML 配置文件,将 XML 中定义的 Bean 导入到 Spring Boot 容器中。
用法与示例
// 导入classpath下的spring-bean.xml配置@Configuration@ImportResource("classpath:spring-bean.xml")public class XmlConfig {}// spring-bean.xml示例\<?xml version="1.0" encoding="UTF-8"?>\<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">\<bean id="xmlService" class="com.example.service.XmlService"/>\</beans>

三、属性绑定注解:关联配置文件

1. @ConfigurationProperties:批量绑定属性

作用

将配置文件(如 application.yml/application.properties)中的属性批量绑定到 Java 类的字段上,替代繁琐的@Value注解。

用法与示例
(1)定义属性绑定类
import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.stereotype.Component;// 前缀prefix指定配置文件中属性的统一前缀@ConfigurationProperties(prefix = "app.datasource")@Component // 注册为Bean,或通过@EnableConfigurationProperties启用public class DataSourceProperties {private String url;private String username;private String password;private int maxPoolSize;// 必须提供getter和setter方法public String getUrl() { return url; }public void setUrl(String url) { this.url = url; }// 其他字段的getter/setter省略}
(2)配置文件(application.yml)
app:datasource:url: jdbc:mysql://localhost:3306/testusername: rootpassword: 123456max-pool-size: 10 # 支持"-"分隔符,自动映射到maxPoolSize
(3)启用属性绑定(两种方式)
+ 方式一:在绑定类上添加`@Component`(如上例)。 + 方式二:在配置类上添加`@EnableConfigurationProperties`:
@Configuration@EnableConfigurationProperties(DataSourceProperties.class)public class DataSourceConfig {// 可注入DataSourceProperties使用@Beanpublic DataSource dataSource(DataSourceProperties properties) {HikariDataSource dataSource = new HikariDataSource();dataSource.setJdbcUrl(properties.getUrl());dataSource.setUsername(properties.getUsername());dataSource.setPassword(properties.getPassword());dataSource.setMaximumPoolSize(properties.getMaxPoolSize());return dataSource;}}
关键注意点
+ 支持松散绑定:配置文件中的`max-pool-size`可映射到 Java 类的`maxPoolSize`(驼峰命名)。 + 支持 JSR303 校验:添加`@Validated`注解实现属性校验,示例:
import org.springframework.validation.annotation.Validated;import javax.validation.constraints.NotEmpty;import javax.validation.constraints.Max;@ConfigurationProperties(prefix = "app.datasource")@Component@Validated // 启用校验public class DataSourceProperties {@NotEmpty(message = "数据库URL不能为空")private String url;@Max(value = 20, message = "最大连接池不能超过20")private int maxPoolSize;// 省略getter/setter}

2. @PropertySource:加载自定义配置文件

作用

加载类路径下的自定义配置文件(非默认的 application.yml/properties),配合@Value@ConfigurationProperties使用。

用法与示例
import org.springframework.context.annotation.PropertySource;import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.stereotype.Component;// 加载classpath下的custom.properties文件@Component@PropertySource("classpath:custom.properties")@ConfigurationProperties(prefix = "custom")public class CustomProperties {private String name;private String version;// getter/setter省略}// custom.properties文件custom.name=MyAppcustom.version=1.0.0
关键注意点
  • 默认只支持 properties 格式文件,加载 yaml 文件需指定factory
@PropertySource(value = "classpath:custom.yml", factory = YamlPropertySourceFactory.class)

(需自定义YamlPropertySourceFactory,或引入 Spring Boot 扩展依赖)

四、条件装配注解:按需注册 Bean

条件注解用于根据特定条件决定 Bean 是否注册到容器中,核心是@Conditional接口,Spring Boot 提供了多种开箱即用的实现。

1. 常用条件注解

注解作用示例
@ConditionalOnClass当类路径存在指定类时生效@ConditionalOnClass(DataSource.class)
@ConditionalOnMissingClass当类路径不存在指定类时生效@ConditionalOnMissingClass("com.example.service.CacheService")
@ConditionalOnBean当容器中存在指定 Bean 时生效@ConditionalOnBean(DataSource.class)
@ConditionalOnMissingBean当容器中不存在指定 Bean 时生效@ConditionalOnMissingBean(UserService.class)
@ConditionalOnProperty当配置文件中指定属性满足条件时生效@ConditionalOnProperty(prefix = "app", name = "enable", havingValue = "true")
@ConditionalOnWebApplication当应用是 Web 应用时生效直接标注在配置类或 @Bean 方法上
@ConditionalOnNotWebApplication当应用不是 Web 应用时生效直接标注在配置类或 @Bean 方法上

2. 用法示例

@Configurationpublic class ConditionalConfig {// 当配置文件中app.enable-cache=true时,注册CacheService@Bean@ConditionalOnProperty(prefix = "app", name = "enable-cache", havingValue = "true")public CacheService cacheService() {return new RedisCacheService();}// 当容器中不存在CacheService时,注册默认的LocalCacheService@Bean@ConditionalOnMissingBean(CacheService.class)public CacheService defaultCacheService() {return new LocalCacheService();}// 当类路径存在HikariDataSource时,注册数据源@Bean@ConditionalOnClass(com.zaxxer.hikari.HikariDataSource.class)public DataSource hikariDataSource() {return new com.zaxxer.hikari.HikariDataSource();}}

五、实战案例:整合配置类注解开发

以 “数据源配置” 为例,整合上述注解实现灵活配置:

1. 定义属性绑定类

import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.validation.annotation.Validated;import javax.validation.constraints.NotEmpty;import javax.validation.constraints.Max;@ConfigurationProperties(prefix = "app.datasource")@Validatedpublic class DataSourceProperties {@NotEmpty(message = "数据库URL不能为空")private String url;@NotEmpty(message = "用户名不能为空")private String username;private String password;@Max(value = 20, message = "最大连接池不能超过20")private int maxPoolSize = 10; // 默认值// getter/setter省略}

2. 配置类实现条件装配

import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.ImportResource;import org.springframework.context.annotation.PropertySource;import org.springframework.boot.context.properties.EnableConfigurationProperties;import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;@Configuration(proxyBeanMethods = false)@EnableConfigurationProperties(DataSourceProperties.class) // 启用属性绑定@PropertySource("classpath:db-custom.properties") // 加载自定义配置// @ImportResource("classpath:legacy-db.xml") // 按需导入XML配置public class DataSourceConfig {// 当存在HikariDataSource类时,注册Hikari数据源@Bean@ConditionalOnClass(com.zaxxer.hikari.HikariDataSource.class)@ConditionalOnMissingBean(DataSource.class) // 避免重复注册public DataSource hikariDataSource(DataSourceProperties properties) {com.zaxxer.hikari.HikariDataSource dataSource = new com.zaxxer.hikari.HikariDataSource();dataSource.setJdbcUrl(properties.getUrl());dataSource.setUsername(properties.getUsername());dataSource.setPassword(properties.getPassword());dataSource.setMaximumPoolSize(properties.getMaxPoolSize());return dataSource;}}

3. 配置文件(db-custom.properties)

app.datasource.url=jdbc:mysql://localhost:3306/mydbapp.datasource.username=adminapp.datasource.password=admin123app.datasource.max-pool-size=15

六、避坑指南:配置类使用注意事项

  1. 配置类扫描范围:Spring Boot 默认扫描主启动类所在包及其子包下的配置类,若配置类在其他包,需通过@SpringBootApplication(scanBasePackages = "com.example.config")指定扫描范围。
  2. @Bean 方法调用陷阱:当proxyBeanMethods=true(默认)时,配置类内部调用 @Bean 方法会返回容器中的单例 Bean;若proxyBeanMethods=false,则返回新实例,需根据依赖关系选择。
  3. 条件注解优先级:多个条件注解同时存在时,需满足所有条件才会注册 Bean(逻辑与关系)。
  4. 属性绑定优先级:配置文件优先级从高到低为:命令行参数 > 系统环境变量 > application.yml(当前目录) > application.properties(类路径) > 自定义配置文件。
  5. 避免循环依赖:配置类中 @Bean 方法的依赖关系需清晰,避免 A 依赖 B、B 依赖 A 的循环依赖场景。

总结

Spring Boot 配置类注解通过@Configuration@Bean构建基础,借助@Import@PropertySource扩展配置资源,利用@ConfigurationProperties实现属性绑定,通过@Conditional系列注解实现按需装配,形成了一套灵活高效的配置体系。掌握这些注解的核心用法与组合技巧,能大幅简化配置代码,提升项目的可维护性与扩展性。建议结合实际场景多动手实践,深入理解注解背后的设计思想。

http://www.dtcms.com/a/415052.html

相关文章:

  • python怎么做网站建站工具评测 discuz
  • ReAct 框架
  • 网站怎么做301重定向如何把做的网站发布到网上
  • 网站维护公司苏宁网站建设
  • 2.1 通信基础 (答案见原书 P38)
  • (附源码)基于Spring Boot的宿舍管理系统设计与实现0007
  • 【FreeRTOS】第七课(4):任务间的通信——一个设备的数据写入多个队列
  • js的this—13
  • 从“全量”到“增量”:Diff解析器如何彻底优化数据处理效率?
  • steamGame——饥荒联机版(2025)
  • 网站服务器连接被重置中网可信网站查询
  • 【Qt】Windows下Qt+MSVC的使用
  • STL容器:vector
  • 网站什么时候备案好wordpress 新浪博客模板
  • 嵌入式面试高频(十二)!!!C++语言(嵌入式八股文,嵌入式面经)c++11新特性
  • iptables 详解
  • 基于dify搭建的论文查询和内容提取应用(可加群)
  • elasticsearch面试八股文
  • MySQL笔记---表的约束
  • 单页产品网站源码带后台东莞全网推广
  • Kafka 事务协议 KIP-890 更强的防重、无感升级与端到端性能
  • 【精品资料鉴赏】873页5A级智慧景区信息化规划设计方案
  • kanass入门到实战(5) - 如何进行任务管理
  • Spring AI alibaba对话上下文持久化数据库
  • 嵌入式面试题合集附答案(六)
  • 青岛做模板网站的公司wordpress自定义注册页面模板
  • 【大模型】深入理解大模型输出的Temperature、Top-k与Top-p采样
  • 如何编辑网站标题简约网站设计
  • 关于七牛云OSS存储的图片数据批量下载到本地
  • 左值引用、右值引用、万能引用