一步一步分析SpringBoot启动源码(四)

分享 未结 精帖 2 3488
KSE-music
KSE-music LV4 2018-08-05
悬赏:20积分
一、context = createApplicationContext();依旧见其名知其义,创建应用上下文即“高富帅”接口ApplicationContext。
1、首先是判断用户有没有自定义的应用上下文class,如果有就直接实例化。
2、如果没有(默认)就判断当前应用的是不是web应用,是则根据class的完全限定名去获取它的class,然后再实例化
web应用: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext
非web应用:org.springframework.context.annotation.AnnotationConfigApplicationContext
3、我们这里是web应用,所以通过反射实例化AnnotationConfigEmbeddedWebApplicationContext,下面是它的构造器

里面new了两个对象。第一个是读取那些通过注解实例化的bean定义读取器,第二个是我们最常见的通过扫描classpath下特定注解的bean定义扫描器。而这两个bean定义拾取器的构造参数都是当前对象this,即AnnotationConfigEmbeddedWebApplicationContext的对象,来看下它的继承结构图

在这个类继承图有几个关键点:一是实例化了默认的资源加载器DefaultResourceLoader,二是实例化了默认的bean默认管理器DefaultListableBeanFactory,还有一个重要的就是当前的这个this也是实现了BeanDefinitionRegistry(bean定义注册表,所有的bean定义描述都在这里注册了,后期上下文刷新就会一个个实例化这里的bean)
常识:子类构造器默认调用其父类构造器
4、AnnotatedBeanDefinitionReader
这里比较简单,大致过程就是:首先看当前应用环境是不是为空,是则创建一个标准的servlet环境,然后调用重载构造器,把当前的BeanDefinitionRegistry赋值给AnnotatedBeanDefinitionReader,同时通过其和环境实例化了一个判定需要实例化的bean是不是条件初始化的对象。最后通过注解配置工具类初始化一些必要的注解配置处理器,即注册所有相关的注解后置处理器。具体操作就在registerAnnotationConfigProcessors这个方法里,这里首先就给beanFactory设置了注解感知比较器和上下文注解装配候选解析器。最后依次注册了6个后置处理器,结果见下图


5、ClassPathBeanDefinitionScanner
这个和上面那个过程大体一样:不同的是它这里使用的默认过滤器(意思是具有哪些标记的bean是由spring实例化的),分别是Component、javax.annotation.ManagedBean( Java EE 6)、javax.inject.Named(JSR-330),当然也包括Repository、Service、Controller,我想这个大家都懂的!然后是设置环境,最后设置了资源类型解析器和实例化了一个MetadataReaderFactory(缓存每一个读取的资源文件,如.class文件)

二、analyzers = new FailureAnalyzers(context);实例化应用启动失败分析器
这里主要就是获取一些失败分析器,手法和前面获取监听器以及上下文初始化器一样,通过解析spring.factories文件里key为org.springframework.boot.diagnostics.FailureAnalyzer的配置项,然后将当前类加载器和分析器名字作为构造器参数通过反射实例化,最后循环所有失败分析器,将实现了BeanFactoryAware接口的分析器设置BeanFactory。

三、prepareContext(context, environment, listeners, applicationArguments,printedBanner);

简单部分已从图上说明。
接下来就是加载source即我们的spring启动类,一句话概括就是把启动类的bean定义描述注册到BeanDefinitionRegistry中去,最后就是发送ApplicationPreparedEvent即表示应用上下文准备好了等待刷新了。

在初始化器中我们选择一个SharedMetadataReaderFactoryContextInitializer讲讲。
这个初始化器作用是创建一个共享的缓存每一个资源文件元数据读取工厂在配置类后置处理器和Spring Boot之间。从它的初始化方法中可以看到它在上下文中添加了一个BeanFactoryPostProcessor,而上下文中的BeanFactoryPostProcessor会在后面的容器刷新时优先执行。

BeanFactoryPostProcessor:
这个后置处理器允许自定义修改已经过标准初始化的bean描述定义,调整上下文的底层bean工厂的bean属性值。
四、refreshContext(context);后续作为专题讲。

五、afterRefresh(context, applicationArguments);

这里主要是在上下文中查找哪些实现了ApplicationRunner和CommandLineRunner的接口,然后排序,再循环一个个调用里面的run方法

六、listeners.finished(context, null);发布应该完成事件
这里主要就是发布完成应用启动完成事件。如果有异常就发布ApplicationFailedEvent时间,否则就发生ApplicationReadyEvent事件,然后通过应用上下文的ApplicationEventMulticaster发送事件
回帖