#博学谷IT学习技术支持#
我们继续来看spring ioc 的refresh方法
obtainFreshBeanFactory 方法
//在这个阶段进行xml配置文件的解析,加载beanDefinitions
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
spring在启动是,会现将xml配置文件中配置的bean信息加载为beanDefinition。这个加载操作就是在
obtainFreshBeanFactory这个方法中进行的。
看下方法内容:
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
//刷新BeanFactory
refreshBeanFactory();
return getBeanFactory();
}
refreshBeanFactory
继续跟进refreshBeanFactory方法
protected final void refreshBeanFactory() throws BeansException {
// 判断beanFactory是否为空,空为false
if (hasBeanFactory()) {
// 如果不为空,则将beanFactory中的Beans都销毁
// 这里兴趣的可以跟进看下
destroyBeans();
// 如果存在beanFactory,则将beanFactory设置为null
closeBeanFactory();
}
try {
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
//自定义BeanFactory,包含是否允许BeanDefinition重写和是否允许循环依赖
customizeBeanFactory(beanFactory);
loadBeanDefinitions(beanFactory);
this.beanFactory = beanFactory;
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
这里是AbstractRefreshableApplicationContext类中的方法实现。
其中主要做了两个操作
1.初始化beanFactory:
beanFactory的初始化主要在createBeanFactory
方法中进行
在beanFactory初始化时,会设置parentBeanFactory,即父级beanFactory,如果没有,则为null。
customizeBeanFactory(beanFactory)
这个方法可有子类自行扩展,定制话beanFactory.
AbstractRefreshableApplicationContext类中,主要是两个参数:
if (this.allowBeanDefinitionOverriding != null) {
// 1.是否允许beanDefinition重写
beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
// 2.是否允许循环引用 这个参数主要用于后面在bean创建时是否允许循环依赖
// 关于循环依赖,后面在bean的创建过程会讲解
if (this.allowCircularReferences != null) {
beanFactory.setAllowCircularReferences(this.allowCircularReferences);
}
2.加载BeanDefinitions
loadBeanDefinitions(beanFactory);
这个方法显而易见就是加载BeanDefinitions的方法了
我们跟进下,默认实现在AbstractXmlApplicationContext类中
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
// 子类实现,初始化beanDefinitionReader属性
initBeanDefinitionReader(beanDefinitionReader);
loadBeanDefinitions(beanDefinitionReader);
}
1.XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
创建一个XmlBeanDefinitionReader类,并将beanFactory传入
将传入的beanFactory赋值给registry属性。
然后还创建了resourceLoader资源解析器和environment,后续会使用evnironment获取一些环境变量系统参数等配置
protected AbstractBeanDefinitionReader(BeanDefinitionRegistry registry) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
this.registry = registry;
if (this.registry instanceof ResourceLoader) {
this.resourceLoader = (ResourceLoader) this.registry;
}
else {
this.resourceLoader = new PathMatchingResourcePatternResolver();
}
if (this.registry instanceof EnvironmentCapable) {
this.environment = ((EnvironmentCapable) this.registry).getEnvironment();
}
else {
this.environment = new StandardEnvironment();
}
}
2.beanDefinitionReader.setEnvironment(this.getEnvironment()); beanDefinitionReader.setResourceLoader(this); beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
loadBeanDefinitions方法,又为beanDefinitionReader重新设置了三个属性。
其中setEntityResolve()是设置实体解析器,用于解析xml的dtd或者schema;
3.initBeanDefinitionReader(beanDefinitionReader);
可以由子类继续重写,初始化beanDefinitionReader属性
4.loadBeanDefinitions(beanDefinitionReader);
开始执行BeanDefinitions的加载操作。
到这里我们的obtainFreshBeanFactory()方法也就结束了。
不过核心的加载BeanDefinitions操作内容比较复杂,后续将分多章进行详细讲解