1、启动配置原理
1.1 几个重要的事件回调机制
配置在META-INF/spring.factories
ApplicationContextInitializer
SpringApplicationRunListener
只需要放在ioc容器中
ApplicationRunner
CommandLineRunner
在主程序类中打上断点,Debug,进行研究。
1.2 启动流程:
1 2 3 4 5 6 7 8
| public static ConfigurableApplicationContext run(Object source, String... args) { return run(new Object[]{source}, args); }
public static ConfigurableApplicationContext run(Object[] sources, String[] args) { return (new SpringApplication(sources)).run(args); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| private void initialize(Object[] sources) { if (sources != null && sources.length > 0) { this.sources.addAll(Arrays.asList(sources)); } this.webEnvironment = deduceWebEnvironment(); setInitializers((Collection) getSpringFactoriesInstances( ApplicationContextInitializer.class)); setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class)); this.mainApplicationClass = deduceMainApplicationClass(); }
|
找到ApplicationContextInitializer:
找到的Listener:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| public ConfigurableApplicationContext run(String... args) { StopWatch stopWatch = new StopWatch(); stopWatch.start(); ConfigurableApplicationContext context = null; FailureAnalyzers analyzers = null; configureHeadlessProperty(); SpringApplicationRunListeners listeners = getRunListeners(args); listeners.starting(); try { ApplicationArguments applicationArguments = new DefaultApplicationArguments( args); ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments); Banner printedBanner = printBanner(environment); context = createApplicationContext(); analyzers = new FailureAnalyzers(context); prepareContext(context, environment, listeners, applicationArguments, printedBanner); refreshContext(context); afterRefresh(context, applicationArguments); listeners.finished(context, null); stopWatch.stop(); if (this.logStartupInfo) { new StartupInfoLogger(this.mainApplicationClass) .logStarted(getApplicationLog(), stopWatch); } return context; } catch (Throwable ex) { handleRunFailure(context, listeners, analyzers, ex); throw new IllegalStateException(ex); } }
|
2、事件监听机制
来实现一下1.1节中提到的4个组件;
2.1 实现自定义ApplicationContextInitializer
Ctrl+n搜索ApplicationContextInitializer,选择ApplicationContextInitializer,Ctrl+h查看SpringBoot已经实现的所有Initializer:
1 2 3 4 5 6 7 8 9 10
| public class HelloApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override public void initialize(ConfigurableApplicationContext applicationContext) { System.out.println("ApplicationContextInitializer...initialize..."+applicationContext); } }
|
2. 2 实现自定义SpringApplicationRunListener
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| public class HelloSpringApplicationRunListener implements SpringApplicationRunListener {
public HelloSpringApplicationRunListener(SpringApplication application, String[] args){
}
@Override public void starting() { System.out.println("SpringApplicationRunListener...starting..."); }
@Override public void environmentPrepared(ConfigurableEnvironment configurableEnvironment) { Object o = configurableEnvironment.getSystemProperties().get("os.name"); System.out.println("SpringApplicationRunListener...environmentPrepared.."+o); }
@Override public void contextPrepared(ConfigurableApplicationContext configurableApplicationContext) { System.out.println("SpringApplicationRunListener...contextPrepared..."); }
@Override public void contextLoaded(ConfigurableApplicationContext configurableApplicationContext) { System.out.println("SpringApplicationRunListener...contextLoaded..."); }
@Override public void finished(ConfigurableApplicationContext configurableApplicationContext, Throwable throwable) {
System.out.println("SpringApplicationRunListener...finished..."); } }
|
以上两个组件想要起作用,必须配置(META-INF/spring.factories);在我们引入的每个Jar包里,点开其目录结构中都有META-INF文件夹,里面有个spring.factories文件;
我们就要在resources文件夹下创建META-INF/spring.factories,并写入:
1 2 3 4 5 6
| // copy Reference org.springframework.context.ApplicationContextInitializer=\ com.initializr.initializer.HelloApplicationContextInitializer
org.springframework.boot.SpringApplicationRunListener=\ com.initializr.listener.HelloSpringApplicationRunListener
|
2.3 实现自定义ApplicationRunner
1 2 3 4 5 6 7 8
| @Component public class HelloApplicationRunner implements ApplicationRunner { @Override public void run(ApplicationArguments applicationArguments) throws Exception { System.out.println("ApplicationRunner...run...."); } }
|
2.4 实现自定义CommandLineRunner
1 2 3 4 5 6 7 8
| @Component public class HelloCommandLineRunner implements CommandLineRunner { @Override public void run(String... strings) throws Exception { System.out.println("CommandLineRunner...run..."+ Arrays.asList(strings)); } }
|
运行查看控制台有定义输出即可: