springboot启动详解

springboot 启动步骤
1,获取当前传入的启动所传入的资源类
2,判断当前环境是否是web应用,根据javax.servlet.Servlet, org.springframework.web.context.ConfigurableWebApplicationContext 是否包含在其中
3, 从factory.properties 中获取 ApplicationContextInitializer 为key的接口实例类 并根据传入如的启动参数args 将这些类实例化
4,从factory.properties 中获取 ApplicationListener 为key的接口实例类 并根据传入如的启动参数args 将这些类实例化
5, 使用new RuntimeException().getStackTrace()获取当前启动main方法所在的启动类
6,启动run(args) 方法
7,判断当前应用上下文是否是有父应用上下文 如果有需要初始化 父应用上下文  并将当前应用上下文 父亲设置为 父应用上下文 按照上面的步骤走一趟初始化父应用
8,将当前应用设置为running为true(原子设置)
9,获取当前启动上下文
    1,设置当前系统属性为java.awt.headless  即Headless模式是在缺少显示屏、键盘或者鼠标是的系统配置 可通过三种方法设置 System.setProperty("java.awt.headless","true") java -Djava.awt.headless=true java.awt.GraphicsEnvironment中这个属性的值为true
    2,从factory.properties 中获取 SpringApplicationRunListener 为key的接口实例类 并根据传入如的启动参数args 将这些类实例化
    3,通过 SpringApplicationRunListeners 将获取到的 SpringApplicationRunListener 包装起来  然后可以通过 SpringApplicationRunListeners 的方法对所有的 SpringApplicationRunListener 中接口方法 顺序执行
    4,调用 SpringApplicationRunListeners 的started方法 调用所有的 SpringApplicationRunListener 的 started方法
    5,使用 ApplicationArguments 封装 传入的 args 参数
    6,创建并刷新上下文
        1,判断当前是否为web应用  创建不同的 标准环境 StandardServletEnvironment  或者 StandardEnvironment
        2,根据系统环境和传入参数配置 属性资源 和 profile
        3,调用 SpringApplicationRunListeners 的started方法 调用所有的 SpringApplicationRunListener 的 environmentPrepared 方法
        4,创建 ApplicationContext 的实例  (AnnotationConfigApplicationContext)
        5, 对 ApplicationContext 进行前置处理
        6,获取前面从factory.properties 中得到的 ApplicationContextInitializer 对 ApplicationContext 进行初始化
        7,

        
        
        
        
        
        
        
        
        
        
        
        
org.springframework.boot.context.config.DelegatingApplicationContextInitializer
org.springframework.boot.context.ContextIdApplicationContextInitializer        
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer
    添加新的beanFactoryProcessor  new ConfigurationWarningsPostProcessor({new ComponentScanPackageCheck()})

org.springframework.boot.context.web.ServerPortInfoApplicationContextInitializer
    添加新的ApplicationListener  ServerPortInfoApplicationContextInitializer.this.onApplicationEvent(EmbeddedServletContainerInitializedEvent)
    
org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer
    向ApplicationContext 添加新的 ApplicationListener new AutoConfigurationReportListener()
    向beanFactory 注册 new ConditionEvaluationReport()

org.springframework.boot.builder.ParentContextCloserApplicationListener,
org.springframework.boot.context.FileEncodingApplicationListener,
org.springframework.boot.context.config.AnsiOutputApplicationListener,
org.springframework.boot.context.config.ConfigFileApplicationListener   
    添加 new PropertySourceOrderingPostProcessor(context) 到 ApplicationContext
    继承 EnviromentPostProcessor ApplicationListener
        用于监听事件 ApplicationEnvironmentPreparedEvent ApplicationPreparedEvent 来处理资源环境变量
        其处理逻辑如下:
            ApplicationEnvironmentPreparedEvent :
                第一步 从 META-INF/spring.factories 中加载 EnvironmentPostProcessor 对应的类
                第二步: 将 ConfigFileApplicationListener 和 加载到的 EnvironmentPostProcessor 合并到 List 集合中
                第三不 迭代集合 进行 EnvironmentPostProcessor 的 postProcessEnvironment(enviroment, springapplication) 处理
                    CloudFoundryVcapEnvironmentPostProcessor : 
                        第一步 判断 enviroment 是否包含 VCAP_APPLICATION 或者 VCAP_SERVICES
                        第二步 从 enviroment 抽取 VCAP_APPLICATION 所配置的 JSON 数据 并使用 JsonParser 来解析得到 Map 然后 将其 配置到 Properties 对象中
                        第三不 将 Properties 对象 属性迭代 键加上前缀 vcap.application.  值不变 放入新的 Properties 对象中
                        第四步 从 enviroment 抽取 VCAP_SERVICES 所配置的 JSON 数据 并使用 JsonParser 来解析得到 Map 然后 将其 配置到 Properties 对象中 (service 中的配置 每一个 List对象 含有 都有name 或 label)
                        第五步 将 Properties 对象 属性迭代 键加上前缀 vcap.services.  值不变 放入新的 Properties 对象中
                        第六步 获取 enviroment 中所有的配置属性 MutablePropertySources
                        第七步 判断该属性中是否含有 commandLineArgs 属性
                        第八步 如果存在 则将 上面得到的 Properties 对象作为值 vcap为键 置入 commandLineArgs 属性之后  否则 将 Properties 对象作为值 vcap为键 放到 MutablePropertySources 最前面
                    ConfigFileApplicationListener :
                        第一步 向 enviroment 的属性中添加 systemEnvironment 为键 RandomValuePropertySource("random") 对象为值的 的属性
                        第二步 从 enviroment 的属性中获取 spring.profiles.active 对应的值 String 转为 Set 集合
                        第三步 从 enviroment 中获取 activeprofiles  从上面的集合中 获取非 activeprofiles 的集合
                        第四步 从 enviroment 中获取 defaultprofiles  从上面的集合中 获取非 defaultprofiles 的集合
                        第五步 从 environment 中获取 spring.config.location 的属性值(集合类型) 遍历为 path 如果不为$开头 则前面添加 file: path  
                                如果ConfigFileApplicationListener的 searchLocations 为空则放入默认classpath:/,classpath:/config/,file:./,file:./config/ 路径 
                                否则 放入 searchLocations 的设置路径  作为搜索 配置文件的路径地址
                        第六步 判断获取到的路径是否为文件 
                                    不为文件 而是以/结尾, 需要 从 environment中的spring.config.name 属性中获取 或者 application 的 文件名称
                        
                        第七步 根据上面两步获取到的 文件位置路径 或者 以及 路径 和 文件名 得到的 文件所在地址 加载文件
                                如果文件名称为空, 则表示 为全路径文件  
                                如果文件名不为空,则需要根据加载器 获取所有的 后缀 拼凑文件路径为 路径+文件名称-profile.后缀
                                让资源加载器(一般为DefaultResourceLoader) 根据上述路径 加载资源
                        第八步 DataBind 对象 将属性绑定到 application
                                            
            ApplicationPreparedEvent : 向 applicationContext 添加一个 BeanFactoryProcessor  new PropertySourceOrderingPostProcessor(context)  用于将属性defaultProperties 放到 最后面
                
org.springframework.boot.context.config.DelegatingApplicationListener : 
                            代理ApplicationListener 用于获取 context.listener.classes属性配置中的类 
                            然后将这些类 SimpleApplicationEventMulticaster 中 然后将事件转发到这些ApplicationListener中(只包含 ApplicationEnvironmentPreparedEvent事件以及该事件的后续事件)
org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener : 用于处理数据库重构的监听类
org.springframework.boot.logging.ClasspathLoggingApplicationListener : 打印 应用启动类路径
org.springframework.boot.logging.LoggingApplicationListener : 对日志系统进行前置初始化
org.springframework.boot.autoconfigure.BackgroundPreinitializer


org.springframework.boot.context.event.EventPublishingRunListener


