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

SpringBoot16-@Configuration 类

一、@Configuration 类的执行时机

@Configuration 注解的类会在 Spring Boot 启动时自动加载,但不是"执行整个类",而是:

1. 类本身会被实例化(构造方法)

@Configuration
public class MyConfig {// 构造方法会在启动时执行public MyConfig() {System.out.println("MyConfig 被实例化了");}
}

输出:项目启动时会打印 MyConfig 被实例化了

2. @Bean 方法会被调用

@Configuration
public class MyConfig {@Beanpublic UserService userService() {System.out.println("创建 UserService Bean");return new UserService();}@Beanpublic OrderService orderService() {System.out.println("创建 OrderService Bean");return new OrderService();}
}

输出:启动时会打印:

创建 UserService Bean
创建 OrderService Bean

3. 普通方法不会自动执行

@Configuration
public class MyConfig {// ❌ 这个方法不会自动执行public void normalMethod() {System.out.println("这不会被执行");}// ✅ 只有 @Bean 方法才会执行@Beanpublic String myBean() {System.out.println("这会被执行");return "hello";}
}

完整的执行流程示例

@Configuration
public class MyConfig {// 1. 构造方法最先执行public MyConfig() {System.out.println("1. MyConfig 构造方法执行");}// 2. @Bean 方法会执行@Beanpublic UserService userService() {System.out.println("2. 创建 UserService");return new UserService();}// 3. 普通方法不会执行public void test() {System.out.println("3. 这不会执行");}// 4. @PostConstruct 会在构造方法后执行@PostConstructpublic void init() {System.out.println("4. @PostConstruct 执行");}
}

启动时输出

1. MyConfig 构造方法执行
4. @PostConstruct 执行
2. 创建 UserService

4、特殊的配置类方法

(1)implements WebMvcConfigurer 的方法

@Configuration
public class WebConfig implements WebMvcConfigurer {// ✅ 这个方法会在启动时自动执行@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {System.out.println("配置静态资源映射");registry.addResourceHandler("/upload/**").addResourceLocations("file:D:/upload/");}// ✅ 这个方法也会自动执行@Overridepublic void addInterceptors(InterceptorRegistry registry) {System.out.println("配置拦截器");registry.addInterceptor(new MyInterceptor());}
}

为什么会执行? 因为 Spring MVC 在启动时会主动调用这些配置方法。

(2)其他自动执行的配置

@Configuration
public class SecurityConfig {// ✅ Spring Security 会自动调用@Beanpublic SecurityFilterChain filterChain(HttpSecurity http) throws Exception {System.out.println("配置 Spring Security");http.authorizeHttpRequests(auth -> auth.anyRequest().authenticated());return http.build();}
}

5、验证是否被加载

方法1:使用构造方法

@Configuration
public class TestConfig {public TestConfig() {System.out.println("===== TestConfig 已加载 =====");}
}

方法2:使用 @PostConstruct

@Configuration
public class TestConfig {@PostConstructpublic void init() {System.out.println("===== TestConfig 初始化完成 =====");}
}

方法3:使用 ApplicationRunner

@Configuration
public class StartupConfig {@Beanpublic ApplicationRunner runner() {return args -> {System.out.println("===== 应用启动完成 =====");};}
}

6、加载顺序控制

(1)使用 @Order 控制顺序

@Configuration
@Order(1)
public class FirstConfig {public FirstConfig() {System.out.println("第一个加载");}
}@Configuration
@Order(2)
public class SecondConfig {public SecondConfig() {System.out.println("第二个加载");}
}

控制不同的@Configuration类

(2)使用 @DependsOn 控制依赖

@Configuration
public class DatabaseConfig {@Beanpublic DataSource dataSource() {System.out.println("创建数据源");return new DataSource();}
}@Configuration
@DependsOn("dataSource")
public class ServiceConfig {@Beanpublic UserService userService(DataSource dataSource) {System.out.println("创建 UserService(依赖数据源)");return new UserService(dataSource);}
}

7、条件加载

(1)只在特定条件下加载@Conditional

@Configuration
@ConditionalOnProperty(name = "feature.enabled", havingValue = "true")
public class FeatureConfig {public FeatureConfig() {System.out.println("功能已启用,加载配置");}
}
# application.yml
feature:enabled: true  # 改为 false 则不加载

(2)根据环境加载@Profile

@Configuration
@Profile("dev")
public class DevConfig {public DevConfig() {System.out.println("开发环境配置");}
}@Configuration
@Profile("prod")
public class ProdConfig {public ProdConfig() {System.out.println("生产环境配置");}
}

8、完整示例:监控配置类加载

