Spring Boot的启动流程,以及各个扩展点的执行顺序

目录

1. 初始化阶段执行顺序

1.1 Bean的构造方法(构造函数)

1.2 @PostConstruct 注解方法

1.3 InitializingBean 的 afterPropertiesSet()

1.4 @Bean(initMethod = "自定义方法")

2. 上下文就绪后的扩展点

2.1 ApplicationContext 事件监听器

2.2 ApplicationRunner 与 CommandLineRunner

3. 完整执行顺序总结

4. 控制执行顺序的方法

5. 示例代码验证


        在Spring Boot应用中,容器初始化及组件执行的顺序遵循特定的生命周期。以下是常见的初始化组件及其执行顺序的详细说明,帮助您合理控制代码逻辑的加载顺序。


1. 初始化阶段执行顺序

以下是Spring Boot应用启动时,各初始化方法的执行顺序(从上到下依次执行):

1.1 Bean的构造方法(构造函数)
  • 触发时机:Bean实例化时。
  • 说明:Bean被容器创建时,构造函数首先被调用。
@Component
public class MyBean {
    public MyBean() {
        System.out.println("构造方法执行");
    }
}
1.2 @PostConstruct 注解方法
  • 触发时机:Bean依赖注入完成后。
  • 说明:在Bean属性赋值(如@Autowired注入)之后执行。
@Component
public class MyBean {
    @PostConstruct
    public void init() {
        System.out.println("@PostConstruct方法执行");
    }
}
1.3 InitializingBean 的 afterPropertiesSet()
  • 触发时机:与@PostConstruct类似,但由Spring原生接口提供。
  • 说明:在Bean属性设置完成后执行,优先于自定义的init-method
@Component
public class MyBean implements InitializingBean {
    @Override
    public void afterPropertiesSet() {
        System.out.println("InitializingBean的afterPropertiesSet执行");
    }
}
1.4 @Bean(initMethod = "自定义方法")
  • 触发时机:在@PostConstructInitializingBean之后执行。
  • 说明:通过@Bean注解显式指定的初始化方法。
@Configuration
public class AppConfig {
    @Bean(initMethod = "customInit")
    public AnotherBean anotherBean() {
        return new AnotherBean();
    }
}

public class AnotherBean {
    public void customInit() {
        System.out.println("@Bean的initMethod执行");
    }
}

2. 上下文就绪后的扩展点

当所有Bean初始化完成后,应用进入上下文就绪阶段:

2.1 ApplicationContext 事件监听器
  • ContextRefreshedEvent 监听器:当ApplicationContext初始化或刷新完成后触发。
    @Component
    public class MyContextListener {
        @EventListener(ContextRefreshedEvent.class)
        public void onContextRefreshed() {
            System.out.println("ContextRefreshedEvent事件触发");
        }
    }
    
2.2 ApplicationRunner 与 CommandLineRunner
  • 触发时机:在上下文就绪后、应用启动完成前执行。
  • 执行顺序:通过@Order或实现Ordered接口控制多个Runner的顺序。
    @Component
    @Order(1)
    public class MyAppRunner implements ApplicationRunner {
        @Override
        public void run(ApplicationArguments args) {
            System.out.println("ApplicationRunner执行");
        }
    }
    
    @Component
    @Order(2)
    public class MyCmdRunner implements CommandLineRunner {
        @Override
        public void run(String... args) {
            System.out.println("CommandLineRunner执行");
        }
    }
    

3. 完整执行顺序总结

以下是典型场景下各组件的执行顺序:

  1. Bean构造函数 → @PostConstruct → InitializingBean → @Bean(initMethod)
  2. ContextRefreshedEvent 监听器
  3. ApplicationRunner → CommandLineRunner

4. 控制执行顺序的方法

  • @Order 注解:为ApplicationRunnerCommandLineRunner和事件监听器指定优先级,值越小优先级越高。
  • @DependsOn 注解:强制指定Bean的依赖关系,间接影响初始化顺序。
  • 实现Ordered接口:替代@Order注解,动态控制顺序。

5. 示例代码验证

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

输出结果

构造方法执行
@PostConstruct方法执行
InitializingBean的afterPropertiesSet执行
@Bean的initMethod执行
ContextRefreshedEvent事件触发
ApplicationRunner执行
CommandLineRunner执行

通过理解这些执行顺序,您可以更精准地安排初始化逻辑(如数据库连接、缓存预热等),避免因顺序问题导致的依赖错误。

你可能感兴趣的:(JAVA研发,框架解析,java,spring,boot,开发语言)