SpringBoot的启动过程

springboot项目启动时SpringApplication.run干了什么

在这里插入图片描述
在这里插入图片描述
很明显干了 ,两件事:
(1)实例化了一个SpringApplication,参数为当前项目的启动类的class对象
(2)调用了SpringApplication的run方法,参数为main方法上的String[] args
接下来我们具体去看着两件事儿

1.SpringApplication的构造函数干了啥

![在这里插入图片描述](https://img-blog.csdnimg.cn/20200927000104259.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2p5MzE3MzU4MzA2,size_16,color_FFFFFF,t_70#pic_center在这里插入图片描述SpringApplication的构造函数除了指定了一些默认参数主要干了四件事儿:
1)确定当前应用程序的类型
2)初始化Initializers
3)初始化Listeners
4)保存当前程序运行mainApplicationClass 即为当前项目的启动类–TestRunApplication

1.1确定当前应用程序的类型时干了些啥

WebApplicationType为Spring中的一个枚举类,类型有三种
(1)NONE 普通应用程序
(2)SERVLET servlet的Web应用程序
(3)REACTIVE 响应式Reactive的Web应用程序
通过调用WebApplicationType.deduceFromClasspath()去确定应用程序类型
在这里插入图片描述
这个方法就是通过ClassUtils.isPresent()来判断当前应用程序时啥类型的,那么这个方法又干了啥呢
在这里插入图片描述
看名字,我们就清楚了,实际上就是通过反射尝试着去创建对应的类的实例,
那么类型的判断流程就很清楚了
(1)首先进来先看org.springframework.web.reactive.DispatcherHandler能不能实例化,不能实例化则,认为不是REACTIVE,能实例化则继续加载REACTIVE需要的org.springframework.web.servlet.DispatcherServlet和org.glassfish.jersey.servlet.ServletContainer
(2)如果不能实例化,则默认为当前环境为Servlet,然后去尝试实例化javax.servlet.Servlet和org.springframework.web.context.ConfigurableWebApplicationContext,初始化成功则认为是Servlet,不能初始化,则认为是NONE

1.2初始化Initializers又干了啥呢

(1)首先调用了SpringApplication的getSpringFactoriesInstances方法
getSpringFactoriesInstances这个方法干了啥呢?
(1)通过SpringFactoriesLoader.loadSpringFactories()去加载这些配置文件下的类
1)org/springframework/boot/spring-boot/2.3.4.RELEASE/spring-boot-2.3.4.RELEASE.jar!/META-INF/spring.factories
2)org/springframework/boot/spring-boot-autoconfigure/2.3.4.RELEASE/spring-boot-autoconfigure-2.3.4.RELEASE.jar!/META-INF/spring.factories
3)org/springframework/spring-beans/5.2.9.RELEASE/spring-beans-5.2.9.RELEASE.jar!/META-INF/spring.factories
然后将加载到的类信息放入SpringFactoriesLoader的一个cache变量中
默认加载的类包含
“org.springframework.boot.diagnostics.FailureAnalyzer” -> " size = 21"
“org.springframework.boot.env.EnvironmentPostProcessor” -> " size = 4"
“org.springframework.boot.SpringApplicationRunListener” -> " size = 1"
“org.springframework.context.ApplicationContextInitializer” -> " size = 7"
“org.springframework.boot.env.PropertySourceLoader” -> " size = 2"
“org.springframework.context.ApplicationListener” -> " size = 11"
“org.springframework.boot.diagnostics.FailureAnalysisReporter” -> " size = 1"
“org.springframework.boot.SpringBootExceptionReporter” -> " size = 1"
“org.springframework.boot.autoconfigure.AutoConfigurationImportFilter” -> " size = 3"
“org.springframework.boot.autoconfigure.AutoConfigurationImportListener” -> " size = 1"
“org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider” -> " size = 5"
“org.springframework.boot.autoconfigure.EnableAutoConfiguration” -> " size = 127"
“org.springframework.beans.BeanInfoFactory” -> " size = 1"
然后通过createSpringFactoriesInstances这个方法指定参数为ApplicationContextInitializer,然后实例化了springboot的jar包下的spring.factories中的七个类
在这里插入图片描述
在这里插入图片描述
黄色字体部分的被实例化了
然后将实例化的实例进行排序返回,赋值给了SpringApplication的List<ApplicationContextInitializer<?>> initializers

1.3初始化Listeners

同初始化Initializers一样,通过ApplicationListener从SpringFactoriesLoader的缓存变量中取到了11个类信息,然后实例化并发返回,赋值给了SpringApplication的List<ApplicationListener<?>> listeners
在这里插入图片描述
org.springframework.boot.ClearCachesApplicationListener
org.springframework.boot.builder.ParentContextCloserApplicationListener
org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor
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
org.springframework.boot.autoconfigure.BackgroundPreinitializer

