spring boot 1.5.3 源代码 - 启动流程

37 篇文章 0 订阅
18 篇文章 0 订阅

 

1、初始化
    1、获取 initializers
        // 加载类路径中所有"META-INF/spring.factories"文件中的所有属性文件,查找键为“org.springframework.context.ApplicationContextInitializer”的类列表,实例化所有ApplicationContextInitializer类
        setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));

    2、获取listeners
        // 加载类路径中所有"META-INF/spring.factories"文件中的所有属性文件,查找键为“org.springframework.context.ApplicationListener”的类列表,实例化所有ApplicationListener类
        setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));

    3、设置 mainApplicationClass
        // this.mainApplicationClass = cn.java.springboot.demo.main2.Main
        this.mainApplicationClass = deduceMainApplicationClass(); // 检查栈中含有main方法的类

2、执行
    1、创建SpringApplicationRunListeners对象(全局环境中,实际只有一个 EventPublishingRunListener,用于管理 SpringApplication.listeners )
        1、加载类路径中所有"META-INF/spring.factories"文件中的所有属性文件,查找键为SpringApplicationRunListener的类列表,实例化所有SpringApplicationRunListener类
        2、实例化所有 SpringApplicationRunListener,并把 SpringApplication 和 args 作为参数注入

    2、触发事件 --- 事件
        # 调用SpringApplicationRunListeners对象的starting方法
        listeners.starting();   // 迭代调用实现SpringApplicationRunListener接口的listener的starting方法

    3、创建《环境》
        StandardServletEnvironment
    4、打印信息到控制台
    5、创建上下文
        AnnotationConfigEmbeddedWebApplicationContext
    6、创建失败分析器
        1、在“META-INF/spring.factories”查找,实现FailureAnalyzer接口的analyzers列表
	 	2、通过 context.getBeanFactory() 获取,给analyzers注入beanFactory
	7、预备上下文
	    1、设置环境 environment 到 context
	    2、设置 context 属性
	        1、设置bean名生成器
                context.getBeanFactory().registerSingleton(...)
            2、设置资源加载器
                。。
            3、设置类加载器
                。。
	    3、迭代 SpringApplication.initializers 列表,调用 initialize(context) 方法

    8、触发事件 --- 事件
         listeners.contextPrepared(context);
    9、注册对象到 BeanFactory
        注册 《参数 》对象到 BeanFactory
	    注册 printedBanner 对象到 BeanFactory

	10、加载资源
	    1、创建 BeanDefinitionLoader 对象
            1、对sources依赖
            2、创建《各种文件类型》的解析器
                1、注册 Processor,处理 @Configuration、@Autowired 注解等。。!!!  ------ 对注解的核心支持
        2、设置 BeanDefinitionLoader 的 bean名生成器
        3、设置 BeanDefinitionLoader 的 资源加载器
        3、设置 BeanDefinitionLoader 的 类加载器
        2、调用 BeanDefinitionLoader 加载 bean 定义 !!!! 按《文件类型》加载资源
    11、触发事件 --- 事件
        listeners.contextLoaded(context);

    12、刷新上下文
        1、调用context.refresh(); 加载ApplicationContext.xml文件
            1、常规的 context.refresh() 功能
                1、处理环境相关
                2、调用bean的postProcessBeanDefinitionRegistry(...)方法
                {
                    1、处理 cn.java.demo.user.MainApplication 类(因为 @SpringBootApplication 注解内有 @ComponentScan 注解)
                    {
                        1、解析 parse(Set<BeanDefinitionHolder> configCandidates) - //  解析 MainApplication 类 --- 创建新的configClass & 无依赖父configClass
                        {
                            1、parse(String className, String beanName)
                            {
                                processConfigurationClass(ConfigurationClass configClass)
                                {
                                    1、检查 @Conditional 的条件

                                    2、doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
                                    {
                                        1、处理《内部类》
                                            如果存在,递归到 《processConfigurationClass(ConfigurationClass configClass)》 (即:深度优先)--- 创建新的configClass & 依赖父configClass

                                        2、处理 @PropertySources 注解
                                            即刻导入资源配置,并设置到 environment

                                        3、处理 @ComponentScans 注解 & 检查 @Conditional 的条件
                                            1、立刻扫描含有 @Component、@ManagedBean、@Named 注解的类,并放入 scannedBeanDefinitions
                                            2、迭代扫描出来的 scannedBeanDefinitions
                                                递归到 parse(String className, String beanName) ,处理扫描到的bean --- (即:深度优先)创建新的configClass & 不依赖父configClass

                                        4、《processImports》处理 @Import 注解
                                            1、是 ImportSelector 的子类
                                                1、是 DeferredImportSelector 的子类
                                                    添加到 this.deferredImportSelectors 列表
                                                2、不是 DeferredImportSelector 的子类
                                                    递归到 《processImports》,执行到

                                            2、是 ImportBeanDefinitionRegistrar 的子类
                                                添加到 configClass.importBeanDefinitionRegistrars

                                            3、其他
                                                递归到 《processConfigurationClass(ConfigurationClass configClass)》,进行解析 --- (即:深度优先)创建新的configClass & 依赖父configClass

                                         5、处理 @ImportResource 注解
                                            添加到 configClass.importedResources

                                         6、处理 带有@Bean注解的方法列表
                                            添加到 configClass.beanMethods

                                         7、读取所有父接口的《带有@Bean注解的方法列表》
                                            添加到 configClass.beanMethods
                                    }

                                    3、注册 configClass 到 configurationClasses ----- 添加 configClass
                                }
                            }

                            2、执行 this.deferredImportSelectors 列表
                                1、执行 《processImports》 导入处理
                         }

                         2、调用 loadBeanDefinitions,执行 Bean 定义加载
                         {
                            1、检查 @Conditional 的条件
                            2、把 configClass 子级的 configClass 注册到 beanFactory --- 会进入第二解析
                            3、处理 @Bean 方法,configClass.beanMethods,用工厂模式包装,并注册到 beanFactory
                                1、带有@Bean注解的方法列表
		                        2、所有父接口的《带有@Bean注解的方法列表》
                            4、处理 @ImportResource 的后续,(即:configClass.importedResources)
                                执行xml资源导入
                            5、处理@Import注解且继承ImportBeanDefinitionRegistrar,(即:configClass.importBeanDefinitionRegistrars)
                                。。
                        }
                    }
                }
                3、调用 bean的postProcessBeanFactory方法
                4、注册 BeanPostProcessor
                等等。。。

            2、上下文容器 tomcat 的获取
            3、上下文容器 tomcat 的启动
		2、调用context.registerShutdownHook();

    13、《刷新》后续处理
        1、扫描 context 中实现 ApplicationRunner 接口的 bean 列表
        2、扫描 context 中实现 CommandLineRunner 接口的 bean 列表
        3、迭代调用的 ApplicationRunner 类型bean的 run 方法
        4、迭代调用的 CommandLineRunner 类型bean的 run 方法

    14、触发事件 --- 事件
        listeners.finished(context, null);

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值