springboot自定义组件加载顺序
springboot常用的两种启动方式
启动方式一:
SpringApplication.run(MyApplication.class, args);
启动方式二:
SpringApplication application = new SpringApplication(MyApplication.class);
application.run(args);
实质上两种启动方式是一样的,但是当你需要在springboot启动前或者上下文加载前需要增加一些启动参数等信息,就需要使用方式二来启动springboot,例:
SpringApplication application = new SpringApplication(MyApplication.class);
application.addInitializers(new ConfigContextInitializer());
application.addListeners(MyApplicationListener.applicationPreparedEvent(),MyApplicationListener.applicationEnvironmentPreparedEvent());
application.run(args);
增加启动参数的几种方式
- 在springboot启动时增加-DXXX=xx参数
- 如果是jar包,在启动时候以空格隔开增加参数,mian方法的args会获取到输入的参数
- 读取环境变量的值
服务启动时加载顺序
- SpringApplicationRunListener
- ApplicationListener《ApplicationEnvironmentPreparedEvent》
- ApplicationContextInitializer
- ApplicationListener《ApplicationPreparedEvent》
- @PostConstruct
- InitializingBean接口
- ApplicationListener《ApplicationStartedEvent》
- ApplicationListener《SpringApplicationEvent》
- ApplicationListener《ApplicationReadyEvent》
SpringApplicationRunListener
-
接收不同执行点事件通知的监听者,事件先通知到SpringApplicationRunListener,在传播到ApplicationListener
-
将spring.factories文件中的SpringApplicationRunListener的value读取并放入SpringApplicationRunListeners的集合中
-
使用方法:
- 继承SpringApplicationRunListener接口,并重写其中的方法
- 在spring.factories中配置,例:org.springframework.boot.SpringApplicationRunListener=com.study.springbootplus.config.MyApplicationRunListener
-
接口方法详情
//刚执行run方法时,可用于在初始化最早期时做一些工作 void starting(); //环境建立好时候,ApplicationContext创建之前,该方法被调用 void environmentPrepared(ConfigurableEnvironment environment); //上下文建立完成时,该方法被调用 void contextPrepared(ConfigurableApplicationContext context); //上下文完成加载,但没有被刷新前,该方法被调用 void contextLoaded(ConfigurableApplicationContext context); // 在ApplicationContext刷新并启动后,CommandLineRunners和ApplicationRunner未被调用前,该方法被调用 void started(ConfigurableApplicationContext context); // 在run()方法执行完成前该方法被调用 void running(ConfigurableApplicationContext context); //上下文刷新完成后,run方法执行完之前 void finished(ConfigurableApplicationContext context, Throwable exception);
-
使用场景:在logback-spring.xml中如需读取配置(如kafka的服务ip:端口),可通过starting()或者environmentPrepared()指定
ApplicationListener
- springboot在调用run方法前会加载ApplicationListener的原生的实现类(这些实现类在spring-boot-2.xxx.jar下的spring.factories中),用于spring容器启动后做一些初始化操作
- 支持的事件类型
ApplicationStartedEvent:spring boot 启动监听类
ApplicationEnvironmentPreparedEvent:环境事先准备【spring容器启动前调用】
ApplicationPreparedEvent:上下文context准备时触发
ApplicationReadyEvent:上下文已经准备完毕的时候触发
SpringApplicationEvent:获取SpringApplication
自定义ApplicationEvent,实现ApplicationEvent类
ApplicationFailedEvent:该事件为spring boot启动失败时的操作
- 使用方法实现
1.ApplicationListener<事件类型>接口,重写onApplicationEvent方法,在SpringApplication类中的addListeners方法添加监听 application.addListeners(new MyApplicationListener());
2.通过@EventListener注解添加监听,将该注解用于方法上
ApplicationContextInitializer
- 用于spring容器初始化前调用,使用场景如nacos配置可通过继承该接口完成配置加载。如DelegatingApplicationContextInitializer等,也可以自己实现加载ApplicationContextInitializer的实现类,重写initialize
- 使用方法
1.继承ApplicationContextInitializer接口,重写initialize
2.1.(mian函数中添加):在启动类中,run方法前。application.addInitializers(new MyApplicationContextInitializer());
2.2.(配置文件中配置):key是固定的,value是实现类的类路径,多个以逗号隔开。context.initializer.classes=org.springframework.boot.demo.common.MyApplicationContextInitializer
2.3.(spring.factories中配置):添加META-INF/spring.factories,增加key-value配置。org.springframework.context.ApplicationContextInitializer=org.springframework.boot.demo.common.MyApplicationContextInitializer
(2.1~2.3其中一个均可)
@PostConstruct
定义在方法上,spring容器初始化的时候执行该方法。
链接: link.
InitializingBean
继承InitializingBean接口,实现afterPropertiesSet方法即可