2.调用SpringApplication的run方法

在这里插入图片描述
核心是AbstractApplicationContext这个类

 synchronized(this.startupShutdownMonitor) {
 			//  准备刷新上下文
            this.prepareRefresh();
            // 创建Bean工厂
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            // Bean工厂进一步的准备工作,包含设置类加载器,添加Bean处理器等后面需要用的一些东西
            this.prepareBeanFactory(beanFactory);

            try {
            	// 根据应用程序来确定Bean工厂使用的Bean的处理器
                this.postProcessBeanFactory(beanFactory);
                // 实例化Bean定义处理器并加载Bean定义
                this.invokeBeanFactoryPostProcessors(beanFactory);
                // 注册Bean处理器
                this.registerBeanPostProcessors(beanFactory);
                // 加载国际化等文件
                this.initMessageSource();
                // 初始化容器时间广播器
                this.initApplicationEventMulticaster();
                //  启动容器,web程序使用的是ServletWebServerApplicationContext
                this.onRefresh();
                // 注册监听器
                this.registerListeners();
                // 根据Bean定义实例化Bean
                this.finishBeanFactoryInitialization(beanFactory);
                // 解决Bean的循环引用,发布时间
                this.finishRefresh();
            } catch (BeansException var9) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
                }

				// 清除一些Bean实例化过程中使用到的辅助的类
                this.destroyBeans();
                // 设置active标志位
                this.cancelRefresh(var9);
                throw var9;
            } finally {
            	// 清除工具类中的缓存
                this.resetCommonCaches();
            }

        }

```java
/**
 上下文刷新准备
*/
protected void prepareRefresh() {
        this.startupDate = System.currentTimeMillis();
        // 应用上下文是否关闭的标识
        this.closed.set(false);
        // 应用上下文是否活跃的标识
        this.active.set(true);
        // 打印日志
        if (this.logger.isDebugEnabled()) {
            if (this.logger.isTraceEnabled()) {
                this.logger.trace("Refreshing " + this);
            } else {
                this.logger.debug("Refreshing " + this.getDisplayName());
            }
        }

		// 实际啥都没干,实现方法是空的
        this.initPropertySources();
        // 创建标准容器并检验必要属性
        this.getEnvironment().validateRequiredProperties();
        // 添加应用监听器
        if (this.earlyApplicationListeners == null) {
            this.earlyApplicationListeners = new LinkedHashSet(this.applicationListeners);
        } else {
            this.applicationListeners.clear();
            this.applicationListeners.addAll(this.earlyApplicationListeners);
        }
		// 初始化应用时间容器
        this.earlyApplicationEvents = new LinkedHashSet();
    }

/**
创建Bean工厂
*/
protected final void refreshBeanFactory() throws BeansException {
        if (this.hasBeanFactory()) {
            this.destroyBeans();
            this.closeBeanFactory();
        }

        try {
        	// 创建Bean工厂,调用的下面的DefaultListableBeanFactory 这个也是springboot的核心类之一
            DefaultListableBeanFactory beanFactory = this.createBeanFactory();
            beanFactory.setSerializationId(this.getId());
            // 设置是否允许Bean定义的重写和是否允许循环引用
            this.customizeBeanFactory(beanFactory);
            // 加载Bean定义(Bean定义的加载器有四种:1.AbstractXmlApplicationContext 2.AnnotationConfigWebApplicationContext 3.GroovyWebApplicationContext 4.XmlWebApplicationContext)
            // AbstractXmlApplicationContext 加载默认的application.xml文件的
            // AnnotationConfigWebApplicationContext web程序注解加载
            // GroovyWebApplicationContext 支持Groovy语言的 Java用不到
            // XmlWebApplicationContext 专为web程序支持的xml解析器
            this.loadBeanDefinitions(beanFactory);
            this.beanFactory = beanFactory;
        } catch (IOException var2) {
            throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var2);
        }
}

public DefaultListableBeanFactory(@Nullable BeanFactory parentBeanFactory) {
        super(parentBeanFactory);
        // 自动装配断言解析器
        this.autowireCandidateResolver = SimpleAutowireCandidateResolver.INSTANCE;
        // 解析依赖的容器
        this.resolvableDependencies = new ConcurrentHashMap(16);
        // Bean定义的Map
        this.beanDefinitionMap = new ConcurrentHashMap(256);
        // Bean定义的Map
        this.mergedBeanDefinitionHolders = new ConcurrentHashMap(256);
        // Bean的名字的容器
        this.allBeanNamesByType = new ConcurrentHashMap(64);
        // 单例Bean名字的容器
        this.singletonBeanNamesByType = new ConcurrentHashMap(64);
        // Bean定义的名字的容器
        this.beanDefinitionNames = new ArrayList(256);
        this.manualSingletonNames = new LinkedHashSet(16);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值