Spring IOC源码 (一) 之BeanFactory创建及预处理

BeanFactory是一个Interface,这是Spring的核心。它仅仅只是提供的一些基本功能。ApplicaionContext也是一个interface,这是从BeanFactory继承过来的所以它具备了BeanFactory的所有功能。

BeanFactory提供的是最基本的IOC容器的功能,用于管理bean的。

我们之前学习Spring AOP、BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor等源码的时候,以及我们在学习一些基础的组件时,以及getBean等方法时,好多地方就会有我们BeanFactory的使用,那我们Spring是在什么地方创建及预处理它的呢?

我们先跟随Spring的源码一步步进行学习,我们先看一下我们非常熟悉的地方,就是我们容器的刷新
Spring IOC源码 (一) 之BeanFactory创建及预处理
箭头上面的方法大致就是如果我们是xml形式等,可能对在其中做一些解析等处理,这里我们就不关心了,直接进入refresh方法(主要是刷新容器的预处理)
Spring IOC源码 (一) 之BeanFactory创建及预处理
这里我们应该都非常熟悉了,我们会发现进入后,首先会进行加锁,防止了线程安全问题,然后我们先看其第一个方法
Spring IOC源码 (一) 之BeanFactory创建及预处理
发现就是先记录下当前时间,然后设置下我们容器的是否是关闭、是否是活跃的等状态,然后我们看第一个方法,看注释说是给上下文环境中初始化一些值,跟进
Spring IOC源码 (一) 之BeanFactory创建及预处理
发现是空的,没有做任何事情这里,但是我们注意下是protected类型,所以我们子类继承后可以对该方法进行自定义的设置。然后我们看其其他二个方法,如下:
Spring IOC源码 (一) 之BeanFactory创建及预处理

  • 第二个方法首先是获取其环境变量,然后进行验证属性的合法性
  • 第三个方法是保存容器早期的通知,我们应该了解容器的一些状态等改变,都是需要事件进行通知,相当于触发器,我们保存其早期的通知,防止我们的事件声明出现问题

我们发现这个方法是和我们的BeanFactory没有太大关系,我们看下一个方法obtainFreshBeanFactory,其实这个方法就是获取我们BeanFactory的实例
Spring IOC源码 (一) 之BeanFactory创建及预处理
我们进入其方法中,查看其获取BeanFactory实例的过程
Spring IOC源码 (一) 之BeanFactory创建及预处理
我们就会发现在其中,有一个刷新BeanFactory的方法,我们先进入其中看一看
Spring IOC源码 (一) 之BeanFactory创建及预处理
我们发现我们会进入GenericApplicationContext类中(可以debug跟进),在其方法中会发现是不是重复刷新,在下面我们会发现一个奇怪的地方,就是我们的beanFactory不是还没创建么,怎么开始调用方法了呢,难道是以及创建了?
Spring IOC源码 (一) 之BeanFactory创建及预处理
我们向下寻找,发现原来是我们这个类在无参构造方法内,就实例化了beanFactory这个对象了,那我们可能又有思考,在什么地方调用我们的GenericApplicationContext类的无参构造方法内了?
这时候我们可以看一下我们的测试类
Spring IOC源码 (一) 之BeanFactory创建及预处理
Spring IOC源码 (一) 之BeanFactory创建及预处理
我们看到上面的两种图片就会明白了,原来AnnotationConfigApplicationContext继承了GenericApplicationContext,当我们实例化AnnotationConfigApplicationContext就会调用其父类的构造方法,也就是会对我们的BeanFactory进行实例化了

我们看refereshBeanFactory方法后,就是用ConfigurationListableBeanFactory接口去接受我们刚刚实例化的BeanFactory的DefaultListableBeanFactory,并返回
Spring IOC源码 (一) 之BeanFactory创建及预处理
我们验证下getBeanFactory方法
Spring IOC源码 (一) 之BeanFactory创建及预处理
好了,到现在为止我们刚刚就创建好了我们的BeanFactory,但是我们的BeanFactory现在还是空,因为我们刚刚直接new了一个对象出来,然后直接返回了。
Spring IOC源码 (一) 之BeanFactory创建及预处理
上图,箭头处方法,这一步就是对我们刚刚创建的BeanFactory进性一些预处理,即进行一些赋值操作,我们对该方法进行跟入
Spring IOC源码 (一) 之BeanFactory创建及预处理
我们会发现其中会进行一系列的赋值,我们先看上图的三个箭头方法的作用

  • 设置BeanFactory的类加载器
  • 支持相关的表达式语言的解析
  • 属性的编辑注册等

继续向下看,如下图:
Spring IOC源码 (一) 之BeanFactory创建及预处理
上面主要是对我们的一些Aware接口进行设置等处理

继续向下看,如下图:
Spring IOC源码 (一) 之BeanFactory创建及预处理
这里主要是注册可以解析的自动装配(可以在其他组件中自动注入,如BeanFactory、ApplicationContext等)

继续向下看,如下图:
Spring IOC源码 (一) 之BeanFactory创建及预处理
添加我们对事件的进行监听的处理器

继续向下看,如下图:
Spring IOC源码 (一) 之BeanFactory创建及预处理
对我们的环境变量进行设置,注册一些环境变量相关的Bean。

到现在我们的BeanFactory的预处理设置也完成了,然后我们继续向下看
Spring IOC源码 (一) 之BeanFactory创建及预处理
进入其中查看,跟进
Spring IOC源码 (一) 之BeanFactory创建及预处理
我们发现和我们刷新容器预处理工作中initPropertySources方法一样,这里的postProcessBeanFactory方法也是空的,默认不进行处理,但是是protected类型,就是说我们子类可以通过重写来在这个方法内进行一些自定义的处理(在创建及其预处理后可以进行自定义的一些处理)。

好了,到这里为止,我们的BeanFactory以及创建及其准备工作已经完成啦。