org.springframework.boot.SpringApplicationRunListeners  
    用于包裹 SpringApplicationRunListener  迭代向 SpringApplicationRunListener 发送消息

org.springframework.boot.context.config.ConfigFileApplicationListener
org.springframework.boot.logging.LoggingApplicationListener
org.springframework.boot.logging.ClasspathLoggingApplicationListener
org.springframework.boot.context.config.DelegatingApplicationListener
org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener


两种资源加载器  properties xml  yaml 格式
org.springframework.boot.env.PropertiesPropertySourceLoader  properties/xml
org.springframework.boot.env.YamlPropertySourceLoader yaml/yml


org.springframework.beans.ExtendedBeanInfoFactory


org.springframework.context.annotation.AnnotatedBeanDefinitionReader


ConfigurationClassPostProcessor
ImportAwareBeanPostProcessor
EnhancedConfigurationBeanPostProcessor


org.springframework.context.annotation.internalConfigurationAnnotationProcessor, 
org.springframework.context.annotation.internalAutowiredAnnotationProcessor, 
org.springframework.context.annotation.internalRequiredAnnotationProcessor, 
org.springframework.context.annotation.internalCommonAnnotationProcessor, 
org.springframework.context.event.internalEventListenerProcessor, 
org.springframework.context.event.internalEventListenerFactory, 
mySpringApplication, 
org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor, 
org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor


org.springframework.context.annotation.ConfigurationClassParser
org.springframework.context.annotation.ImportSelector


org.springframework.boot.autoconfigure.EnableAutoConfiguration
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration, 
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration, 
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration, 
org.springframework.boot.autoconfigure.MessageSourceAutoConfiguration, 
org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration, 
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration, 
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration, 
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration, 
org.springframework.boot.autoconfigure.cloud.CloudAutoConfiguration, 
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration, 
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration, 
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration, 
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration, 
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration, 
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration, 
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration, 
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration, 
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration, 
org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration, 
org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration, 
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration, 
org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration, 
org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration, 
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration, 
org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration, 
org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration, 
org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration, 
org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration, 
org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration, 
org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration, 
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration, 
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, 
org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration, 
org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration, 
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration, 
org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration, 
org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration, 
org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration, 
org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration, 
org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration, 
org.springframework.boot.autoconfigure.jms.hornetq.HornetQAutoConfiguration, 
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration, 
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration, 
org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration, 
org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration, 
org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration, 
org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration, 
org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration, 
org.springframework.boot.autoconfigure.mobile.DeviceResolverAutoConfiguration, 
org.springframework.boot.autoconfigure.mobile.DeviceDelegatingViewResolverAutoConfiguration, 
org.springframework.boot.autoconfigure.mobile.SitePreferenceAutoConfiguration, 
org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration, 
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration, 
org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration, 
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration, 
org.springframework.boot.autoconfigure.reactor.ReactorAutoConfiguration, 
org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration, 
org.springframework.boot.autoconfigure.security.SecurityFilterAutoConfiguration, 
org.springframework.boot.autoconfigure.security.FallbackWebSecurityAutoConfiguration, 
org.springframework.boot.autoconfigure.security.oauth2.OAuth2AutoConfiguration, 
org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration, 
org.springframework.boot.autoconfigure.session.SessionAutoConfiguration, 
org.springframework.boot.autoconfigure.social.SocialWebAutoConfiguration, 
org.springframework.boot.autoconfigure.social.FacebookAutoConfiguration, 
org.springframework.boot.autoconfigure.social.LinkedInAutoConfiguration, 
org.springframework.boot.autoconfigure.social.TwitterAutoConfiguration, 
org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration, 
org.springframework.boot.autoconfigure.velocity.VelocityAutoConfiguration, 
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration, 
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration, 
org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration, 
org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration, 
org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration, 
org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration, 
org.springframework.boot.autoconfigure.web.HttpEncodingAutoConfiguration, 
org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration, 
org.springframework.boot.autoconfigure.web.MultipartAutoConfiguration, 
org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration, 
org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration, 
org.springframework.boot.autoconfigure.websocket.WebSocketAutoConfiguration, 
org.springframework.boot.autoconfigure.websocket.WebSocketMessagingAutoConfiguration


springboot 监听器
org.springframework.boot.context.config.ConfigFileApplicationListener
org.springframework.boot.context.config.AnsiOutputApplicationListener
org.springframework.boot.logging.LoggingApplicationListener
org.springframework.boot.logging.ClasspathLoggingApplicationListener
org.springframework.boot.autoconfigure.BackgroundPreinitializer
org.springframework.boot.context.config.DelegatingApplicationListener
org.springframework.boot.builder.ParentContextCloserApplicationListener
org.springframework.boot.context.FileEncodingApplicationListener
org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener

springboot 上下文初始化
org.springframework.boot.context.config.DelegatingApplicationContextInitializer
org.springframework.boot.context.ContextIdApplicationContextInitializer
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer
org.springframework.boot.context.web.ServerPortInfoApplicationContextInitializer
org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer

springboot 后置处理器
org.springframework.context.annotation.ConfigurationClassPostProcessor
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor
org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor
org.springframework.context.event.EventListenerMethodProcessor
org.springframework.context.event.DefaultEventListenerFactory