@Configuration
@Slf4j
public class WebConfig implements WebMvcConfigurer {// 1. 构造方法public WebConfig() {log.info("========================================");log.info("WebConfig 开始加载");log.info("========================================");}// 2. 初始化方法@PostConstructpublic void init() {log.info("WebConfig 初始化完成");}// 3. 配置静态资源(自动执行)@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {log.info("开始配置静态资源映射");registry.addResourceHandler("/upload/**").addResourceLocations("file:D:/upload/");log.info("静态资源映射配置完成");}// 4. Bean 创建@Beanpublic MyService myService() {log.info("创建 MyService Bean");return new MyService();}
}

启动日志

WebConfig 开始加载
WebConfig 初始化完成
开始配置静态资源映射
静态资源映射配置完成
创建 MyService Bean

9、总结

会自动执行不会自动执行
构造方法普通方法
@Bean 方法没有注解的方法
@PostConstruct 方法-
WebMvcConfigurer 的重写方法-

关键点

  • @Configuration 类在启动时会被实例化
  • 只有特定方法会自动执行(@Bean、配置接口的方法等)
  • 普通方法不会执行,除非手动调用
  • 可以用构造方法或 @PostConstruct 验证类是否加载

二、@Configuration 类和 spring.factories文件

2-1、@Configuration 类的自动扫描

大多数情况:自动扫描(不需要注册)

只要 @Configuration 类在主启动类的包或子包下,Spring Boot 会自动扫描并加载

com.example.myapp
├── MyApplication.java          # 主启动类
├── config
│   ├── WebConfig.java         # ✅ 自动扫描
│   └── SecurityConfig.java    # ✅ 自动扫描
├── controller
│   └── UserController.java    # ✅ 自动扫描
└── service└── UserService.java        # ✅ 自动扫描
@SpringBootApplication  // 包含 @ComponentScan
public class MyApplication {public static void main(String[] args) {SpringApplication.run(MyApplication.class, args);}
}

原理

@SpringBootApplication 包含了 @ComponentScan,会扫描当前包及子包下所有带 @Component@Configuration@Service 等注解的类。

示例:普通配置类(无需注册)

