您的位置:首页 > 编程语言 > Java开发

Spring Boot 启动配置原理和启动事件监听

2019-05-24 19:02 573 查看

 

[code]public static ConfigurableApplicationContext run(Object[] sources, String[] args) {
return new SpringApplication(sources).run(args);
}

1、启动流程:

 1、创建SpringApplication对象(new SpringApplication(sources)

通过构造器调用initialize(sources);方法

[code]public SpringApplication(Object... sources) {
initialize(sources);
}

 initialize(sources):

[code]private void initialize(Object[] sources) {
//保存主配置类
if (sources != null && sources.length > 0) {
this.sources.addAll(Arrays.asList(sources));
}
//判断当前是否一个web应用
this.webEnvironment = deduceWebEnvironment();
//从类路径下找到META-INF/spring.factories配置的所有ApplicationContextInitializer;然后保存起来
setInitializers((Collection) getSpringFactoriesInstances(
ApplicationContextInitializer.class));
//从类路径下找到ETA-INF/spring.factories配置的所有ApplicationListener
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
//从多个配置类中找到有main方法的主配置类
this.mainApplicationClass = deduceMainApplicationClass();
}

①setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class)):

从类路径下的META-INF/spring.factories中拿到配置的所有ApplicationContextInitializer

例子:

 方法执行完成后,拿到的所有的Initializers:

②setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));:

从类路径下META-INF/spring.factories拿到配置的所有ApplicationListener

例子:

  方法执行完成后,拿到的所有的Listener

 

2、运行run方法(.run(args))

run方法:

[code]public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
//声明一个ioc容器
ConfigurableApplicationContext context = null;
FailureAnalyzers analyzers = null;
configureHeadlessProperty();

//获取SpringApplicationRunListeners;从类路径下META-INF/spring.factories
SpringApplicationRunListeners listeners = getRunListeners(args);
//回调所有的SpringApplicationRunListener.starting()方法
listeners.starting();
try {
//封装命令行参数
ApplicationArguments applicationArguments = new DefaultApplicationArguments(
args);
//准备环境
ConfigurableEnvironment environment = prepareEnvironment(listeners,
applicationArguments);
//创建环境完成后回调SpringApplicationRunListener.environmentPrepared();表示环境准备完成

Banner printedBanner = printBanner(environment);

//创建ApplicationContext;决定创建web的ioc还是普通的ioc
context = createApplicationContext();

analyzers = new FailureAnalyzers(context);
//准备上下文环境;将environment保存到ioc中;而且applyInitializers();
//applyInitializers():回调之前保存的所有的ApplicationContextInitializer的initialize方法
//回调所有的SpringApplicationRunListener的contextPrepared();
prepareContext(context, environment, listeners, applicationArguments,
printedBanner);
//prepareContext运行完成以后回调所有的SpringApplicationRunListener的contextLoaded();

//刷新容器,ioc容器初始化(如果是web应用还会创建嵌入式的Tomcat)
//扫描,创建,加载所有组件的地方;(配置类,组件,自动配置)
refreshContext(context);
//从ioc容器中获取所有的ApplicationRunner和CommandLineRunner进行回调
//ApplicationRunner先回调,CommandLineRunner再回调
afterRefresh(context, applicationArguments);
//所有的SpringApplicationRunListener回调finished方法
listeners.finished(context, null);
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass)
.logStarted(getApplicationLog(), stopWatch);
}
//整个SpringBoot应用启动完成以后返回启动的ioc容器;
return context;
}
catch (Throwable ex) {
handleRunFailure(context, listeners, analyzers, ex);
throw new IllegalStateException(ex);
}
}

步骤的解析:

1)、SpringApplicationRunListeners listeners = getRunListeners(args);:

获取SpringApplicationRunListeners,从类路径下META-INF/spring.factories

 

2)、listeners.starting();

回调所有的SpringApplicationRunListener.starting()方法

 

3)、new DefaultApplicationArguments(args);

封装命令行参数

 

4)、prepareEnvironment(listeners,applicationArguments);

创建环境完成后回调SpringApplicationRunListener.environmentPrepared();表示环境准备完成

 

5)、printBanner(environment);

打印spring图标

 

6)、createApplicationContext();

创建ApplicationContext,决定创建web的ioc还是普通的ioc

 

7)、prepareContext(context, environment, listeners, applicationArguments,printedBanner);

准备上下文环境,将environment保存到ioc中,而且调用了applyInitializers();

        ① applyInitializers();

            回调之前保存的所有的ApplicationContextInitializer的initialize()方法

然后回调SpringApplicationRunListener.contextPrepared(context);方法,

运行到最后一步回调SpringApplicationRunListener.contextLoaded(context);方法

 

8)、 refreshContext(context);

刷新容器,ioc容器初始化(如果是web应用还会创建嵌入式的Tomcat)

扫描,创建,加载所有组件的地方(配置类,组件,自动配置)

 

9)、 afterRefresh(context, applicationArguments);

 从ioc容器中获取所有的ApplicationRunner和CommandLineRunner进行回调

ApplicationRunner先回调,CommandLineRunner再回调

 

10)、listeners.finished(context, null);

所有的SpringApplicationRunListener回调finished()方法

 

11)、 return context;

整个spring boot应用启动完成后,返回ioc容器

2、事件监听机制

在spring boot应用启动中有几个重要的事件回调机制

1.配置在META-INF/spring.factories

1)ApplicationContextInitializer

[code]public class HelloApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
System.out.println("HelloApplicationContextInitializer.........initialize" + applicationContext);
}
}

2)SpringApplicationRunListener(必须要有一个(SpringApplication application, String[] args)参数的构造器,否则会出错)

[code]public class HelloSpringApplicationRunListener implements SpringApplicationRunListener {

//必须有的构造器
public HelloSpringApplicationRunListener(SpringApplication application, String[] args){

}

@Override
public void starting() {
System.out.println("HelloSpringApplicationRunListener...starting");
}

@Override
public void environmentPrepared(ConfigurableEnvironment environment) {
System.out.println("HelloSpringApplicationRunListener...environmentPrepared");
}

@Override
public void contextPrepared(ConfigurableApplicationContext context) {
System.out.println("HelloSpringApplicationRunListener...contextPrepared");
}

@Override
public void contextLoaded(ConfigurableApplicationContext context) {
System.out.println("HelloSpringApplicationRunListener...contextLoaded");
}

@Override
public void finished(ConfigurableApplicationContext context, Throwable exception) {
System.out.println("HelloSpringApplicationRunListener...finished");
}
}

在META-INF中的spring.factories中配置

[code]org.springframework.context.ApplicationContextInitializer=\
com.it.springboot.listener.HelloApplicationContextInitializer

org.springframework.boot.SpringApplicationRunListener=\
com.it.springboot.listener.HelloSpringApplicationRunListener

 

2.只需要放在ioc容器中

1)、ApplicationRunner

[code]@Component
public class HelloApplicationRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("HelloApplicationRunner....run");
}
}

2)、CommandLineRunner

[code]@Component
public class HelloCommandLineRunner implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println("HelloCommandLineRunner....run");
}
}

执行结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: