您的位置:首页 > 编程语言 > Java开发

从小白的角度看Spring核心流程概览(XML版)- 容器初始化第三章-创建BeanFactory 3ff8

2018-09-24 16:02 906 查看
#本章我们来看看Spring的BeanFactory是如何被创建的
##1、方法概览
入口:AbstractApplicationContext类refresh方法264行:

ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
// 真正刷新BeanFactory的方法
this.refreshBeanFactory();
// 返回BeanFactory
return this.getBeanFactory();
}

###2.1、刷新BeanFactory

//真正调用的是AbstractRefreshableApplicationContext的refreshBeanFactory方法
protected final void refreshBeanFactory() throws BeansException {
//判断是否已经存在BeanFactory,如果存在就销毁and关闭
if(this.hasBeanFactory()) {
this.destroyBeans();
this.closeBeanFactory();
}
try {
// 真正创建BeanFactory的方法
DefaultListableBeanFactory beanFactory = this.createBeanFactory();
// 给BeanFactory设置一个id,怎么设置的自己看~
beanFactory.setSerializationId(this.getId());
// 定制BeanFactory
this.customizeBeanFactory(beanFactory);
// 加载Bean的Definition解析器
this.loadBeanDefinitions(beanFactory);
// 下面就是将创建出来的BeanFactory保存起来
Object var2 = this.beanFactoryMonitor;
synchronized(this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
} catch (IOException var5) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var5);
}
}

####2.1.1、创建BeanFactory

//AbstractRefreshableApplicationContext第103行
protected DefaultListableBeanFactory createBeanFactory() {
//创建并返回一个DefaultListableBeanFactory工厂,其中参数是他的父工厂
return new DefaultListableBeanFactory(this.getInternalParentBeanFactory());
}
//AbstractApplicationContext第725行,这里注意AbstractApplicationContext是AbstractRefreshableApplicationContext的父类,而这段逻辑对于所有上下文都管用,所以卸载这(后面这句话是我瞎猜的~)
protected BeanFactory getInternalParentBeanFactory() {
// 判断当前上下文是否有父上下文,如果有就返回回去。当然这里是没有的,在Spring-MVC里面的话就会有了~这样看来工厂之间也有链路关系额。以前都不知道
return (BeanFactory)(this.getParent() instanceof ConfigurableApplicationContext?((ConfigurableApplicationContext)this.getParent()).getBeanFactory():this.getParent());
}

####2.1.2、定制BeanFactory

//AbstractRefreshableApplicationContext第725行
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
//如果 允许bean定义重写 有值,则设置对于的值,这里默认没有,不过你要是使用事务的话,就会有了。
if(this.allowBeanDefinitionOverriding != null) {
beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding.booleanValue());
}
//如果 允许循环引用 有值,则设置对于的值,这里默认也没有。
if(this.allowCircularReferences != null) {
beanFactory.setAllowCircularReferences(this.allowCircularReferences.booleanValue());
}

}

####2.1.3、加载DeFinition解析器

//这里实际调用的是AbstractXmlApplicationContext的方法,如果你是Annotation版的,那么走的就是Annotation版的了,到时候再说- -
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
//创建一个XmlBeanDefinition的解析器
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
// 设置系统属性
beanDefinitionReader.setEnvironment(this.getEnvironment());
// 设置资源加载器
beanDefinitionReader.setResourceLoader(this);
// 设置实体解析器
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
// 初始化BeanDefinitionReader解析器
this.initBeanDefinitionReader(beanDefinitionReader);
// 加载BeanDefinitions
// 大内容,单独分析
this.loadBeanDefinitions(beanDefinitionReader);
}

###2.2、返回BeanFactory

//真正调用的是AbstractRefreshableApplicationContext的getBeanFactory方法
//就是将上一步创建的BeanFactory返回回去。
public final ConfigurableListableBeanFactory getBeanFactory() {
Object var1 = this.beanFactoryMonitor;
synchronized(this.beanFactoryMonitor) {
if(this.beanFactory == null) {
throw new IllegalStateException("BeanFactory not initialized or already closed - call 'refresh' before accessing beans via the ApplicationContext");
} else {
return this.beanFactory;
}
}
}

#总结
截至到现在,除了加载BeanDefinitions没有讲以外(其实是我自己也还没开始看....),BeanFactory的创建过程已经完全结束。
首先spring会设置一堆乱七八糟的东西,然后定位在XML文件的位置,并且保存起来。这就是整个流程的第一步,资源定位。马上我们就要开始第二步,资源的加载了~下期见~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Spring
相关文章推荐