
在 Spring Boot 中,被 @Service、@RestController 或 @Configuration 等注解标记的类作为 Spring Bean,其构造函数会在应用启动时由 IoC 容器创建单例实例的过程中执行,且仅执行一次(默认单例作用域下)。
在 spring boot 中,被 `@service`、@restcontroller` 或 `@configuration` 等注解标记的类作为 spring bean,其构造函数会在应用启动时由 ioc 容器创建单例实例的过程中执行,且仅执行一次(默认单例作用域下)。
Spring Boot 应用启动时,Spring IoC 容器会扫描所有带组件注解(如 @RestController、@Service、@Component、@Configuration)的类,并根据其作用域(scope)决定实例化时机与次数。对于默认的 singleton 作用域(绝大多数 Bean 的默认值),构造函数会在容器刷新(refresh())阶段、上下文初始化完成前被调用——即应用启动过程中,且仅执行一次。
以您提供的控制器为例:
@RestController
@RequestMapping("/api/v1")
public class MessageController {
private final RabbitMQProducer producer; // 推荐使用 final 字段 + 构造注入
public MessageController(RabbitMQProducer producer) {
this.producer = producer; // ✅ 构造函数在此处执行:依赖已就绪,对象完成初始化
}
@GetMapping("/publish")
public ResponseEntity<string> sendMessage(@RequestParam("message") String message) {
producer.sendMessage(message);
return ResponseEntity.ok("message sent to the rabbitmq");
}
}</string>
该类被 @RestController 标记,因此是 Spring 管理的 Bean。当 Spring 启动并构建 ApplicationContext 时,它会按依赖顺序(拓扑排序)依次实例化 Bean:先创建 RabbitMQProducer(假设它也是 @Service 或 @Component),再将其注入 MessageController 的构造函数中——此时 MessageController 的构造函数被执行。
一款AI开发辅助工具,主要用于通过后台进程将编码任务委托给 Codex、Claude Code 或 Pi 智能体。适用场景:(1)构建或创建新功能/应用,(2)审查 PR,适合需要提升相关任务效率的用户。
⚠️ 注意事项:
- 构造函数执行 ≠ 对象完全可用:构造函数执行后,Spring 还可能执行 @PostConstruct 方法、InitializingBean.afterPropertiesSet() 或自定义 init-method,这些均在构造完成后、Bean 被放入容器前发生。
- 非单例 Bean(如 @Scope("prototype")):每次通过 applicationContext.getBean() 获取时都会触发新构造函数调用;但 Web 层控制器几乎从不使用 prototype 作用域(因线程安全与设计模式限制)。
- 构造注入优于字段注入:如示例所示,使用构造函数参数注入(Constructor Injection)不仅语义清晰、线程安全、利于单元测试,还确保依赖不可变(配合 final 字段),是 Spring 官方推荐的方式(自 Spring 4.3+ 对单构造函数场景自动启用)。
- 循环依赖场景:若两个 Bean 相互通过构造函数注入,Spring 无法解决(抛出 BeanCurrentlyInCreationException),需改用 setter 或 @Lazy 注解破环。
✅ 总结:Spring Boot 中,@RestController 等组件类的构造函数,在应用启动阶段、IoC 容器初始化 Bean 图时执行,严格遵循依赖顺序,且默认仅执行一次。这是 Spring 生命周期管理的核心环节,也是实现松耦合与可测试性的基石。










