springboot的启动源码流程(菜鸟笔记)

springboot的启动源码流程

1.几个重要的事件回调机制

//放在类路劲下的META-INF/spring.factories文件中
ApplicationContextInitializer
ApplicationListener

//先执行ApplicationRunner,再执行CommandLineRunner
ApplicationRunner
CommandLineRunner

2.springboot.run(Main.class)分为两部分

//首先spring容器的创建
//执行容器的run方法
new SpringApplication(primarySources).run(args);

3.spring容器的创建

	
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然后保存起来
    //getSpringFactoriesInstances
    //1.从META-INF/spring.factories文件中找实现了ApplicationContextInitializer接口的所有类
    	//1.1 实现类如下
        org.springframework.context.ApplicationContextInitializer=\
        org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\
        org.springframework.boot.context.ContextIdApplicationContextInitializer,\
        org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\
        org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer
    //2.createSpringFactoriesInstances 获取到的全类名,通过反射创建实例
	//3.保存ApplicationContextInitializer创建的实例
    setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
    
    
    //从类路劲下找到\META-INF\spring.factories配置所有实现了ApplicationListener接口的类
    //getSpringFactoriesInstances
    //1.从META-INF/spring.factories文件中找实现了ApplicationListener接口的所有类
    //1.1 实现类如下:
    	org.springframework.context.ApplicationListener=\
        org.springframework.boot.ClearCachesApplicationListener,\
        org.springframework.boot.builder.ParentContextCloserApplicationListener,\
        org.springframework.boot.context.FileEncodingApplicationListener,\
        org.springframework.boot.context.config.AnsiOutputApplicationListener,\
        org.springframework.boot.context.config.ConfigFileApplicationListener,\
        org.springframework.boot.context.config.DelegatingApplicationListener,\
        org.springframework.boot.context.logging.ClasspathLoggingApplicationListener,\
        org.springframework.boot.context.logging.LoggingApplicationListener,\
        org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener
    //2.createSpringFactoriesInstances 获取到的全类名,通过反射创建实例
	//3.保存ApplicationListener创建的实例
    setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
    //从配置类中找到有main方法的主类
    this.mainApplicationClass = deduceMainApplicationClass();
}

在这里插入图片描述

在这里插入图片描述

4.执行容器的run方法

/**
* Run the Spring application, creating and refreshing a new ApplicationContext
* @param args the application arguments (usually passed from a Java main method)
* @return a running {@link ApplicationContext}
*/
public ConfigurableApplicationContext run(String... args) {
    //用来打印,方法执行的时间,
    //如:Started BootMasterApplication in 56.783 seconds (JVM running for 69.93)
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    //1.申明ioc容器
    ConfigurableApplicationContext context = null;
    Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
    //2.配置环境变量  java.awt.headless='true'
    configureHeadlessProperty();
    
    //3.在\META-INF\spring.factories中找实现类接口SpringApplicationRunListener的所有类,并依次创建类的实例
    SpringApplicationRunListeners listeners = getRunListeners(args);
    //4.回调SpringApplicationRunListener.starting();依次开启所有的监听器
    listeners.starting();
    try {
        //5.包装传入参数  在Idea工具中添加命令行参数,如username=zzhua password=1234
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        
        //6.准备环境变量
        //6.1 获取或者创建环境,配置环境
        //6.2 回调SpringApplicationRunListener.environmentPrepared(environment);表示环境准备完成
        ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
        //6.3 配置ignore 的Bean信息
        configureIgnoreBeanInfo(environment);
        //7.打印Banner
        Banner printedBanner = printBanner(environment);
        //8.创建ApplicationContext,决定创建web容器还是普通的ioc,反射技术
        context = createApplicationContext();
        //9.异常信息处理
        exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
                                                         new Class[] { ConfigurableApplicationContext.class }, context);
        //10.准备上下文环境
        //10.1 将environment保存到ioc容器中
        //10.2 applyInitializers(),回调前面保存的所有的ApplicationContextInitializer实现类的initialize()方法
        //10.3 回调所有的SpringApplicationRunListener.contextPrepared()
        prepareContext(context, environment, listeners, applicationArguments, printedBanner);
        //11. spring容器的刷新 applicationContext).refresh(); 【如果是web应用还会创建嵌入式的Tomcat】。 其他章节已经整理
        refreshContext(context);
        
        //空方法,让子类实现
        afterRefresh(context, applicationArguments);
        //12.监控结束,并打印花费时间日志
        stopWatch.stop();
        if (this.logStartupInfo) {
            new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
        }
        //13.所有的SpringApplicationRunListener回调started()方法,表示容器开启完成
        listeners.started(context);
        //14
        //14.1 在ioc容器中获取所有实现了ApplicationRunner和CommandLineRunner接口的类
        //14.2 先回调所有的ApplicationRunner.run()
        //14.3 再回调所有的CommandLineRunner.run()
        callRunners(context, applicationArguments);
    }catch (Throwable ex) {
        handleRunFailure(context, ex, exceptionReporters, listeners);
        throw new IllegalStateException(ex);
    }

    try {
        //回调SpringApplicationRunListener.running()
        listeners.running(context);
    }catch (Throwable ex) {
        handleRunFailure(context, ex, exceptionReporters, null);
        throw new IllegalStateException(ex);
    }
    //返回创建好的容器
    return context;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot是一个开源的Java框架,用于构建独立的、可执行的、生产级的Spring应用程序。它提供了一个快速、简单的方式来开发和部署应用程序。而在Spring Boot的启动过程中,有以下几个主要的步骤: 1. 加载启动类:Spring Boot应用程序的启动类通常是一个带有`@SpringBootApplication`注解的Java类。在应用程序启动时,会通过`main`方法加载这个启动类。 2. 创建Spring Application对象:Spring Boot会创建一个`SpringApplication`对象,用于启动应用程序。`SpringApplication`是Spring Boot框架的核心类,它负责管理整个应用程序的生命周期。 3. 解析配置信息:在启动过程中,`SpringApplication`会解析`application.properties`或`application.yaml`文件中的配置信息,并将其加载到Spring环境中。这些配置信息可以用来配置应用程序的各个方面,如数据库连接、日志级别等。 4. 创建并配置Spring容器:Spring Boot使用Spring容器来管理应用程序中的各个Bean。在启动过程中,`SpringApplication`会根据配置信息创建并配置一个Spring容器,该容器负责加载和管理应用程序中的所有Bean。 5. 执行自定义逻辑:在Spring Boot的启动过程中,可以添加自定义的逻辑。例如,可以通过实现`CommandLineRunner`接口来在应用程序启动后执行一些初始化操作。 6. 启动应用程序:完成上述步骤后,`SpringApplication`会启动应用程序,并通过Servlet容器(如Tomcat、Jetty等)监听端口,开始接收和处理HTTP请求。 总体而言,Spring Boot的启动流程是一个通过加载启动类、解析配置信息、创建和配置Spring容器的过程。通过Spring Boot的自动配置和快速启动能力,开发者可以更加方便地构建和部署Spring应用程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值