Spring源码学习(二)

Spring源码学习之高手如云

Posted by GuiLing on May 21, 2019

Spring源码分析(二)

  • 上篇中说道执行refresh()方法中的prepareRefresh();进行容器刷新前的准备工作。

首先看一下创建容器的几种方式,上篇中只说了其中的一种方式,使用注解的方式创建。除了注解方式外还有

ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
ApplicationContext applicationContext1  = new ClassPathXmlApplicationContext("");
ApplicationContext applicationContext2  = new FileSystemXmlApplicationContext("");

在容器刷新前准备完成后会调用ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();方法获得BeanFactory,在obtainFreshBeanFactory中首先会刷新BeanFactory,refreshBeanFactory();AbstractApplicationContext的一个抽象方法不同的创建容器的方式实现不同,这里先来看一下AbstractApplicationContext的类结构图:

由类图可以看出注解方式使用的AnnotationConfigApplicationContext类继承了GenericApplicationContext类所以在进行BeanFactory刷新时调用了父类GenericApplicationContext类实现的refreshBeanFactory()方法实际是给BeanFactory设置了一个ID.

如果使用另外两种方式创建容器的话在刷新BeanFactory时所作的操作是不同的,因为其他两种方式他们的父类是AbstractRefreshableApplicationContext在刷新时调用了AbstractRefreshableApplicationContext的实现,具体做了哪些事呢?

由代码可以看出,这里首先判断当前是否已经有一个BeanFactory存在了,如果已经存在了一个BeanFactory就执行destroyBeans()方法,在方法中拿到当前的BeanFactory并销毁所有的单实例Bean和缓存中的Bean,关闭并销毁当前的BeanFactory,为创建新的BeanFactory做准备。

销毁了已存在的BeanFactory之后重新创建了一个新的BeanFactory并设置ID,调用自定义BeanFactory方法,设置是否允许Bean定义被覆盖,是否允许循环依赖。

然后加载XML中的Bean定义信息

创建一个XmlBeanDefinitionReader用来读取XML中Bean的配置信息,设置reader的属性,然后将Bean的定义信息进行注册,返货Bean的数量。将刷新后的BeanFactory设置为全局的。然后回到obtainFreshBeanFactory()方法中调用getBeanFactory将BeanFactory返回。至此BeanFactory刷新完成。

这里其实主要做了两件事情,BeanFactory的刷新前准备,和实际两种不同方式在BeanFactory刷新时的不同方式。