温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

springboot2.0.6的运行流程以及怎么执行SpringApplication的run方法

发布时间:2021-09-04 11:13:35 来源:亿速云 阅读:251 作者:chen 栏目:大数据

这篇文章主要介绍“springboot2.0.6的运行流程以及怎么执行SpringApplication的run方法”,在日常操作中,相信很多人在springboot2.0.6的运行流程以及怎么执行SpringApplication的run方法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”springboot2.0.6的运行流程以及怎么执行SpringApplication的run方法”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

1. 启动流程图

springboot2.0.6的运行流程以及怎么执行SpringApplication的run方法

2. 启动结构图

springboot2.0.6的运行流程以及怎么执行SpringApplication的run方法

3.运行流程

1. 初始化SpringApplication

  1. 设置resourceload

  2. 设置primarySources,可以把启动类加载进入spring容器

  3. 判断当前application应该运行在什么环境下,即获取webApplicationType(程序应用类型)

  4. 加载所有classpath下面的META-INF/spring.factories中的ApplicationContextInitializer

  5. 加载所有classpath下面的META-INF/spring.factories中的ApplicationListener

  6. mainApplicationClass:找出main方法启动的class

2. 执行SpringApplication的run方法

1. 设置Java.awt.headless系统变量

2. 获取监听器SpringApplicationRunListeners

  1. 加载所有classpath下面的META-INF/spring.factories文件,获取SpringApplicationRunListener的集合,即加载所有spring.factories文件中SpringApplicationRunListener

  2. 依次调用的SpringApplicationRunListener的starting方法,最终调用ApplicationListener的onApplicationEvent方法,发布springboot启动事件

3. 实例化ApplicationArguments对象获取应用参数

4. 创建并设置ConfigurableEnvironment (可配置环境)

    ConfigurableEnvironment:代表两种意义:一种是profiles,用来描述哪些bean definitions是可用的;一种是properties,用来描述系统的配置,其来源可能是配置文件、JVM属性文件、操作系统环境变量等等    

  1. 创建ConfigurableEnvironment,即执行getOrCreateEnvironment()方法,根据webApplicationType创建不同的Environment对象

  2. 配置environment,即执行configureEnvironment(XX)方法。主要把运行方法参数配置到environment

    1. 通过configurePropertySources(environment, args)设置properties

    2. 通过configureProfiles(environment, args)设置profiles

  3. 执行listeners.environmentPrepared(environment)方法,发布environmentPrepared事件,即调用ApplicationListener的onApplicationEvent事件   

  4. 执行bindToSpringApplication方法,即把当前的environment和当前的springApplication绑定

  5. 如果不是web环境,但是是web的environment,则把其转换成标准的environment

  6. 执行ConfigurationPropertySources.attach(environment)方法,将ConfigurationPropertySource放入environment的propertysource中的第一个

5. 打印Banner

6. 创建spring的容器

  1. 根据不同的webApplicationType设置不同的contextClass(容器的class类型),然后生成不同的容器实例对象

  2. 生成容器实例的时候,对于Kotlin类使用'primary'构造函数实例化一个类,如果不是就使用默认构造函数,根据得到构造函数生成实例对象,如果构造函数不是公共的,我们尝试去改变并访问

7. 执行getSpringFactorInstances方法获取具体实现类

8. 准备容器,在准备刷新容器前准备好容器

  1. 执行context.setEnvironment(environment)方法,设置spring容器的environment

  2. 执行postProcessApplicationContext(context)方法,设置beanNameGenerator(其不未空时注入到容器中)和resourceLoader(其不未空时加载对象)

  3. 执行applyInitializers(context),回调所有ApplicationContextInitializer的initialize来初始化context,其中还检测各个ApplicationContextInitializer是否接受该类型的容器

  4. 执行listeners.contextPrepared(context),调用SpringApplicationRunListener的contextPrepared方法,但目前是个空实现。

  5. 依次向容器注册springApplicationArguments和springBootBanner这两个bean

  6. getAllSources就是获取我们的primarySources和sources

  7. 加载所有资源到context里,即调用load(context, sources.toArray(new Object[0]))方法创建BeanDefinitionLoader,设置该loader的sources,annotatedReader,xmlReader,scanner,以及添加scanner的ExcludeFilter(即过滤springboot的启动类),若用户启动的时候设置了beanNameGenerator,resourceLoader,environment的话就替代我们自身设置的属性。同时根据source的类型选择不同的load方法,这边我们是load(class),最终判断是否是component注解,是的话就通过annotatedReader将启动类注册成bean

  8. 执行listeners.contextLoaded(context)方法,判断ApplicationListener是否属于ApplicationContextAware,如果是的话就将spring容器赋值给该listener,然后将该ApplicationListener赋值给spring容器,然后调用ApplicationListener的onApplicationEvent方法

