SpringBoot版本:2.1.1.RELEASE
在SpringApplication对象创建和run()方法的运行过程中,我们可以发现有几个重要的事件回调机制,分别是:
- ApplicationContextInitializer
- SpringApplicationRunListener
- ApplicationRunner
- CommandLineRunner
这几个重要的事件回调机制在很多环境下都有应用,例如:
- 启动前的环境检测
- 启动时的配置初始化
- 启动后的数据初始化
下面将会对这四个事件回调机制进行详细的讲解:
-
ApplicationContextInitializer
首先SpringBoot项目启动时,会先创建SpringApplication对象,在创建对象过程中,会将根路径下的META-INF/spring.factories 文件中的 key为org.springframework.context.ApplicationContextInitializer的值加入SpringApplication对象的属性 List<ApplicationContextInitializer<?>> initializers中
SpringApplication对象创建完成,会运行run方法,然后在容器初始化的时候调用applyInitializers(context)方法实例化initializers属性中保存的值。如下图:
2.SpringApplicationRunListener
SpringBoot启动过程中多次被回调,详细可参考:
SpringBoot(2)—启动原理之run方法的运行3.ApplicationRunner、CommandLineRunner
容器启动完成之后回调,其中ApplicationRunner比CommandLineRunner先执行,一般可用于系统数据的初始化
代码示例:
1.代码结构
2.代码工程
package com.van.springbootdemo7.listeners;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
/**
* description:
*
* @author van.shu
* @date 2019/5/28 23:03
*/
public class MyApplicaitonInitilizer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
System.out.println("MyApplicaitonInitilizer...running...");
}
}
package com.van.springbootdemo7.listeners;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
/**
* description:
*
* @author van.shu
* @date 2019/5/28 23:09
*/
@Component
public class MyApplicaitonRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("MyApplicaitonRunner...running...");
}
}
然后将上面两个类的路径加入到资源路径下META-INF/spring.factories配置文件中
org.springframework.context.ApplicationContextInitializer=\
com.van.springbootdemo7.listeners.MyApplicaitonInitilizer
org.springframework.boot.SpringApplicationRunListener=\
com.van.springbootdemo7.listeners.MyApplicationRunLIstener
最后再实现另外两个事件回调接口ApplicaitonRunner和CommandLineRunner:
package com.van.springbootdemo7.listeners;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringApplicationRunListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
/**
* description:
*
* @author van.shu
* @date 2019/5/28 23:06
*/
public class MyApplicationRunLIstener implements SpringApplicationRunListener {
public MyApplicationRunLIstener(SpringApplication application, String[] args) {
}
@Override
public void starting() {
System.out.println("MyApplicationRunLIstener...starting...");
}
@Override
public void environmentPrepared(ConfigurableEnvironment environment) {
}
@Override
public void contextPrepared(ConfigurableApplicationContext context) {
}
@Override
public void contextLoaded(ConfigurableApplicationContext context) {
}
@Override
public void started(ConfigurableApplicationContext context) {
}
@Override
public void running(ConfigurableApplicationContext context) {
}
@Override
public void failed(ConfigurableApplicationContext context, Throwable exception) {
}
}
package com.van.springbootdemo7.listeners;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
/**
* description:
*
* @author van.shu
* @date 2019/5/28 23:10
*/
@Component
public class MyCommandLineRunner implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println("MyCommandLineRunner...running...");
}
}
运行效果如下:
Connected to the target VM, address: '127.0.0.1:10623', transport: 'socket'
MyApplicationRunLIstener...starting...
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.1.RELEASE)
MyApplicaitonInitilizer...running...
......(启动信息省略)
2019-06-05 00:57:37.393 INFO 9992 --- [ main] c.v.s.SpringbootDemoApplication : Started SpringbootDemoApplication in 5.989 seconds (JVM running for 6.406)
MyApplicaitonRunner...running...
MyCommandLineRunner...running...
总结: