原本这章是要解析prepareRefresh中的这段代码的,但是没有找到earlyApplicationListeners对象在哪里应用了,查了下资料这部分逻辑应该是在prepareRefresh阶段出触发的,所以这里先跳过:
// 这个暂时不知道啥意思,我估计要往后面看才能明白
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
else {
// Reset local application listeners to pre-refresh state.
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
// Allow for the collection of early ApplicationEvents,
// to be published once the multicaster is available...
this.earlyApplicationEvents = new LinkedHashSet<>();
那么继续,之后就是refresh方法的obtainFreshBeanFactory方法的解析了:
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
该方法具体内容如下:
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
return getBeanFactory();
}
首先解析refreshBeanFactory方法,具体内容如下:
createBeanFactorycreateBeanFactory@Override
protected final void refreshBeanFactory() throws BeansException {
// 如果bean工厂不等于空则销毁bean工厂
// 判断bean工厂是否不等于空,如果不等于则销毁bean工厂
if (hasBeanFactory()) {
// 这个方法我看了下,其实就是对工厂的各大容器进行clear方法的调用,实在想了解,可以在下面评论,我带大家看一看
// 不讲解的原因还有一个,由于是第一次创建工厂所以这里的工厂对象并不会有具体的实例,也就不会进入这个判断,我debug试过了
destroyBeans();
// 关闭bean工厂,不解析,原因同上
closeBeanFactory();
}
try {
// 创建DefaultListableBeanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
loadBeanDefinitions(beanFactory);
this.beanFactory = beanFactory;
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
前半段内容不是很复杂,看注释,这里提一句,看我的文章一定要看注释!!!看注释!!!看注释!!!重要的话说三遍!!!!,接下来就是createBeanFactory方法的解析了:
DefaultListableBeanFactory beanFactory = createBeanFactory();
createBeanFactory方法其实就是创建了一个DefaultListableBeanFactory对象:
protected DefaultListableBeanFactory createBeanFactory() {
return new DefaultListableBeanFactory(getInternalParentBeanFactory());
}
这个对象调用了getInternalParentBeanFactory方法,这个方法判断是否是ConfigurableApplicationContext如果是,则使用getBeanFactory方法获取工厂对象,否则调用getParent:
@Nullable
protected BeanFactory getInternalParentBeanFactory() {
return (getParent() instanceof ConfigurableApplicationContext ?
((ConfigurableApplicationContext) getParent()).getBeanFactory() : getParent());
}
那么这里提出一个问题,为什么要做以下判断呢:
getParent() instanceof ConfigurableApplicationContext
要理解这里我们首先要注意一个关键字:instanceof,这个关键字需要注意,如果一个对象的实际类型是某个类的子类,那么使用instanceof判断该对象是否为这个类的实例时,结果会为true,例如:B继承了A ,如果用instanceof判断B是否是A类型,会返回true,所以这里判断的是两种情况:
- 属于ConfigurableApplicationContext的所有子类对象(ConfigurableApplicationContext是一个接口,依赖于子类的具体实现)
- 不属于ConfigurableApplicationContext的所有子类对象
好,了解了这点,我们才能更好的明白为什么要这么判断,那么那些工厂类不是ConfigurableApplicationContext的子类呢,注意这里说的是工厂类,那么我们就要了解Spring一共存在多少个工厂类实现,所以如何找到所有的工厂类呢?我们会发现Spring框架的设计都是从接口开始的,在Java一类面向对象的语言中,源码和代码的设计都有一个规律,就是一切源码从接口开始,这话说的有些绝对,但是至少大部分是,所以我们现在找的是BeanFactory接口,并找到其所有的实现,如图所示:

看了这张图我们会发现,BeanFactory接口下来和ConfigurableApplicationContext接口同级的并且没有继承ConfigurableApplicationContext有以下几个:
- ConfigurableListableBeanFactory
- AbstractBeanFactory
继续往下看,你会发现这两个类自成一派,和另一边毫无关系,并且最终都是指向了DefaultListableBeanFactory 这个类,那么这样就很清晰了,存在两种情况:
- ConfigurableApplicationContext及其子类
- DefaultListableBeanFactory 工厂类

那么再提出一个问题,为什么需要DefaultListableBeanFactory这个工厂类,不能用ConfigurableApplicationContext直接创建工厂么,这个问题我们再开一章,因为必须要解析清楚ConfigurableApplicationContext和DefaultListableBeanFactory这两个类的不同作用,预计东西可能有点儿多
1371

被折叠的 条评论
为什么被折叠?



