springboot007启动配置原理

编程

几个重要的事件回调机制:

ApplicationContextInitializer

配置在META-INF/spring.factories

SpringApplicationRunListener

配置在META-INF/spring.factories

ApplicationRunner

只需要放在ioc容器中

CommandLineRunner

只需要放在ioc容器中

1. SpringBoot启动流程

  1. 创建SpringApplication对象

public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {

this.resourceLoader = resourceLoader;

Assert.notNull(primarySources, "PrimarySources must not be null");

//保存主配置类

this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));

//判断当前项目是否是一个web应用

this.webApplicationType = WebApplicationType.deduceFromClasspath();

//从类路径下找到META-INF/spring.factories里配置的所有ApplicationContextInitializer,然后保存起来

setInitializers((Collection) getSpringFactoriesInstances(

ApplicationContextInitializer.class));

//从类路径下找到META-INF/spring.factories里配置的所有ApplicationListener,然后保存起来

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

//从多个主配置类中找到包含main方法的主配置类

this.mainApplicationClass = deduceMainApplicationClass();

}

  1. 运行run方法

/**

* Run the Spring application, creating and refreshing a new

* {@link ApplicationContext}.

* @param args the application arguments (usually passed from a Java main method)

* @return a running {@link ApplicationContext}

*/

public ConfigurableApplicationContext run(String... args) {

StopWatch stopWatch = new StopWatch();

stopWatch.start();

ConfigurableApplicationContext context = null;

Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();

configureHeadlessProperty();

//从类路径下找到META-INF/spring.factories里配置的所有SpringApplicationRunListener

SpringApplicationRunListeners listeners = getRunListeners(args);

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

listeners.starting();

try {

//封装命令行参数

ApplicationArguments applicationArguments = new DefaultApplicationArguments(

args);

//准备环境

// 1. 创建环境完成之后回调所有的SpringApplicationRunListener.environmentPrepared()方法,表示环境已经准备好了

ConfigurableEnvironment environment = prepareEnvironment(listeners,

applicationArguments);

configureIgnoreBeanInfo(environment);

Banner printedBanner = printBanner(environment);

//创建ApplicationContext:决定是创建web应用的ioc,还是普通的ioc

context = createApplicationContext();

exceptionReporters = getSpringFactoriesInstances(

SpringBootExceptionReporter.class,

new Class[] { ConfigurableApplicationContext.class }, context);

//准备上下文

// 1. 将environment保存到ioc中;

// 2. applyInitializers():回调之前保存的所有ApplicationContextInitializer的initialize()方法

// 3. listeners.contextPrepared():回调之前保存的所有SpringApplicationRunListener的contextPrepared()方法

// 4. listeners.contextLoaded():contextPrepared运行完成之后,回调所有SpringApplicationRunListener的contextLoaded()方法

prepareContext(context, environment, listeners, applicationArguments,

printedBanner);

//刷新容器,即ioc容器的初始化(如果是web应用,还会初始化嵌入式的tomcat)

//扫描、创建、加载所有组件的地方

refreshContext(context);

afterRefresh(context, applicationArguments);

stopWatch.stop();

if (this.logStartupInfo) {

new StartupInfoLogger(this.mainApplicationClass)

.logStarted(getApplicationLog(), stopWatch);

}

//回调所有的SpringApplicationRunListener.started()方法

listeners.started(context);

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

//所有的ApplicationRunner优先于所有的CommandLineRunner进行回调

callRunners(context, applicationArguments);

}

catch (Throwable ex) {

handleRunFailure(context, ex, exceptionReporters, listeners);

throw new IllegalStateException(ex);

}

try {

listeners.running(context);

}

catch (Throwable ex) {

handleRunFailure(context, ex, exceptionReporters, null);

throw new IllegalStateException(ex);

}

//整个SpringBoot应用启动完成以后,返回ioc容器

return context;

}

SpringBoot启动流程参考

2. 事件监听机制

配置在META-INF/spring.factories

#SpringApplicationRunListener

org.springframework.boot.SpringApplicationRunListener=

com.qiang.springboot.listener.HelloSpringApplicationRunListener

##ApplicationContextInitializer

org.springframework.context.ApplicationContextInitializer=

com.qiang.springboot.listener.HelloApplicationContextInitializer

ApplicationContextInitializer

public class HelloApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {

@Override

public void initialize(ConfigurableApplicationContext configurableApplicationContext) {

System.out.println("ApplicationContextInitializer...initialize..." + configurableApplicationContext);

}

}

SpringApplicationRunListener

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 environment) {

Object osName = environment.getSystemProperties().get("os.name");

System.out.println("SpringApplicationRunListener...environmentPrepared..." + osName);

}

@Override

public void contextPrepared(ConfigurableApplicationContext context) {

System.out.println("SpringApplicationRunListener...contextPrepared...");

}

@Override

public void contextLoaded(ConfigurableApplicationContext context) {

System.out.println("SpringApplicationRunListener...contextLoaded...");

}

@Override

public void started(ConfigurableApplicationContext context) {

System.out.println("SpringApplicationRunListener...started...");

}

@Override

public void running(ConfigurableApplicationContext context) {

System.out.println("SpringApplicationRunListener...running...");

}

@Override

public void failed(ConfigurableApplicationContext context, Throwable exception) {

System.out.println("SpringApplicationRunListener...failed...");

}

}

只需要放在ioc容器中

ApplicationRunner

@Component

public class HelloApplicationRunner implements ApplicationRunner {

@Override

public void run(ApplicationArguments args) throws Exception {

System.out.println("ApplicationRunner...run..." + args);

}

}

CommandLineRunner

@Component

public class HelloCommandLineRunner implements CommandLineRunner {

@Override

public void run(String... args) throws Exception {

System.out.println("CommandLineRunner...run..." + Arrays.asList(args));

}

}

以上是 springboot007启动配置原理 的全部内容, 来源链接: utcz.com/z/510423.html

回到顶部