源码流程
作用:做两件事:注册spring依赖的各种后置处理器beanPostProcessor、注册相关的beanDifinition,用来后续的bean工厂创建bean;
其实它就是用来描述Bean的,里面存放着关于Bean的一系列信息,比如Bean的作用域,Bean所对应的Class,是 否懒加载,是否Primary等等,这个BeanDefinition也相当重要,我们以后会常常和它打交道。
回到这个方法中,我们发现他又调用了一个注册方法将beanName和definition注册,
主要是这个加锁有点难以理解,其他都好说;至此,bean工厂的所有原料 添加完毕,就等工厂开工生产!
之后就是创建扫描器,这个扫描器只是提供给外部手动调用的,没多大用处;
好家伙,内置的类全注册了,但是我们自定义的类呢?不慌,把目光回到开始
点进去!最终来到doRegister
在这里又要说明下,以常规方式去注册配置类,此方法中除了第一个参数,其他参数都是默认值。
通过AnnotatedGenericBeanDefinition的构造方法,获得配置类的BeanDefinition,这里是不是 似曾相似,在注册ConfigurationClassPostProcessor类的时候,也是通过构造方法去获得 BeanDefinition的,只不过当时是通过RootBeanDefinition去获得,现在是通过 AnnotatedGenericBeanDefinition去获得。
判断需不需要跳过注册,Spring中有一个@Condition注解,如果不满足条件,就会过这个类的 注册。
然后是解析作用域,如果没有设置的话,默认为单例。
获得BeanName。
解析通用注解,填充到AnnotatedGenericBeanDefinition,解析的注解为Lazy,Primary, DependsOn,Role,Description。
限定符处理,不是特指@Qualifier注解,也有可能是Primary,或者是Lazy,或者是其他(理论上 是任何注解,这里没有判断注解的有效性)。
把AnnotatedGenericBeanDefinition数据结构和beanName封装到一个对象中(这个不是很重 要,可以简单的理解为方便传参)。
注册,最终会调用DefaultListableBeanFactory中的registerBeanDefinition方法去注册:
其实到这里只是Spring的冰山一角,我们目前只知道了spring是如何注册内置的bean和我们的配置类而已,我们还没扫描呢,还没创建bean呢!不急!
prepareBeanFactory(beanFactory);这个方法需要了解一下,主要有以下功能
首先明确他的任务:把之前加入的后置处理器给实例化,我们不是加入了许多后置处理器么( BeanFactoryPostProcessor ),这里的目的就是首先把他们实例化出来,然后调用他们内部的方法!所以带着这个任务去阅读源码,寻找我们需要的信息
但是我们想一下,我们注册了五个后置处理器,他以什么样的规则来实例化执行呢?这里先给出结论:
分类: BeanFactoryPostProcessor 分为两种
spring机制要求先处理直接实现了第二种的Post Processor,然后处理直接实现了第一种的;
在处理每一种Post Processor时,还要分优先级情况PriorityOrdered, Ordered。
所以流程就是
整体上流程如下:
1.处理BeanDefinitionRegistryPostProcessor
-------1.1 处理PriorityOrdered优先级的
-------1.2处理Ordered优先级的
-------1.3处理其他优先级的
打开一看继承关系发现:
只有一个后置处理器实现了他,所以把它处理了就ok了!
2.处理BeanFactoryPostProcessor
-------2.1 处理PriorityOrdered优先级的
-------2.2处理Ordered优先级的
-------2.3处理其他优先级的
-------ok进源码,先BeanDefinitionRegistryPostProcessor
拿到ConfigProcessor之后就可以实例化了
接下来就可以看看实例化的代码,这是很重要的一环
点击getbean后发现是个接口
那么那会调用哪一个实现类呢?答案是 第二个,那么直接点进去来到dogetBean();
接着往下看
@DependsOn注解遇到循环依赖就会抛出异常了,举个例子
来看运行结果:
不就是上面源码中的那个异常吗?看来Spring并没有解决这种循环依赖的办法?或者是我孤陋寡闻------
接着往下看
如何创建bean的呢?这里可能涉及循环依赖,当然我们第一步的话是实例化ConfigrationProcessor这个类,这个类是不会有循环依赖的,毕竟他的功能就是实例化出来后用来扫描bean,
看源码如何创建的
每一个类在实例化之前都会调用后置处理器,然后再实例化,关于实例化docreatBean里面有很处理了循环依赖的问题导致稍微难理解,这回单独放在一章来讲解
后置处理器的九次调用,上上图中的resolveBeforeInstantiationjiushi 第一次;方法中判断是否实现的 hasInstantiationAwareBeanPostProcessors 这个接口,实现了就会调用方法;
简单介绍一下doCreatBean的主要流程打个照面
1.首先使用bean的构造方法创建bean;
2.执行MergedBeanDefinitionPostProcessor类型的后置处理器回调方法,利用反射技术,遍历类中的属性和方法,并判断属性和方法上的注解信息;
比如CommonAnnotationBeanPostProcessor.java,用于发现并缓存@Resource等注解修饰的属性;
比如AutowiredAnnotationBeanPostProcessor.java,用于发现并缓存@Autowired/@Value等注解修饰的属性;
等等。
3.提前缓存earlyBeanReference引用,就是实例化还没初始化的bean信息,用于后边处理循环依赖。
4.populateBean填充bean,就是初始化bean的属性值;如果属性是个bean,此处需要实例化依赖的bean,并缓存到一个叫earlySingletonObjects的map中;
5.initializeBean执行init或者post processors,动态代理也发生在这一步;
6.最终返回创建好的bean对象。
之后的其他各种后置处理器走一样的流程;
之后还有几个方法:分别作用是:
这些就是IOC的流程了!
1.BeanFactory和FactoryBean的区别?
2.请介绍BeanFactoryPostProcessor在Spring中的用途。
3.SpringIoC的加载过程。
4.Bean的生命周期。
5.Spring中有哪些扩展接口及调用时机。