SpringIOC的启动流程

因为现在都是注解驱动,当我们使用AnnotationConfigApplicationContext(Class<?>… annotatedClasses)创建一个spring容器的时候,spring加载的bean都会放到这里面。
①他首先会去调用自己的无参构造方法,先调用父类的无参构造方法生成一个IOC容器,
然后在自己的无参构造方法中创建了一个读取注解的bean定义(beanDefinition)读取器,向spring容器注册各种后置处理器(BeanDefinition),比如处理@Autowired的后置处理器还有处理@Resource的后置处理器,其中有一个类
ConfigurationClassPostProcessor
注册进spring中非常重要,一系列的解析器都是spring 的组件
1.1、创建一个扫描器,创建一些过滤器用来从指定包下面查找Class,如果能通过过滤器的话,那么这个class就会被转化成BeanDefinition注册到容器,默认注册了@Component过滤器到includeFiters ,相当于 同时注册了所有被@Component注释的注解,包括@Service ,@Repository,@Controller,还支持其他的几种注解,可以用来扫描包或者类,继而转化为beanDefinition。这里的扫描器不是,但是实际上我们扫描包工作不是scanner这个对象来完成的,是spring自己new的一个ClassPathBeanDefinitionScanner(这里的scanner仅仅是为了程序员能够在外部调用AnnotationConfigApplicationContext对象的scan方法)

②然后会调用register(annotatedClasses);把配置类注册进register(annotatedClasses);
③调用refersh()刷新整个容器

  1. 先调用prepareRefresh()准备刷新上下文环境,先初始化一些属性设置,然后校验属性的合法性,创建容器用来保存早期事件
  2. obtainFreshBeanFactory(); ,通过这个方法获取一个工厂
  3. prepareBeanFactory(beanFactory);,准备工厂,对工厂的各种功能进行填充,比如设置其上下文的加载器,设置各种Aware接口的实现类为忽略自动装配,还会添加一个后置处理器ApplicationContextAwareProcessor,能够在bean中获得各种*Aware
  4. postProcessBeanFactory(beanFactory);bean工厂的后置处理器,这个方法是空实现,可能是为了方便我们自己扩展的。可以让子类覆盖方法做额外的处理
  5. invokeBeanFactoryPostProcessors(beanFactory); //**在spring的环境中去执行已经被注册的facotry processors,设置执行自定义的ProcessBeanFactory 和spring内部自己定义的激活各种BeanFactory处理器。**因为spring工厂在初始化完成之前,需要完成一些注解扫描的解析,所以spring在上面创建bean定义读取器的时候向容器注册了,在这里会执行两种后置处理器BeanFactoryPostProcessor和invokeBeanFactoryPostProcessors,执行逻辑如下。
    再执行BeanFactoryPostProcessor的方法
    1)、获取所有的BeanFactoryPostProcessor
    2)、看先执行实现了PriorityOrdered优先级接口的BeanFactoryPostProcessor、
    postProcessor.postProcessBeanFactory()
    3)、在执行实现了Ordered顺序接口的BeanFactoryPostProcessor;
    postProcessor.postProcessBeanFactory()
    4)、最后执行没有实现任何优先级或者是顺序接口的BeanFactoryPostProcessor;
    postProcessor.postProcessBeanFactory()
    ConfigurationClassPostProcessor,ConfigurationClassPostProcessor是一个BeanFactory的后置处理器,因此它的主要功能是参与BeanFactory的建造,在这个类中,会解析加了@Configuration的配置类,还会解析@ComponentScan、@ComponentScans注解扫描的包,以及解析@Import等注解。
  6. registerBeanPostProcessors(beanFactory); 会找出所有实现BeanPostProcessor接口的类,注册beanPostProcessor,BeanPostProcessor 实现类和 BeanFactoryPostProcessor 实现类一样,也可以通过实现 PriorityOrdered、Ordered 接口来调整自己的优先级。spring的aop的BeanPostProcessor也会被找出来注册进IOC中
  7. initMessageSource();为上下文初始化Message源,即不同语言的消息体,做一些国际化处理
  8. initApplicationEventMulticaster(); 初始化应用事件广播器,用来派发事件的
  9. onRefresh();是空实现,留给子类来初始化其他的bean,springboot启动Tomcat就是在这个方法中实现,执行其他的初始化操作,例如和SpringMVC整合时,需要初始化一些其他的bean,但是对于纯Spring工程来说,onRefresh()方法是一个空方法。
  10. registerListeners(beanFactory); 获取之前注册的广播器中,在所有注册的bean中查找Listener bean,注册到消息广播器中,执行其他的初始化操作,如果有早期事件,还会发布早期事件,早期事件就是这个广播器还没有初始化的时候发布的事件。
  11. finishBeanFactoryInitialization(beanFactory);该方法会实例化所有剩余的非懒加载单例 bean
    ①在这个方法里首先会冻结所有的beanDifinition,然后调用 beanFactory.preInstantiateSingletons();实例化所有的单例对象。
    ②在 preInstantiateSingletons()中会.遍历所有的beanNames,获取 beanName 对应的 MergedBeanDefinition,判断 beanName 对应的 bean 是否为 FactoryBean,然后调用getBean(Bean)获取bean 的实例,最后遍历所有的beanNames,触发所有 SmartInitializingSingleton 的后初始化回调,这是 Spring 提供的一个扩展点,在所有非懒加载单例实例化结束后调用。
    在Spring中,关于bean定义,其Java建模模型是接口BeanDefinition, 其变种有RootBeanDefinition,ChildBeanDefinition,还有GenericBeanDefinition,
    综上可见,一个MergedBeanDefinition是这样一个载体:
1、根据原始BeanDefinition及其可能存在的双亲BeanDefinition中的bean定义信息"合并"而得来的一个RootBeanDefinition;
2、每个Bean的创建需要的是一个MergedBeanDefinition,也就是需要基于原始BeanDefinition及其双亲BeanDefinition信息得到一个信息"合并"之后的BeanDefinition;

3、 Spring框架同时提供了一个机会给框架其他部分,或者开发人员用于在bean创建过程中,MergedBeanDefinition生成之后,bean属性填充之前,对该bean和该MergedBeanDefinition做一次回调,相应的回调接口是MergedBeanDefinitionPostProcessor。
4、 MergedBeanDefinition没有相应的Spring建模,它是处于一个内部使用目的合并自其它BeanDefinition对象,其具体对象所使用的实现类类型是RootBeanDefinition。

        ③getBean的执行流程十分复杂

12.finishRefresh();完成刷新过程,通知声明周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent把上下文刷新完成时间通知给别人通知别人

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值