spring启动的流程图

spring启动.png

分析三个步骤

创建容器

1.设置reader,scanner,beanFactory

准备容器

一、设置context的environment
二、如果存在开发主动设置的beanNameGenerator,resourceLoader就替换原有的这两个属性
三、设置ContextInitializer

DelegatingApplicationContextInitializer

-1.获取environment的属性context.initializer.classes锁对应的class(ApplicationContextInitializer)数组
-2.同时要保证ApplicationContextInitializer的参数泛型能处理context
-3.实例化ApplicationContextInitializer的数组
-4.依次调用这些ApplicationContextInitializer的initialize方法
-5.目前这个方法只是增加了一个扩展点,用来后期继续添加一些ApplicationContextInitializer
-6.目前spring是直接把这些class信息放置在META-INF/spring.factorie

ContextIdApplicationContextInitializer

-1.获取contextId
-2.注册单例contextId到beanFactory中

ConfigurationWarningsApplicationContextInitializer

-1.添加BeanFactoryPostProcessor---ConfigurationWarningsPostProcessor
-2.ConfigurationWarningsPostProcessor的作用-优先调用postProcessBeanDefinitionRegistry打印一些warn信息,postProcessBeanFactory是空实现,warn信息主要是检测scannedPackages,看看其是否有问题

ServerPortInfoApplicationContextInitializer

-1.添加其自身作为ApplicationListener
-2.ServerPortInfoApplicationContextInitializer的onApplicationEvent用于将内置tomcat的端口号信息设置到一个map中作为上下文

SharedMetadataReaderFactoryContextInitializer

-1.添加BeanFactoryPostProcessor---CachingMetadataReaderFactoryPostProcessor
-2.CachingMetadataReaderFactoryPostProcessor--在beanfactory注册自身RootBeanDefinition,并将其自身作为属性设置到internalConfigurationAnnotationProcessor中

ConditionEvaluationReportLoggingListener

-1.添加ConditionEvaluationReportListener作为ApplicationListener
-2.主要是打印debugg日志

四、注册ApplicationArguments和Banner以及启动类单例
五、调用contextLoaded方法

-1.给ApplicationContextAware属于ApplicationContextAware设置applicationContext
-2.将这些listener都添加到集合 然后统一发布容器准备成功事件,最终就是调用这些listener的onEvent方法

六、SpringApplicationRunListener 目前只有EventPublishingRunListener,专门发布各种listener事件

刷新容器

refreshContext

refresh(context);

-1.prepareRefresh();

propertySources代表存放propertySource的容器
1.设置startupDate
2.设置close为false
3.设置active为true
4.把servletConfig和servletContext替换到spring容器的propertySources容器里面原本的servletConfig和servletContext.如果原来没有就不替换
5.校验必填的属性是否存在,不存在就抛出异常
6.初始化earlyApplicationEvents

-2.obtainFreshBeanFactory();

1.设置beanFactory的refresh为true
2.返回创建高级spring容器时候生成的beanFactory

-3.prepareBeanFactory(beanFactory);

1.设置classloader
2.设置StandardBeanExpressionResolver专门解析spel,即将数据转换成字符串
3.ResourceEditorRegistrar,专门将属性设置的时候把字符串转换成具体的数据类型,比如转化成obejct,数值等等.其在defaultEditors注册了不同数据类型class和具体的编辑器
4.ApplicationContextAwareProcessor,回调xxaware接口
5.ApplicationListenerDetector,检测ApplicationListeners
6.ignoreDependencyInterface,即忽略xxaware接口中属性类型与xxaware接口的setter方法参数相同的属性,即这些属性不会注入,这样这些属性只能由spring自己设置,放置被用户修改(beans 需要设置 default-autowire="byType" 或者bean 设置 autowire="byType" 才能不会注入)
7.registerResolvableDependency,即指定注入的属性的结果是什么