package com.example.myapp.config;@Configuration
public class WebConfig implements WebMvcConfigurer {@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/upload/**").addResourceLocations("file:D:/upload/");}
}

启动时会自动加载 ✅ 不需要在任何文件中注册

2-2、spring.factories 的使用场景

spring.factories 只在特定场景下需要:

场景1:自动配置类(Auto-Configuration)

当你开发一个 starter 或需要自动配置时才需要。

my-spring-boot-starter
├── src/main/java
│   └── com.example.starter
│       └── MyAutoConfiguration.java
└── src/main/resources└── META-INF└── spring.factories  # ⚠️ 这里才需要

spring.factories:

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.starter.MyAutoConfiguration
@Configuration
@ConditionalOnClass(SomeClass.class)
public class MyAutoConfiguration {@Beanpublic MyService myService() {return new MyService();}
}

场景2:外部包的配置类

如果配置类在主启动类包之外,有两种解决方案:

方案A:使用 @Import(推荐)
@SpringBootApplication
@Import(ExternalConfig.class)  // 导入外部配置
public class MyApplication {public static void main(String[] args) {SpringApplication.run(MyApplication.class, args);}
}

方案B:使用 @ComponentScan 指定包
@SpringBootApplication
@ComponentScan(basePackages = {"com.example.myapp",      // 主包"com.external.config"     // 外部包
})
public class MyApplication {public static void main(String[] args) {SpringApplication.run(MyApplication.class, args);}
}

方案C:使用 spring.factories

META-INF/spring.factories:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.external.config.ExternalConfig

2-3、对比:什么时候需要注册

场景是否需要注册注册方式
项目内的配置类(同包或子包)❌ 不需要自动扫描
自定义 Starter 的自动配置✅ 需要spring.factories
外部 jar 包的配置类✅ 需要spring.factories 或 @Import/@ComponetScan
第三方库的配置✅ 需要spring.factories(由第三方提供)

2-4、完整示例对比

示例1:普通项目配置(不需要 spring.factories)

my-project
├── src/main/java
│   └── com.example.myapp
│       ├── MyApplication.java
│       ├── config
│       │   ├── WebConfig.java        # ✅ 自动加载
│       │   ├── SecurityConfig.java   # ✅ 自动加载
│       │   └── DatabaseConfig.java   # ✅ 自动加载
│       ├── controller
│       └── service
└── src/main/resources├── application.yml└── 无需 spring.factories ❌

示例2:开发 Starter(需要 spring.factories)

my-redis-starter
├── src/main/java
│   └── com.example.redis
│       ├── RedisAutoConfiguration.java
│       └── RedisTemplate.java
└── src/main/resources└── META-INF└── spring.factories  # ✅ 必须有

spring.factories:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.redis.RedisAutoConfiguration

使用方只需要引入依赖:

<dependency><groupId>com.example</groupId><artifactId>my-redis-starter</artifactId>
</dependency>

自动配置就会生效,无需手动 @Import

2-5、验证是否自动加载

方法1:启动日志

@Configuration
@Slf4j
public class WebConfig implements WebMvcConfigurer {public WebConfig() {log.info("========================================");log.info("WebConfig 已自动加载(无需注册)");log.info("========================================");}
}

启动项目,看到日志就说明自动加载了。

方法2:使用 @Autowired 测试

@RestController
public class TestController {@Autowiredprivate ApplicationContext context;@GetMapping("/test")public String test() {// 检查 Bean 是否存在boolean exists = context.containsBean("webConfig");return "WebConfig exists: " + exists;}
}

2-6、spring.factories 的完整格式

如果你真的需要用 spring.factories

位置src/main/resources/META-INF/spring.factories

# 自动配置类
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.config.MyAutoConfiguration,\
com.example.config.AnotherAutoConfiguration# 应用监听器
org.springframework.context.ApplicationListener=\
com.example.listener.MyApplicationListener# 环境后置处理器
org.springframework.boot.env.EnvironmentPostProcessor=\
com.example.processor.MyEnvironmentPostProcessor

2-7、常见误区

❌ 误区1:所有配置类都要注册

// 错误认知:需要在 spring.factories 注册
@Configuration
public class WebConfig {// ...
}

正确:项目内的配置类自动扫描,无需注册。

❌ 误区2:@Component 类需要注册

// 错误认知:需要在 spring.factories 注册
@Service
public class UserService {// ...
}

正确@Service@Component@Controller 等都会自动扫描。

✅ 正确认知

  • 99% 的情况:不需要 spring.factories
  • 只有开发 starter 或外部库:才需要 spring.factories

2-8、总结

项目结构:
├── 主启动类
├── 同包或子包
│   └── @Configuration 类  → ✅ 自动扫描,无需注册
│
├── 外部包(其他项目)
│   └── @Configuration 类  → ⚠️ 需要 @Import 或 spring.factories
│
└── 自定义 Starter└── 自动配置类      → ✅ 必须用 spring.factories

记住

  • 普通项目的配置类 → 不需要 spring.factories
  • 开发 Starter 或库 → 才需要 spring.factories
http://www.dtcms.com/a/609970.html

相关文章:

  • 【EGO-Planner自主无人机】在编译EGO-Planner源码时遇到的问题
  • 农业无人机实训教学转型—虚拟仿真破解“三高三难”
  • 专做五金正品的网站网站的定位分析
  • Android开发-java版:SQLite数据库
  • PHP进阶-在Ubuntu上搭建LAMP环境教程
  • 苔藓泛基因组--文献精读174
  • 购物网站建设过程视频权威发布信息
  • 网站建设营销方案wordpress添加微信分享功能
  • JavaWeb项目打包、部署至Tomcat并启动的全程指南(图文详解)
  • Netty和Tomcat有什么区别
  • 多标签页导航后台模板 html+css+js 纯手写 无第三方UI框架 复制粘贴即用
  • 做贷款网站犯法英文网站字体大小
  • Docker Desktop(Windows/Mac)零外网部署 Dify 极简指南
  • 1015 Reversible Primes
  • Nextcloud容器化部署新范式:Docker与Cpolar如何重塑私有云远程访问能力
  • 网站资源建设方案西安网页设计培训
  • AI Compass前沿速览:GPT--Codex 、宇树科技世界模型、InfiniteTalk美团数字人、ROMA多智能体框架、混元D .
  • 做维修那个网站发布信息好编辑不了的wordpress
  • 织梦摄影网站模板长沙网站制作公司怎么做
  • 《Chrome》 [142.0.7444.60][绿色便携版] 下载
  • leetcode2536. 子矩阵元素加 1
  • 11.6-11.14力扣前缀和刷题
  • vue3.0数据驱动问题
  • Java 8+新特性实战:Lambda表达式、Stream API与函数式编程范式
  • Rust新手第一课:Mac环境搭建踩坑记录
  • 长沙品质网站建设优点wordpress导入插件下载
  • 男的和女的做那个视频网站国内网站建设代理
  • 操作教程 |JumpServer堡垒机数据脱敏功能的使用
  • Ⅰ人工智能学习的核心概念概述+线性回归(1)
  • KKT条件:对偶问题、KKT条件以及内点法