9. 执行refreshContext(context) 刷新spring容器

    1. refresh(context)
  1. 执行prepareRefresh()方法设置些初始的操作。比如 开启激活,启动日期,初始化propertySource。

  2. 获取beanFactory

  3. 执行prepareBeanFactory(beanFactory),设置beanFactory的classloader,BeanExpressionResolver,PropertyEditorRegistrar,    ApplicationContextAwareProcessor和忽略xxxxAware,注册依赖,还有ApplicationListenerDetector

    1. 自动注入不是指的@AutoWire 而是指的是beans的default-autowire="byType" 或在bean的autowire="byType" ,这样spring 会去ioc容器寻找类型相似的类型给其注入,如果实现了spring 的xxaware接口,就不会自动注入记载filterPropertyDescriptorsForDependencyCheck删除与入参类型相同的属性

    2. ApplicationContextAwareProcessor:只是将applicationContext传递给ApplicationContextAwareProcessor,方便后面的xxxAware调用

    3. 忽略xxxxAware:忽略这些Aware接口实现类中与接口set方法中入参类型相同的属性的的自动注入这样就保证了关键的类是由spring容器自己产生的而不是我们注入的

    4. 注册依赖:即指定一些类自动注入的实例是spring指定的实例对象

    5. ApplicationListenerDetector:检测实现了ApplicationListener的实现类,因为有些实现类,无法通过getBeanNamesForType获取到。

  4. 执行postProcessBeanFactory(beanFactory)方法,设置ignoreDependencyInterface(ServletContextAware)还有annotatedClasses,basePackages如果存在就设置。

  5. 执行invokeBeanFactoryPostProcessors(beanFactory)方法,从beanFactoryPostProcessors获取BeanFactoryPostProcessor,然后先执行BeanDefinitionRegistryPostProcessor类型的postProcessBeanDefinitionRegistry,继续从beanFactory获取BeanDefinitionRegistryPostProcessor类型的bean然后执行postProcessBeanDefinitionRegistry,执行的过程按照PriorityOrdered,Ordered,普通的类型进行执行,然后优先执行registryProcessors的postProcessBeanFactory在执行regularPostProcessors的postProcessBeanFactory,再从BeanFactory获取PriorityOrdered,Ordered,普通的类型三种类型的BeanFactoryPostProcessor,并按照顺序执行。总结:从之前加入的beanFactoryPostProcessor先执行postProcessBeanDefinitionRegistry(假如是BeanDefinitionRegistryPostProcessor)然后在执行postProcessBeanFactory方法,然后从beanFactory获取BeanFactoryPostProcessor 然后执行postProcessBeanFactory,执行过程中都要按照PriorityOrdered,Ordered,普通的类型三种类型的顺序执行。

  6. 执行egisterBeanPostProcessors方法,从beanFactory获取BeanPostProcessor分别按照PriorityOrdered,Ordered,普通的类型注册BeanPostProcessor

    1. BeanPostProcessor和BeanFactoryPostProcessor:前者是对bean初始化前后进行设置,后者可以对beanFactory进行修改 或者,可以对beanDefinition进行修改或者增加或者初始化渴望提前初始化的bean

  7. 执行initMessageSource()方法,初始化我们国际化文件

  8. 执行initApplicationEventMulticaster()方法,设置applicationEventMulticaster,spring发布各种事件就依靠他,这个和springboot发布事件使用相同的类

  9. 执行onRefresh()方法,初始化其他的子容器类中的bean,同时创建spring的内置容器(tomcat)

  10. 执行registerListeners()方法,添加用户设置applicationListeners,然后从beanFactory获取ApplicationListener,然后发布需要earlyApplicationEvents事件

  11. 执行inishBeanFactoryInitialization(beanFactory)方法,实例化非懒加载的剩余bean

  12. 执行finishRefresh方法,清理资源缓存,初始化lifecycle,调用lifecycle的onrefresh,发布ContextRefreshedEvent的事件,激活JMX,启动tomcat

  2. context.registerShutdownHook()

        注册一个线程,该线程主要指向doclose方法,doClose方法的逻辑就是:从applicationContexts集合中删除当前容器,MBeanServer卸载MBean,发布容器关闭事件,调用了实现了lifecycleProcessor接口的bean,destroyBeans,closeBeanFactory,onClose:关闭内置tomcat,active设置为false

10. 执行afterRefresh(context, applicationArguments)方法(目前是空的实现)

11. 执行listeners.started(context)方法,发布started事件

12. 执行callRunners(context, applicationArguments)方法

  从spring容器中获取ApplicationRunner和CommandLineRunner对象,然后按照顺序排序,循环调用他们的run方法

13. 执行handleRunFailure(context, ex, exceptionReporters, listeners)方法

     处理不同的异常状态,然后调用listeners.failed(context, exception),并关闭spring容器

14. listeners.running(context)

    发布running事件

4. 自动化配置

    该配置模块的主要使用到了SpringFactoriesLoader,即Spring工厂加载器,该对象提供了loadFactoryNames方法,入参为factoryClass和classLoader,即需要传入上图中的工厂类名称和对应的类加载器,方法会根据指定的classLoader,加载该类加器搜索路径下的指定文件,即spring.factories文件,传入的工厂类为接口,而文件中对应的类则是接口的实现类,或最终作为实现类,所以文件中一般为一对多的类名集合,获取到这些实现类的类名后,loadFactoryNames方法返回类名集合,方法调用方得到这些集合后,再通过反射获取这些类的类对象、构造方法,最终生成实例

到此,关于“springboot2.0.6的运行流程以及怎么执行SpringApplication的run方法”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI