千家信息网

springboot-007启动配置的原理是什么

发表于:2025-02-04 作者:千家信息网编辑
千家信息网最后更新 2025年02月04日,这篇文章主要介绍"springboot-007启动配置的原理是什么",在日常操作中,相信很多人在springboot-007启动配置的原理是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作
千家信息网最后更新 2025年02月04日springboot-007启动配置的原理是什么

这篇文章主要介绍"springboot-007启动配置的原理是什么",在日常操作中,相信很多人在springboot-007启动配置的原理是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"springboot-007启动配置的原理是什么"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

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



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 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

#SpringApplicationRunListenerorg.springframework.boot.SpringApplicationRunListener=\com.qiang.springboot.listener.HelloSpringApplicationRunListener##ApplicationContextInitializerorg.springframework.context.ApplicationContextInitializer=\com.qiang.springboot.listener.HelloApplicationContextInitializer

ApplicationContextInitializer

public class HelloApplicationContextInitializer implements ApplicationContextInitializer {    @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

@Componentpublic class HelloApplicationRunner implements ApplicationRunner {    @Override    public void run(ApplicationArguments args) throws Exception {        System.out.println("ApplicationRunner...run..." + args);    }}

CommandLineRunner

@Componentpublic class HelloCommandLineRunner implements CommandLineRunner {    @Override    public void run(String... args) throws Exception {        System.out.println("CommandLineRunner...run..." + Arrays.asList(args));    }}

到此,关于"springboot-007启动配置的原理是什么"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

0