自动注入不是指的@AutoWire 而是指的是beans的default-autowire="byType" 或在bean的autowire="byType" ,这样spring 回去ioc容器寻找类型相似的类型给其注入,如果实现了spring 的xxaware接口,就不会自动注入

-4.postProcessBeanFactory(beanFactory);

1.添加WebApplicationContextServletContextAwareProcessor
2.ignoreDependencyInterface---WebApplicationContextServletContextAwareProcessor
3.如果存在额外添加的basePackages则加入
4.如果存在annotatedClasses,则注册进入beanFactory

-5.invokeBeanFactoryPostProcessors(beanFactory);

1.调用beanFactoryPostProcessor 并实例化所有的bean
2.首先调用我们在之前prepare时候添加的beanFactoryPostProcessor的postProcessBeanDefinitionRegistry(必须改后置处理器是BeanDefinitionRegistryPostProcessor)
3.从beanFactory获取BeanDefinitionRegistryPostProcessor类型的beanDefinition,然后按照PriorityOrdered,Ordered,普通,进行实例化和调用postProcessBeanDefinitionRegistry
4.然后调用上述聚集的beanFactoryPostProcessor的postProcessBeanFactory
5.在从beanFactory按照上述逻辑继续获取BeanFactoryPostProcessor,然后依次调用postProcessBeanFactory

  1. beanFactory.clearMetadataCache(); 删除beanFactoryPostProcessor已经修改了原始的beanDefinition,删除的条件是判断configurationFrozen是否为false,false 可以删除,如果是true的话在判断alreadyCreated是否存在该beanDefinition ,如果存在bean已经实例化了则应该拥有该beanDefinition ,清除allBeanNamesByType(缓存单例和非单例)和singletonBeanNamesByType的缓存

-6.registerBeanPostProcessors(beanFactory);

1.顾名思义注册并实例各种beanpostProcessor,注册的顺序类似beanFactoryPostProcessor

-7.initMessageSource();

1.如果beanfactory是否存在messageSource作为beanName的bean或者beanDefinition
2.如果存在则看看父容器是否存在,若存在且messageSource是HierarchicalMessageSource,则设置当前容器作为父类的messageSource
3.如果上述不存在,则是设置一个DelegatingMessageSource作为当前容器messageSource,设置messaesource的ParentMessageSource

-8.initApplicationEventMulticaster();

1.类似第7项 ,首先判断beanFactory是否存在applicationEventMulticaster的bean,如果存在,则赋值给容器的applicationEventMulticaster属性。
2.如果上述不存在则设置一个默认的SimpleApplicationEventMulticaster作为applicationEventMulticaster
3.applicationEventMulticaster是当有ApplicationListener感兴趣的事件发生的时候,调用ApplicationListener的onEvent方法

-9.onRefresh();

1.对ThemeSource进行初始化,类似messageSource。messageSource是springmvc的一个组件
2.启动内置的tomcat,根据ServletWebServerFactory获取具体的beanName,然后获取该实现类的实例,最终得到serverFactory。这个工厂包含我们tomcat设置的基本属性,比如项目名称和端口号等
3.根据我们的创建内置的tomcat然后把spring容器设置进入内置tomcat

-10.registerListeners();

1.往defaultRetriever的applicationListeners添加applicationListener,同时需要检测该applicationListener是否是Advised,如果是就获取proxy后面真正的target,然后从defaultRetriever,这样避免多次调用
2.因为添加了新的监听者所以clear retrieverCache
3.再从beanfactory获取监听者的beanName 添加到defaultRetriever的applicationListenerBeans中
4.发布需要earlyApplicationEvents

-11.finishBeanFactoryInitialization(beanFactory);

1.这就是spring的ioc容器开始初始化所有的非懒加载的单例bean

-12.finishRefresh();

1.启动tomcat,发布tomcat启动事件

注册钩子

-1.卸载容器
-2.发布卸载事件
-3.lifecycleProcessor的onclose方法
-4.摧毁bean,关闭beanfactory,关闭一些子容器

你可能感兴趣的:(spring启动的流程图)