springboot启动源码分析

本文深入剖析SpringBoot的启动过程,从SpringApplication构造函数到ConfigurableApplicationContext的run方法,详细解读每个步骤,包括环境准备、监听器回调、IOC容器创建与刷新,以及关键注解@SpringBootApplication的工作原理。
摘要由CSDN通过智能技术生成

springboot解析

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


一.SpringApplication(Object... sources)  构造函数


1.调用this.initialize(sources);
    private void initialize(Object[] sources) {
        if (sources != null && sources.length > 0) {
            this.sources.addAll(Arrays.asList(sources));
        }
        // 判断当前应用是否为一个WEB应用
        this.webEnvironment = this.deduceWebEnvironment();
         // 从类路径下找到META-INF/spring.factories配置的所有ApplicationContextInitializer,然后保存起来
        this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
        // 从类路径下找到META-INF/spring.factories配置的所有ApplicationListener
        this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
        // 从多个主配置类中找到有main方法的主配置类
        this.mainApplicationClass = this.deduceMainApplicationClass();
    }
2.org.springframework.core.io.support.SpringFactoriesLoader#loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) 根据factoryClass从META-INF/spring.factories加载类
    1).拿到ApplicationContextInitializer 属性
    2).拿到ApplicationListener属性

二. ConfigurableApplicationContext run(String... args)


   1. public ConfigurableApplicationContext run(String... args) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        ConfigurableApplicationContext context = null;        
        this.configureHeadlessProperty();
        // 获取SpringApplicationRunListeners,从类路径下META-INF/spring-factories
        SpringApplicationRunListeners listeners = this.getRunListeners(args);
        // 循环所有的listener,回调starting()方法
        listeners.started();

        try {
          // 封装命令行参数
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);

            context = this.createAndRefreshContext(listeners, applicationArguments);
            this.afterRefresh(context, (ApplicationArguments)applicationArguments);
            listeners.finished(context, (Throwable)null);
            stopWatch.stop();
            if (this.logStartupInfo) {
                (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
            }

            return context;
        } catch (Throwable var6) {
            this.handleRunFailure(context, listeners, var6);
            throw new IllegalStateException(var6);
        }
    }
     2.context = this.createAndRefreshContext(listeners, applicationArguments);
     /*
         * 准备环境:
         * 创建环境完成后回调SpringApplicationRunListener.environmentPrepared()方法,表示
         * 环境准备完成。
         */
        ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
        // 打印控制台的Spring 字符画
        Banner printedBanner = printBanner(environment);
        // 创建IOC容器:ApplicationContext;决定创建web IOC还是普通的IOC容器。
        context = createApplicationContext();
        // 创建错误分析对象
        analyzers = new FailureAnalyzers(context);
        /*
         * 准备上下文环境,将environment保存到IOC容器中; 而且applyInitializers(),
         * 回调之前保存的所有的applicationContextInitializer的initialize()方法;
         * 回调所有的SpringApplicationRunListener的contextPrepareded();最后回调
         * 所有的SpringApplicationRunListener的contextLoaded()方法
         */
        prepareContext(context, environment, listeners, applicationArguments, printedBanner);
        /*
         * 刷新容器:IOC容器的初始化(扫描所有的配置类、@Bean等,加载并创建IOC容器中所有的组件。如果是web应用,
         * 还会创建嵌入式的tomcat),当执行完refreshContext()后,IOC容器即创建完毕
         */
        refreshContext(context);
    
1.拿到SpringApplicationRunListener属性 SpringApplicationRunListeners封装了ApplicationContextInitializer和ApplicationListener
2.每个listeners.started(); 发布事件publishEvent
3. ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
   context = this.createAndRefreshContext(listeners, applicationArguments); 走refresh创建IOC流程

注解分析

1.@SpringBootApplication
    @Configuration
    @EnableAutoConfiguration
    @ComponentScan
2.@EnableAutoConfiguration
    @AutoConfigurationPackage      (@Import({Registrar.class}))
    @Import({EnableAutoConfigurationImportSelector.class})
    1)分析EnableAutoConfigurationImportSelector
        public String[] selectImports(AnnotationMetadata metadata)
        a.从文件中加载所有META-INF/spring.factories文件
        jar:file:/D:/resource/repository/org/springframework/boot/spring-boot/1.3.2.RELEASE/spring-boot-1.3.2.RELEASE.jar!/META-INF/spring.factories
        jar:file:/D:/resource/repository/org/springframework/boot/spring-boot-autoconfigure/1.3.2.RELEASE/spring-boot-autoconfigure-1.3.2.RELEASE.jar!/META-INF/spring.factories
        jar:file:/D:/resource/repository/org/springframework/spring-beans/4.2.4.RELEASE/spring-beans-4.2.4.RELEASE.jar!/META-INF/spring.factories
            封装成Property类 key ,value 进行遍历
        b.拿到key=org.springframework.boot.autoconfigure.EnableAutoConfiguration 属性 总共81个ClassName
    2)分析 @Import({Registrar.class})
        导入ImportBeanDefinitionRegistrar,自定义BeanDefinition注册类,将AutoConfigurationPackages.BasePackages.class注册到IOC中

org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,
org.springframework.boot.context.ContextIdApplicationContextInitializer,
org.springframework.boot.context.config.DelegatingApplicationContextInitializer,
org.springframework.boot.context.web.ServerPortInfoApplicationContextInitializer

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值