启动流程
    1,初始化 SpringApplication
        1,设置sources属性 当前只有启动函数所在类
        2,判断当前环境是否为web环境 判断(javax.servlet.Servlet, org.springframework.web.context.ConfigurableWebApplicationContext)这两个类存在于应用中
        3,在应用中获取所有 META-INF/spring.factories 文件中 ApplicationContextInitializer 为key的值 初始化 的实例  并将这些 实例添加到 initializers 属性中
        4,在应用中获取所有 META-INF/spring.factories 文件中 ApplicationListener 为key的值 初始化 的实例 并将这些 实例添加到 listeners 属性中
        5,设置 mainApplicationClass 属性 值为 当前启动函数所在类
        注意:
            ApplicationContextInitializer 
                void initialize(C applicationContext);
                ConfigurableApplicationContext.refresh()之前调用 
                通常用于需要对应用程序上下文进行编程式初始化的Web应用程序中。 
                例如,根据上下文环境注册属性来源或激活配置文件。 请参阅ContextLoader和FrameworkServlet支持分别声明“contextInitializerClasses”上下文参数和init-param。
                我们鼓励ApplicationContextInitializer处理器检测Spring的Ordered接口是否已经实现,或者是否存在@Order注释,并在调用之前进行相应的排序。
            
            ApplicationListener
                void onApplicationEvent(E event);
                用于监听处理应用中不同的事件
                
    2,启用 SpringApplication 的 run 方法 对applicationCotext进行初始化
        1, 在应用中获取所有 META-INF/spring.factories 文件中 SpringApplicationRunListener 为key的值 初始化 的实例 并将这些 实例 用 SpringApplicationRunListeners 包裹
            注意:
                1,SpringApplicationRunListener 只要提供5个方法,用于监听处理 不同 阶段 的ConfigurableApplicationContext
                    void started();
                    void environmentPrepared(ConfigurableEnvironment environment);
                    void contextPrepared(ConfigurableApplicationContext context);
                    void contextLoaded(ConfigurableApplicationContext context);
                    void finished(ConfigurableApplicationContext context, Throwable exception);
                    该接口实例接受连个参数进行实例化  SpringApplication   String[]
                    该实例 根据 Ordered 排序然后 顺序执行
                目前应用只有 org.springframework.boot.context.event.EventPublishingRunListener 类
                EventPublishingRunListener 初始化 会设置三个属性
                    第一个 SpringApplication 
                    第二个 String[] 
                    第三个 SimpleApplicationEventMulticaster 实例 并将 SpringApplication 中 listeners 添加到 SimpleApplicationEventMulticaster 事例中
                    前面两个为构造函数 传入的参数  第三个为 new 的对象
                
        2,通过 SpringApplicationRunListeners 顺序遍历  SpringApplicationRunListener 
        3,SpringApplicationRunListener(EventPublishingRunListener)发出启动事件
            1,new ApplicationStartedEvent(SpringApplication, String[]) 事件
            2,通过 SimpleApplicationEventMulticaster 将事件广播出去
                1, SimpleApplicationEventMulticaster 根据 事件 以及 事件所产生的 ResolvableType(事件类的反射包装类) 获取对应的 ApplicationListener 类
                    具体细节如下:
                        1, 根据事件类的反射包装类,以及事件源 生成一个 监听器缓存 key(根据这个key 缓存对应的 监听器)
                        2,在缓存池里根据上面产生的key获取 监听器
                        3,如果该监听器缓存池内含有该key 那么直接取值返回
                        4,判断当前 beanClassLoader 是否为空。如果不为空 可以直接调用 retrieveApplicationListeners(eventType, sourceType, null) 获取对应的 监听器
                            如果为空则需要 再次判断 键值key 是否存在。不存在 则调用 retrieveApplicationListeners(eventType, sourceType, null) 获取对应的 监听器,
                            并且将获取到的监听器加入到 监听器缓存池中
                        
                            1,获取所有 的监听器 (即 原SpringApplication 中 listeners) 以及 根据 监听器注册到 beanFactory 中的 bean 名称 代表的 监听器
                            2,遍历 SpringApplication 中 listeners 判断该监听器是否支持 该事件
                                1,判断该监听器是否为 GenericApplicationListener 
                                    注意: GenericApplicationListener 提供两个方法
                                        boolean supportsEventType(ResolvableType eventType); //判断该监听器是否支持 该事件类型
                                        boolean supportsSourceType(Class sourceType);    //判断该监听器是否支持 该事件所在源
                                        该两个方法 用于判断 该监听器是否支持事件
                                2,如果该监听器 不是 GenericApplicationListener 的子类 则 使用适配器 GenericApplicationListenerAdapter
                                    注意:
                                        该适配器提供两个方法
                                        boolean supportsEventType(ResolvableType eventType); //判断该监听器支持的事件是否为需要处理事件的父类
                                        boolean supportsSourceType(Class sourceType);    //判断该监听器是否支持 该事件所在源 (一般为true, 如果为SmartApplicationListener则直接调用)
                                        
                                        SmartApplicationListener 是对 ApplicationListener 接口的扩展 暴露接口用于判断 该监听器是否能处理 某个事件
                                        
                                        该适配器 用于 判断 该监听器 的泛型参数是否为 该事件
                            3,如果该监听器支持处理该事件 则将该监听器添加到当前 key所能代表的 监听器集合中
                            4, 判断 监听器 名称属性中的监听器是否能处理事件 如果能 ,则从当前上下文所在的 beanfactory 中获取实例 重复 上面 的支路进行判断添加
                            5,排序监听器(按Order的顺序排序), 然后返回所有的 监听器
                    2,遍历获取到 ApplicationListener 类,调用监听器的 onApplicationEvent(ApplicationEvent) 对事件进行处理
                        具体详情见 springboot 监听器
                            
        4,new 一个应用参数对象 实现对传入参数的包裹
        5,调用 createAndRefreshContext(SpringApplicationRunListeners, ApplicationArguments) 初始化并刷新一个应用上下文 即 ConfigurableApplicationContext 的子类 AnnotationConfigEmbeddedWebApplicationContext
            具体细节:
                1, 创建当前 配置环境
                    1,判断当前配置环境是否存在,如果存在则立即返回
                    2,判断当前环境是否为web环境 
                    3,web环境则返回 new StandardServletEnvironment() 不是则返回 new StandardEnvironment()
                2,根据 ApplicationArguments 配置 当前环境属性
                    1,配置属性
                        1,如果当前 SpringApplication 含有默认属性  则将当前默认属性 以 defaultProperties 为键 添加到 当前环境
                        2,如果当前 ApplicationArguments 不为空 则以 commandLineArgs 为键值 添加到当前环境中
                    2,配置profile
                        1,对当前环境中profile进行初始化 environment.getActiveProfiles();
                        2,将 SpringApplication 中的 profile(即属性 additionalProfiles) 以及 当前环境中 profile 合并
                        3,将上述 profile 集合 添加到当前 有效 profile 中
                3,通过 SpringApplicationRunListeners 发出当前 应用中 环境变量已经准备好的事件
                    1,遍历 SpringApplicationRunListener 集合。 也就是只有一个 org.springframework.boot.context.event.EventPublishingRunListener 发出事件
                        1, new ApplicationEnvironmentPreparedEvent(this.application, this.args, environment) 事件。
                        2,通过 org.springframework.context.event.SimpleApplicationEventMulticaster 对事件进行 广播 即对上面的 程序流程进行再次 复现
                4,创建 ConfigurableApplicationContext
                    1, 判断当前 SpringApplication 中 applicationContextClass 属性是否为空 不为空则直接实例返回
                    2, 判断 当前是否为web环境 返回对应的 applicationContext
                        注意:
                            如果为web环境  返回 org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext 实例
                            如果不是web环境 返回 org.springframework.context.annotation.AnnotationConfigApplicationContext 实例
                            当前环境 返回 web环境 实例 即 AnnotationConfigEmbeddedWebApplicationContext
                    3,实例化 AnnotationConfigEmbeddedWebApplicationContext
                        1,构造函数初始化 reader 属性 new AnnotatedBeanDefinitionReader(this) 用于对读取到的 bean进行后置处理
                            具体细节:
                                1, 初始化一个bean命名器 属性 new AnnotationBeanNameGenerator()
                                    AnnotationBeanNameGenerator: 
                                        用于给相应的beanDefinition 取名字。 
                                        如果该bean 被 Component ManagedBean Named 注解 存在 且其属性 value存在有值 那么 则取出该值 作为 该 bean在容器中的名字
                                        如果没有 则利用 Introspector.decapitalize(shortClassName) 取到类名 并做驼峰化 FooBar 变为 fooBar
                                2, 初始化一个Scope解析器 属性。new AnnotationScopeMetadataResolver()
                                    AnnotationScopeMetadataResolver:
                                        用于给相应BeanDefinition设置scope
                                        如果该bean 被Scope注解且有值 则设置为该scope值
                                        如果没有,则设置默认的 ScopeMetadata  其scope为single
                                3,设置AnnotatedBeanDefinitionReader 的属性 registry 为 AnnotationConfigEmbeddedWebApplicationContext
                                4,设置属性 conditionEvaluator 为 new ConditionEvaluator(BeanDefinitionRegistry, Environment, null)
                                    ConditionEvaluator:
                                        用于评估BeanDefinition 中的 AnnotatedTypeMetadata 是否包含 Conditional 注解
                                        如果没有该注解 返回false
                                        如果有该注解
                                            则判断 该注解中的类bean是否已经添加到容器,如果没有则跳过该beanDefiniton 如果有则不忽略
                                5,对 beanFactory 进行配置
                                    1,判断 beanFactory 的 依赖比较器是否为 AnnotationAwareOrderComparator
                                        如果 不是则设置为 AnnotationAwareOrderComparator: 用于 @Order and @Priority 两个注解 对依赖项进行排序
                                    2,判断 beanFactory 的 自动装配解析器 是否为 ContextAnnotationAutowireCandidateResolver (原来是SimpleAutowireCandidateResolver 用于检测bean是否可以作为其他类的装配组件)
                                        如果不是则设置为 ContextAnnotationAutowireCandidateResolver
                                        
                                    3,判断容器中是否已有 org.springframework.context.annotation.internalConfigurationAnnotationProcessor bean名称
                                        如果没有 则初始化一个 new RootBeanDefinition(ConfigurationClassPostProcessor.class)
                                        并且 将 该 RootBeanDefinition 注册到 registry 
                                        名称为 org.springframework.context.annotation.internalConfigurationAnnotationProcessor 
                                        角色为 BeanDefinition.ROLE_INFRASTRUCTURE (基础设施) 
                                    4,判断容器中是否已有 org.springframework.context.annotation.internalAutowiredAnnotationProcessor bean名称
                                        如果没有 则初始化一个  new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class)
                                        并且 将 该 RootBeanDefinition 注册到 registry 
                                        名称为 org.springframework.context.annotation.internalAutowiredAnnotationProcessor
                                        角色为 BeanDefinition.ROLE_INFRASTRUCTURE (基础设施) 
                                    5,判断容器中是否已有 org.springframework.context.annotation.internalRequiredAnnotationProcessor bean名称
                                        如果没有 则初始化一个  new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class)
                                        并且 将 该 RootBeanDefinition 注册到 registry 
                                        名称为 org.springframework.context.annotation.internalRequiredAnnotationProcessor
                                        角色为 BeanDefinition.ROLE_INFRASTRUCTURE (基础设施) 
                                    6,判断当前应用是否支持 javax.annotation.Resource 注解,并且 判断容器中是否已有 org.springframework.context.annotation.internalCommonAnnotationProcessor bean名称
                                        如果支持 javax.annotation.Resource 注解 且没有 internalCommonAnnotationProcessor bean名称
                                        则初始化一个  new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class)
                                        并且 将 该 RootBeanDefinition 注册到 registry 
                                        名称为 org.springframework.context.annotation.internalCommonAnnotationProcessor
                                        角色为 BeanDefinition.ROLE_INFRASTRUCTURE (基础设施) 
                                    7,判断当前应用是否支持 javax.persistence.EntityManagerFactory 注解 且有 org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor 类
                                       判断容器中是否已有 org.springframework.context.annotation.internalPersistenceAnnotationProcessor bean名称
                                        如果没有 则初始化一个  new RootBeanDefinition(PersistenceAnnotationBeanPostProcessor.class)
                                        并且 将 该 RootBeanDefinition 注册到 registry 
                                        名称为 org.springframework.context.annotation.internalPersistenceAnnotationProcessor
                                        角色为 BeanDefinition.ROLE_INFRASTRUCTURE (基础设施) 
                                    8,判断容器中是否已有 org.springframework.context.event.internalEventListenerProcessor bean名称
                                        如果没有 则初始化一个  new RootBeanDefinition(EventListenerMethodProcessor.class)
                                        并且 将 该 RootBeanDefinition 注册到 registry 
                                        名称为 org.springframework.context.event.internalEventListenerProcessor
                                        角色为 BeanDefinition.ROLE_INFRASTRUCTURE (基础设施) 
                                    8,判断容器中是否已有 org.springframework.context.event.internalEventListenerFactory bean名称
                                        如果没有 则初始化一个  new RootBeanDefinition(DefaultEventListenerFactory.class)
                                        并且 将 该 RootBeanDefinition 注册到 registry 
                                        名称为 org.springframework.context.event.internalEventListenerFactory
                                        角色为 BeanDefinition.ROLE_INFRASTRUCTURE (基础设施) 
                                需要了解这beanPost处理器查看beanPost
                                    
                        2,构造函数初始化 scanner 属性 new ClassPathBeanDefinitionScanner(this) 用于扫描应用中的资源文件  并加载 beanDefinition
                            具体细节:
                                1,初始化 resourcePatternResolver 属性为  new PathMatchingResourcePatternResolver()
                                    用于对资源路径进行匹配
                                    如果 资源路径以 classpath*: 开头
                                        匹配该路径 或者 该文件夹 下的 路径 Resource
                                    如果不是以 这个开头 
                                        匹配文件 获取Resource
                                        如果不匹配文件 则使用 ResourceLoader 去解析这个路径 加载资源
                                2,初始化属性  metadataReaderFactory    为 CachingMetadataReaderFactory(resourcePatternResolver) 
                                    用于加载资原的 元数据
                                3,注册过滤器
                                    1,向 includeFilters 属性注册 new AnnotationTypeFilter(Component.class) 过滤器
                                    2,向 includeFilters 属性注册  new AnnotationTypeFilter(javax.annotation.ManagedBean.class)  过滤器
                                    3,向 includeFilters 属性注册  new AnnotationTypeFilter(javax.inject.Named.class)  过滤器
                                4,设置 environment 属性
                                5, 初始化 beanDefinitionDefaults 属性为 new BeanDefinitionDefaults() 用于配置 beanDefiniton 的一些默认配置属性 比如 lazy 属性
                                6, 初始化一个bean命名器 new AnnotationBeanNameGenerator()
                                    AnnotationBeanNameGenerator: 
                                        用于给相应的beanDefinition 取名字。 
                                        如果该bean 被 Component ManagedBean Named 注解 存在 且其属性 value存在有值 那么 则取出该值 作为 该 bean在容器中的名字
                                        如果没有 则利用 Introspector.decapitalize(shortClassName) 取到类名 并做驼峰化 FooBar 变为 fooBar
                                7, 初始化一个Scope解析器。new AnnotationScopeMetadataResolver()
                                    AnnotationScopeMetadataResolver:
                                        用于给相应BeanDefinition设置scope
                                        如果该bean 被Scope注解且有值 则设置为该scope值
                                        如果没有,则设置默认的 ScopeMetadata  其scope为single
                                8,设置当前容器注册器为 AnnotationConfigEmbeddedWebApplicationContext
                                9,设置当前资源加载器为 AnnotationConfigEmbeddedWebApplicationContext
                                    即配置 resourcePatternResolver 属性为 ResourcePatternUtils.getResourcePatternResolver(resourceLoader) AnnotationConfigEmbeddedWebApplicationContext
                                    即配置 metadataReaderFactory    属性为 new CachingMetadataReaderFactory(resourceLoader)
                                    
                6,设置 AnnotationConfigEmbeddedWebApplicationContext 的环境变量为 StandardServletEnvironment
                7,对 AnnotationConfigEmbeddedWebApplicationContext 进行一些配置
                    具体细节如下:
                        1,判断当前环境 是否为 web 环境
                            1,判断当前 AnnotationConfigEmbeddedWebApplicationContext 是否为 ConfigurableWebApplicationContext
                                1,如果 SpringApplication 的属性为 beanNameGenerator 不为空 则向容器注册 该bean 且命名为 org.springframework.context.annotation.internalConfigurationBeanNameGenerator
                            2,判断当前 SpringApplication 的 resourceLoader 是否为空
                                如果不为空则设置当前 AnnotationConfigEmbeddedWebApplicationContext 的资源加载器 为 resourceLoader
                8,对 AnnotationConfigEmbeddedWebApplicationContext 进行刷新之前的 初始化操作 即使用 ApplicationContextInitializers  进行初始化
                    具体细节查看 springboot上下文初始化
                    
                9, 通过 SpringApplicationRunListeners 顺序遍历  SpringApplicationRunListener(即只有 EventPublishingRunListener) 
                    EventPublishingRunListener 向 当前注册器注册一个 单例广播器 applicationEventMulticaster (org.springframework.context.event.SimpleApplicationEventMulticaster) 用于向监听器发送事件
                    并且向 applicationEventMulticaster 中设置 beanFactory 为当前容器
                    
                10,向当前容器注册一个 名称为 springApplicationArguments(DefaultApplicationArguments) 的单例
                11,加载资源 (含有 bean的定义资源文件 通过传入 sources 来加载)
                    具体细节:
                        1,创建一个 BeanDefinitionLoader 用于加载 BeanDefinition 
                            细节:
                                1,设置 BeanDefinitionLoader 属性 sources 为启动函数所在类  即SpringApplication 的 sources
                                2,设置 annotatedReader 属性 new AnnotatedBeanDefinitionReader(registry) 用于读取 BeanDefinition  跟上面那个差不多的流程
                                3,设置 xmlReader 属性 new XmlBeanDefinitionReader(registry) 用于读取 xml 格式的资源文件 以获取 BeanDefinition
                                4,判断 当前应用是否支持 groovy.lang.MetaClass 如果有 则需要 设置 groovyReader 属性 为 new GroovyBeanDefinitionReader(registry) 用于读取 groovy 格式的 资源文件
                                5,配置scanner 属性 为 new ClassPathBeanDefinitionScanner(registry) 用于扫描资源文件 加载 eanDefinition
                                6,将当前 sources 中的 资源加入 ClassPathBeanDefinitionScanner 的屏蔽资源中
                        2,设置 BeanDefinitionLoader 的属性 beanNameGenerator resourceLoader environment
                        3,调用 BeanDefinitionLoader 的 load() 方法 进行资源加载 注册 BeanDefinition
                            细节:
                                1,遍历 BeanDefinitionLoader 的资源属性 sources
                                2,判断每个source的类型 以便加载 资源
                                    细节:
                                        如果class类型的资源
                                            1,判断是否支持 groovy.lang.MetaClass 如果支持 需要调用 GroovyBeanDefinitionSource 获取bean 注册到容器
                                            2,判断该 class 是否被 Component 注解 如果是 则将该bean 注册到容器
                                        如果为 Resource 类型资源
                                            1,判断资源文件是否以 .groovy 结尾 并且 groovyReader 属性不为空, 则调用该 读取器 加载bean 注册到容器
                                            2,如果不是则调用 xmlReader 解析文件 (文件一般为xml格式 使用java的DDOM解析器) 注册 beanDefiniton 到容器
                                        如果为 Package 类型资源
                                            1,直接调用 ClassPathBeanDefinitionScanner 进行 包扫描注册
                                        如果为 CharSequence 类型资源
                                            1,调用xmlReader属性的环境变量中的通配符解析器进行资源解析  
                                            2,如果该资源类型 为Class 类名称资源 则使用 class类型资源加载
                                            3,如果该字符串为资源地址 则调用 Resource 类型进行加载
                                            4,乳沟该字符串为Package 则调用 ClassPathBeanDefinitionScanner 进行扫描处理
                                            
                12,通过 SpringApplicationRunListeners 顺序遍历  SpringApplicationRunListener(即只有 EventPublishingRunListener)     发出资源bean 已加载的事件
                    细节:
                        1,遍历 SpringApplication 中listeners 获取监听器
                        2,判断 监听器是否 继承 自 ApplicationContextAware 如果继承 则 设置好 监听器内部 的 applicationContext 属性
                        3,并且 在 applicationContext 添加 当前遍历的 监听器
                        4,通过 multicaster (SimpleApplicationEventMulticaster)广播向所有监听器遍历 发送 new ApplicationPreparedEvent(SpringApplication, this.args, applicationContext) 事件
                            详情可见 springboot 监听器
                13,对上下文进行刷新
                    细节:
                        1,调用  ApplicationContext(org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext) 刷新  即 AbstractApplicationContext 中的刷新函数 该刷新是单例的
                        2,进行刷新 前的准备工作
                            1,清理 scanner (ClassPathBeanDefinitionScanner) 的缓存 (即Resource对应的 CachingMetadataReaderFactory)
                            2,初始化 当前 环境变量(ConfigurableWebEnvironment) 中的 属性 
                                细节:
                                    根据上面的propertySources设置 ServletContext 一些初始化属性
                                    即 servletContextInitParams  servletConfigInitParams
                            3,验证环境变量中的属性 是否含有 必须的属性
                            4,初始化 earlyApplicationEvents 属性 以便收集所有的 ApplicationEvents 然后通过 multicaster 发布出去 让监听器处理
                        3,获取用于刷新的 容器 (需要设置该容器的序列化ID) 即  DefaultListableBeanFactory
                        4,对 容器 DefaultListableBeanFactory 做一些前期准备工作 如下所示
                            细节:
                                1,设置当前容器的 ClassLoader 用于加载 Class
                                2,设置当前容器的 表达式解析器 new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())
                                    细节:
                                        初始化 expressionParser 属性为 new SpelExpressionParser(new SpelParserConfiguration(null, beanClassLoader) 根据特定的 spel配置器 设置相应的解析器
                                3,设置当前容器的 属性编辑器 new ResourceEditorRegistrar(this, getEnvironment()) 用于 属性的 类型转换  profile 文件设置
                                4,在当前容器添加 new ApplicationContextAwareProcessor(this) 的 后置处理器 用于处理当 bean 继承 某个 Aware 的子类 就将某个 Aware 设置到该bean的内置属性中
                                5,忽略接口 ResourceLoaderAware ApplicationEventPublisherAware MessageSourceAware ApplicationContextAware EnvironmentAware 处理 因为 上面的 ApplicationContextAwareProcessor 已经处理完这些类的工作
                                6,对容器注册 相应的 自动装配 依赖项 类名-实例 形式注册  如 BeanFactory.class-beanFactory  ResourceLoader-AbstractApplicationContext(this) ApplicationEventPublisher-AbstractApplicationContext(this) ApplicationContext-AbstractApplicationContext(this)
                                7,判断容器中 是否有 loadTimeWeaver 的bean 名称 
                                    如果有 
                                    则 添加 new LoadTimeWeaverAwareProcessor(beanFactory) 后置处理器 用于处理 bean 
                                    并且设置一个临时 类加载器 用于加载
                                8,判断 当前容器 是否含有 environment 的bean名称 没有 则将当前的 environment(StandardServletEnvironment) 注册为单例到容器中
                                9,判断 当前容器 是否含有 systemProperties 的bean名称 没有 则将当前的 systemProperties(即系统属性 Map集合) 注册为单例到容器中
                                10,判断 当前容器 是否含有 systemEnvironment 的bean名称 没有 则将当前的 systemEnvironment(即系统环境变量 Map集合 System.getEnv()) 注册为单例到容器中
                        5, 对容器 进行 后期处理
                            细节:
                                1,往容器内添加 Bean 处理器 new WebApplicationContextServletContextAwareProcessor(this)  用于设置 某个bean 继承 ServletContextAware  ServletConfigAware 中的 ServletContext ServletConfig 属性
                                2,配置容器 忽略接口 ServletContextAware; 因为上面的后置处理器 以及 处理完该接口的工作
                                3,如果该上下文 中的 basePackages 不为空 则利用 ClassPathBeanDefinitionScanner 对这些包进行扫描 进行资源加载 注册
                                4,如果该上下文中的 annotatedClasses 不为空 则利用 AnnotatedBeanDefinitionReader 注册这些类
                        6,执行注册到容器的 BeanFactoryPostProcessor 处理器
                            细节:
                                1,获取到所有的 BeanFactoryPostProcessor 处理器
                                2,将处理器 分成两类 集合   registryPostProcessors , regularPostProcessors
                                    细节:
                                        处理分为 两类 分别是  BeanDefinitionRegistryPostProcessor 处理器  和 规则 处理器
                                        将这两类加入不同的 处理器器集合  在容器中 先执行 BeanDefinitionRegistryPostProcessor 处理器  再 执行 规则处理器
                                        首先要处理 内部添加的 BeanDefinitionRegistry 处理器的 postProcessBeanDefinitionRegistry(registry) 方法
                                        用于用于修改容器 该阶段为 处于BeanDefinitionRegistry 中所有的bean 已加载 单还没有 实例化  在这个阶段 可以允许 注册 更多的 bean 到容器
                                3,从注册表 获取 所有 类型为 BeanDefinitionRegistryPostProcessor 的 bean 实例 
                                4,判断这些 BeanDefinitionRegistryPostProcessor 哪些是 继承自 PriorityOrdered 的类
                                5,如果是 将这些 类名称 以及 实例  添加到 priorityOrderedPostProcessors 集合 和 processedBeans
                                6,对 priorityOrderedPostProcessors 进行排序
                                7,将 priorityOrderedPostProcessors 添加到 registryPostProcessors 集合
                                8, 执行这些 优先级 的 BeanDefinitionRegistryPostProcessor 处理器 的 postProcessBeanDefinitionRegistry(registry)
                                    细节:
                                        用于修改 含有 注册 器的上下文, 以及 添加 更多的 bean
                                        比如 ConfigurationClassPostProcessor 可以用于 解析当前应用的 配置注解 用于加载更多的 bean
                                            ConfigurationClassPostProcessor 处理细节:
                                                1,向容器注册   两个个处理器 
                                                    ImportAwareBeanPostProcessor(org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor) 
                                                    EnhancedConfigurationBeanPostProcessor(org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor)
                                                2,向registriesPostProcessed 属性 添加当前 容器的 id 防止重复 使用
                                                3,获取容器中所有已注册 的 bean 名称
                                                4,顺序遍历 根据名称获取 BeanDefinition
                                                5,判断 该 BeanDefinition 是否已被完全配置或轻量配置处理
                                                6,如果没有 则判断该 BeanDefinition 是否被 Configuration,Component,ComponentScan,Import,ImportResource 注解  
                                                7,如果有被 Configuration 注解 则 设置 BeanDefinition 为完全配置 或者被余下的 注解 注解 则设置为 轻量配置
                                                8,将这些需要进行配置 解析的 的 BeanDefinition 放入 配置候选集合中
                                                9,对集合中的 bean 进行 Order 注解排序
                                                10,初始化一个 new ConfigurationClassParser(this.metadataReaderFactory, this.problemReporter, this.environment,this.resourceLoader, this.componentScanBeanNameGenerator, registry) 配置类解析器
                                                    ConfigurationClassParser 用于解析 被 Configuration  注解定义的类。 
                                                    填充 配置类对象 (解析单个配置类可能会由于Import注解造成一个类拥有无数个配置类对象)
                                                    ConfigurationClassParser 可以帮助我们从 注册 BeanDefinition 中分离出来(除了@ComponentScan注解的类需要被立即处理注册)。
                                                    该类使用 ASM 来帮助我们避免反射和类加载 以便配合 ApplicationContext 的懒加载
                                                11,使用 ConfigurationClassParser 对这些候选类进行解析
                                                    解析细节:
                                                        1,初始化 deferredImportSelectors 属性
                                                        2,遍历 这些候选类
                                                        3,判断这些候选类的 bean定义 执行不同的 解析方案
                                                            如果为 AnnotatedBeanDefinition,
                                                            如果为 AbstractBeanDefinition
                                                            或者为 class
                                                            使用 ConfigurationClass 包裹这些定义
                                                        4,使用条件评估器对 ConfigurationClass 包裹 进行评估 判断是否需要跳过 
                                                            判断该类上是否有 Conditional 条件注解, 没有跳过
                                                            判断 该 Conditional 注解中的 value 是否有类
                                                            通过该类实例化获取该类的配置阶段
                                                            最后判断该类所处的阶段 一致表示 可以解析 否则略过
                                                        5,对该类进行迭代循环处理 获取含有注解的 类 并包裹成 SourceClass
                                                        6,进行 Configuration 处理
                                                            1,判断该 类中的 成员类 是否有被 配置注解的注解类 注解的 如果有 则将该 类压入 importStack 进行 循环解析 然后再从 importStack 弹出
                                                            2,判断该类上 是否有 PropertySource 注解 如果有 进行 属性文件解析 (需要根据不同的文件名 解析不同的文件 解析后的属性 放入应用的属性中)
                                                            3,判断该类上是否有 ComponentScan 注解 如果有 调用 ComponentScanAnnotationParser 进行解析 扫描 如果扫出来注册到容器  
                                                                对扫描出来的 类进行 配置检测 如果有配置类型的注解  则需要对该类进行解析
                                                            4,判断该类上是否有 @Import 注解,如果有 需要对该类上的 Import 进行处理
                                                                迭代循环 获取 该类上的注解上是否有  @Import 如果有 则将Import注解中的类加入集合 并将该 注解类 放入已访问集合中避免再次访问
                                                                循环处理 上面Import导入的类 
                                                                如果该类 是 ImportSelector 的子类 
                                                                    判断该类是否为 DeferredImportSelector 
                                                                    如果是 则放入 deferredImportSelectors 属性中
                                                                    如果不是 则执行该类的 的 selectImports 方法 获取 类 迭代进行 @Import 处理
                                                                如果该类是 ImportBeanDefinitionRegistrar 的子类  则将该类实例化 并且 将其添加到 档期配置类的 importBeanDefinitionRegistrars 集合 用于后期bean处理
                                                                或者 将该 类包装成 ConfigurationClass  重新进行 配置处理
                                                            5,判断该类上是否有 @ImportResource 如果有则调用资源解析器 对其进行解析  后期可使用 BeanDefinitionReader 读取该 资源
                                                            6,判断该类的方法上是否有 @Bean 如果有 则将 该方法 包装成 BeanMethod 添加到该类代表的 ConfigurationClass
                                                            7,判断该类的接口的方法上是否有 @Bean 注解 如果有 跟上面一样 包装成 BeanMethod 添加到该类代表的 ConfigurationClass
                                                            8,返回该类的上级类
                                                        7,获取所有的 deferredImportSelectors 集合属性
                                                        8,对 deferredImportSelectors 集合进行排序
                                                        9,调用 deferredImportSelectors 中 ImportSelector 的 selectImports 处理 集合中对应配置类 得到 类
                                                        10,调用 processImports 再次处理 
                                                12,获取    ConfigurationClassParser 解析后所有的 ConfigurationClass 类
                                                13,去掉以及解析过了的配置类
                                                14,初始化 reader 属性 new ConfigurationClassBeanDefinitionReader(registry, this.sourceExtractor, this.resourceLoader, this.environment,this.importBeanNameGenerator, parser.getImportRegistry());
                                                15,调用 ConfigurationClassBeanDefinitionReader 的 loadBeanDefinitions(ConfigurationClass) 对这些类进行解析 并将类定义注册到容器
                                                    细节如下:
                                                16,判断当前容器内的的注册个数是否大于容器中原有个数
                                                    如果有 
                                                    则获取当前容器内的 已注册bena的名称 
                                                    获取当前已解析bean的类名
                                                    获取原有候选解析类
                                                    然后 条件判断新 将该已注册bean中需要被 解析却没有解析的定义进行重新解析。 重复该流程步骤 1-16
                                                17,判断当前 registry是否为空(一般不为空) 
                                                18, 如果该注册容器不包含 org.springframework.context.annotation.ConfigurationClassPostProcessor.importRegistry 单例,则注册一个 ImportStack 主要用于 设置 ImportAware
                                                            
                                9,重新从注册表 获取 所有 类型为 BeanDefinitionRegistryPostProcessor 的 bean 实例 
                                10,遍历这些 bean 获取 这些bean中未执行 postProcessBeanDefinitionRegistry(registry) 的Order子类 到集合 orderedPostProcessors
                                11,对 orderedPostProcessors 排序
                                12,registryPostProcessors 添加该集合
                                12,对 orderedPostProcessors 集合执行 postProcessBeanDefinitionRegistry(registry) 处理
                                13,重新从注册表 获取 所有 类型为 BeanDefinitionRegistryPostProcessor 的 bean 实例 
                                14,遍历这些 bean 获取 这些bean中未执行 postProcessBeanDefinitionRegistry(registry) 类 顺序执行 postProcessBeanDefinitionRegistry(registry) (即不存在于 processedBeans 集合中的类) 执行后将这些类添加到 processedBeans中        
                                15,首先执行 registryPostProcessors 集合中的 处理器的 postProcessBeanFactory(beanFactory) 方法  原因是 该类处理器 可能导致 容器中出现 新的 处理器
                                16,然后执行 regularPostProcessors 集合中的 处理器的 postProcessBeanFactory(beanFactory) 方法
                                17,获取所有的  BeanFactoryPostProcessor 处理器类
                                18,对这些处理器进行分类处理(processedBeans该集合中已存在(基本上为 BeanDefinitionRegistryPostProcessor) 则不做任何处理)  即  priorityOrderedPostProcessors orderedPostProcessorNames nonOrderedPostProcessorNames
                                19,然后进行 priorityOrderedPostProcessors orderedPostProcessorNames nonOrderedPostProcessorNames 集合 依次调用 postProcessBeanDefinitionRegistry(registry) 处理
                    7,注册BeanPostProcessors到容器
                        细节:
                            1,从容器中获取类型为 BeanPostProcessor 的处理器
                            2,设置 BeanPostProcessor 总数量为 beanProcessorTargetCount 容器中已知BeanPostProcessor的个数 以及 上面获取到的个数
                            3,向容器中添加 一个 new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount) 处理器  用于打印日志消息。(处理那些不适合所有处理器处理的bean)
                            4,从容器中获取处理器 并分为4类 PriorityOrdered MergedBeanDefinitionPostProcessor Ordered 其它
                                细节:
                                    PriorityOrdered: 优先级高于 Ordered  该处理器集合最优先处理
                                    MergedBeanDefinitionPostProcessor : 对bean定义进行合并处理 适用于 RootBeanDefinition  类型的定义 该集合是所有该类型的子类集合
                                    Ordered: 优先级低于 PriorityOrdered 该处理器中集合 第二优先级处理
                                    其它: 最后处理的 处理器集合
                            5,向容器中按照 PriorityOrdered Ordered 其它 MergedBeanDefinitionPostProcessor 的顺序 将处理器添加到容器中的 处理器集合
                                细节:
                                    容器在添加处理器时,
                                    会先移除该处理器,
                                    然后再添加该处理器
                                    再然后会判断 该处理器是否为 InstantiationAwareBeanPostProcessor 子类  是,会设置 hasInstantiationAwareBeanPostProcessors 为true  该类会对已初始化的bean属性值进行修改
                                    最后判断,该处理器是否为 DestructionAwareBeanPostProcessor 子类  是,会设置 hasDestructionAwareBeanPostProcessors 为true 该类会对要销毁bean进行回调处理
                            6,向容器中的处理器集合 添加 new ApplicationListenerDetector(applicationContext)
                                细节:
                                    ApplicationListenerDetector : 用于检测处理bean为监听器的,在执行 postProcessAfterInitialization 该方法时 将该bean添加到 applicationContext
                                                                    在执行 postProcessBeforeDestruction 将该bean从 applicationContext 中的 ApplicationEventMulticaster 中移除
                                    
                    8,为 ApplicationContext 初始化 messageSource        
                        细节:
                            1, 获取 beanFactory 容器
                            2,判断该容器是否含有 messageSource 名称的 beanDefinition
                                如果含有:
                                    1, 获取该容器中 名称为 messageSource 类型为 MessageSource 的 bean
                                    2,如果当前 ApplicationContext 的父 不为空,且 该 bean 为 HierarchicalMessageSource 的子类,那么设置该bean的父为 当前ApplicationContext 的父中的 MessageSource
                                如果不含有:
                                    1, 初始化一个 new DelegatingMessageSource() 该对象为空的 MessageSource 但能接受 getMessage 的调用
                                    2,设置该 DelegatingMessageSource 的 父 MessageSource 为 当前 ApplicationContext 的父中的 MessageSource
                                        细节:
                                            如果父 MessageSource 不为空 则会使用 该messageSource 做 getMessage 调用的 回调
                                            如果没有  则判断 如果默认 消息 则处理,否则抛出异常
                                    3,设置当前 ApplicationContext 的 MessageSource 为当前 DelegatingMessageSource 对象
                                    4,向容器中注册 名称为 messageSource 对象为 DelegatingMessageSource 的 bean
                    
                    9,位当前 ApplicationContext 初始化 事件广播器
                        细节:
                            1, 获取 beanFactory 容器
                            2,判断该容器是否含有 applicationEventMulticaster 名称的 beanDefinition
                                如果含有: 则设置 当前 ApplicationContext 的 applicationEventMulticaster 为容器中 名称为 applicationEventMulticaster 类型为 ApplicationEventMulticaster 的bean
                                如果不含有:
                                    1, 初始化一个 new SimpleApplicationEventMulticaster(beanFactory) 为当前 ApplicationContext 的 applicationEventMulticaster
                                    2,将 该对象注册到容器 名称为 applicationEventMulticaster 对象为 SimpleApplicationEventMulticaster 的 bean
                                    
                    10,位当前上下文初始化具体的 bean  即 onRefresh() : 模板方法 用于特定的 ApplicationContext 进行刷新工作,用于 singletons 类型的 bean 实例化之前
                        细节:
                            1,为当前的 ApplicationContext 初始化一个 ThemeSource 主要用于获取样式
                                1,判断当前容器中是否含有 themeSource 名称的 beanDefinition
                                    如果含有:
                                    1, 获取该容器中 名称为 themeSource 类型为 ThemeSource 的 bean
                                    2,如果当前 ApplicationContext 的父 继承自 ThemeSource 且不为空,且 该 bean 为 HierarchicalThemeSource 的子类,那么设置该bean的父为 当前 ApplicationContext 的父
                                如果不含有:
                                    1,判断当前 ApplicationContext 的父 是否是 ThemeSource 的一个实例
                                        如果是:
                                            初始化一个 new DelegatingThemeSource() 并将当前 ApplicationContext 的父 设置为 DelegatingThemeSource 的父
                                        如果不是:
                                            直接初始化一个  new ResourceBundleThemeSource()
                            2,为当前上下文 创建一个 嵌入式的 Servlet 容器 embeddedServletContainer
                                细节:
                                    1, 判断当前 ApplicationContext 中的 EmbeddedServletContainer ServletContext 是否都为空
                                        细节:
                                            1, 从容器中获取 类型为 EmbeddedServletContainerFactory 的 嵌入式Servlet容器工厂
                                            2,获取一个 ServletContextInitializer 用于完成对 ApplicationContext 的 ServletContext 的初始化工作
                                                细节:
                                                    该 ServletContextInitializer 用于 ApplicationContext 对 ServletContext创建的 初始化
                                            3,使用 EmbeddedServletContainerFactory 创建一个 EmbeddedServletContainer
                                                细节: 假设为 Tomcat 的容器
                                                    1, 初始化一个 new Tomcat() 对象
                                                    2,为 Tomcat 对象设置一个 根文件夹
                                                    3,为 Tomcat 对象 的一个服务 设置一个 连接器
                                                            详细:
                                                                连接器: org.apache.catalina.connector.Connector 
                                                                        设置该连接器的默认协议处理器为 org.apache.coyote.http11.Http11NioProtocol
                                                                        设置该连接器的 URIEncoding = "UTF-8";
                                                                        设置该连接器的 URIEncodingLower = URIEncoding.toLowerCase(Locale.ENGLISH);
                                                    4,对 Connector 对象 进行配置
                                                        1,为 Connector 对象 配置端口
                                                        2,为 Connector 对象 中协议处理器 配置地址
                                                        3,为 Connector 对象 配置 URIEncoding
                                                        4,为 Connector 对象 配置 属性 bindOnInit=false  这是为了防止 tomcat 在 ApplicationContext 启动前就绑定套接字
                                                        5,如果 当前应用设置为 ssl 连接 则将连接器 设置为 https  且 设置 secure 属性为 true 并且配置 协议处理器 的ssl
                                                            配置ssl细节:
                                                                1, 设置协议处理器的 ssl 为true
                                                                2,设置协议处理器的 ssl协议名称为 TLS
                                                                3,设置协议处理器的 密钥库密码 为 ssl 对象携带的 密钥库密码 KeyStorePassword
                                                                4,设置协议处理器的 密钥 为 ssl 携带的密钥    KeyPassword
                                                                5,设置协议处理器的 密钥别名 为 ssl 携带的密钥别名 KeyAlias
                                                                6,设置协议处理器的 密钥库文件所在位置 为 ssl 携带的密钥库文件所在位置
                                                                7,设置协议处理器的 密钥库类型  为 ssl 携带的密钥库类型
                                                                8,设置协议处理器的 密钥库供应商  为 ssl 携带的密钥库供应商
                                                        6,如果当前应用设置压缩配置 则对连接器 进行压缩配置
                                                            配置压缩细节:
                                                                1, 设置协议处理器的 Compression 属性为 on
                                                                2,设置协议处理器的 CompressionMinSize 属性为 压缩配置的 压缩最小值
                                                                3,设置协议处理器的 CompressableMimeTypes 属性为 压缩配置的 可压缩 MimeType
                                                                4,设置协议处理器的 NoCompressionUserAgents 属性为 压缩配置的 不压缩 代理
                                                        7,如果当前应用含有 tomcatConnectorCustomizers 则遍历 这个 对 连接器进行初始化 (即对连接器进行自定义配置)
                                            4,设置 Tomcat 对象 的 主机地址自动配置为false
                                            5,设置 Tomcat 对象 的 引擎 在处理上的延迟 为非延迟
                                            6,遍历当前 EmbeddedServletContainerFactory 中的 连接器 并将这些连接器 添加到 Tomcat 对象 的服务中
                                            7,对  Tomcat 对象 的 Host(StandardHost) 进行处理
                                                细节:
                                                    1, 获取 docBase
                                                    2,设置 TomcatEmbeddedContext 的 访问路径
                                                    3,设置 TomcatEmbeddedContext 的显示名称
                                                    4,设置 TomcatEmbeddedContext 的名称
                                                    5,设置 TomcatEmbeddedContext 的 应用存放路径
                                                    6,设置 TomcatEmbeddedContext 的 生命周期监听器 new FixContextListener()
                                                    7,设置 TomcatEmbeddedContext 的 类加载器
                                                    8,设置 TomcatEmbeddedContext 的 应用加载器
                                                    9,设置 TomcatEmbeddedContext 的 默认 DefaultServlet
                                                    10,设置 TomcatEmbeddedContext 的 JspServlet 并添加 Jsp 的初始化器
                                                    11,合并所有 的 ServletContextInitializer 
                                                        主要有 上面初始化好的 传入的 ServletContextInitializer ,SessionConfiguringInitializer , InitParameterConfiguringServletContextInitializer
                                                    12, 初始化一个 new TomcatStarter(ServletContextInitializers) 对象
                                                    13,设置 TomcatEmbeddedContext 的 TomcatStarter 启动器
                                                    14,设置 TomcatEmbeddedContext 的 ServletContextInitializer 集合 添加上面三个 初始化器
                                                    15,设置 TomcatEmbeddedContext 的 Pipeline
                                                    16,设置 TomcatEmbeddedContext 的 错误页面
                                                    17,设置 TomcatEmbeddedContext 的 MimeMappings 映射 即 extension 对应的 MimeType
                                                    18,设置 TomcatEmbeddedContext 的 session 处理  比如 session 持久化, 时长,  如果不进行持久化 则添加一个 session的非持久化监听器
                                                    19, 使用 TomcatContextCustomizer 对 TomcatEmbeddedContext 进行自定义处理
                                                    20, 设置 Host 的 子节点为 TomcatEmbeddedContext
                                                    
                                            8, 根据传入的 Tomcat 对象 获取 EmbeddedServletContainer 容器
                                                细节:
                                                    1,设置 tomcat 属性
                                                    2,设置 autoStart 为true
                                                    3,设置 引擎 名称
                                                    4,获取 tomcat service 集合 遍历 service 移除所有连接器 并将这些连接器 放入 serviceConnectors 属性中 对应为 service-所有的连接器
                                                    5,启动 tomcat 触发 tomcat 中的所有 监听器
                                                    6,重新抛出 启动失败的 异常 (如果有的情况下)
                                                    7,设置当前 tomcat 的 Server 为等待状态 (表明 当前的tomcat 已处于就绪状态)
                                                    
                            3,使用当前应用的配置属性 以及 ServletConfig 配置当前 ServletContext
                    
                    11,从当前 ApplicationContext 中检测 listener 并注册这些 监听器到 到当前 ApplicationContext    的广播器当中
                            细节:
                                1, 获取当前 ApplicationContext 中的监听器 注册这些监听器到 ApplicationContext 的广播器当中
                                2,获取容器中 类型为 ApplicationListener 的监听器,并注册到 ApplicationContext 的广播器当中
                                3,获取当前 ApplicationContext 中 earlyApplicationEvents 并通过 ApplicationContext 的广播器 发送到所有监听器中
                    
                    12,初始化所有当前 ApplicationContext 的容器中 所有 非懒加载的 单例 bean
                            细节:
                                1, 判断 容器中 是否含有 conversionService 名称的bean 以及 类型 符合 ConversionService 的bean
                                2,如有 则取出bean 设置为 容器 ConversionService 属性
                                3,冻结容器内所有的配置 以及 冻结容器内所有的 beanDefinitionNames
                                4,对单例 beanDefinition 进行初始化
                                    细节:
                                        1,获取容器中所有的 beanDefinitionNames 
                                        2,遍历 beanDefinitionNames 并取出改名字 代表的 beanDefinition (包括该容器的 父容器)
                                        3,对取出的 beanDefinition 进行 判断  取出 (非抽象,单例,非懒加载) 的定义
                                        4,判断该 beanDefinition 是否是 FactoryBean
                                            判断细节:
                                                1,根据名称获取真实名称 (比如去掉&前置符号,如果是别名,需要取出真实名称)
                                                2,根据给定名称 从容器中的 singletonObjects 获取对象
                                                3,如果 singletonObjects 中 找不到该名称对象,并且判断该对象处于创建中
                                                4,从 earlySingletonObjects 中根据名称获取对象。如果渠道的为空,并且如果 允许早期引用,那么通过 singletonFactories 获取其工厂创建类 创建对象
                                                5,判断取出的对象 是否为 FactoryBean 的实例 是的话 返回true
                                                6,判断 singletonObjects 含有该名称 返回false
                                                7,如果从容器中的Beandefinition中找不到,并且 当前容器 的父容器 属于 ConfigurableBeanFactory 则获取 父容器来判断当前 名称是否是 FactoryBean
                                                8,如果从容器中BEANDefinition 中到得到到,或者 父容器 不是 ConfigurableBeanFactory 则使用当前容器判断 是否为 FactoryBean
                                        5,如果是则获取该名称的FactoryBean 然后进行处理
                                        6,最后调用 容器中getBean 获取bean实例化
                    13,进行刷新后 刷新事件的广播
                        细节:
                            1, 配置属性 lifecycleProcessor  (首先从容器中获取,如果获取不到 自己 new DefaultLifecycleProcessor() 然后注册到容器)
                            2,调用刚刚配置的属性 lifecycleProcessor 的刷新进行刷新 并设置 lifecycleProcessor 的属性 running 为true
                            3,通过当前 ApplicationContext 的广播器将 ContextRefreshedEvent 事件广播出去,如果 当前 ApplicationContext 的父 存在 则调用父的广播器将事件广播出去
                            4,获取通过 startEmbeddedServletContainer 启动 返回 EmbeddedServletContainer 容器,如果该容器存在 则通过广播器 将 new EmbeddedServletContainerInitializedEvent(this, localContainer) 事件广播出去
                            
                14, ApplicationContext  注册一个关闭钩子
        
        6, ApplicationContext 刷新后的    处理
                1,获取当前上下文中 ApplicationRunner, CommandLineRunner 集合 排序
                2,执行 集合中的 bean的run方法
                                
                    
                
                
                
                

你可能感兴趣的:(spring,spring)