欢迎访问昆山宝鼎软件有限公司网站! 设为首页 | 网站地图 | XML | RSS订阅 | 宝鼎邮箱 | 后台管理


新闻资讯

MENU

软件开发知识

顾名思义即解 昆山软件定制开发 析Bean定义元素

点击: 次  来源:宝鼎软件 时间:2017-06-01

原文出处: 五月的仓颉

媒介

Spring设置文件读取流程原来是和http://www.cnblogs.com/xrq730/p/6285358.html一文放在一起的,这两天在看Spring自界说标签的时候,感受对Spring设置文件读取流程照旧研究得不足,因此将Spring设置文件读取流程部门从之前的文章拆出来单独成为一文。

为了看一下Spring设置文件加载流程,先界说一个bean.xml:

 <?xml version="1.0" encoding="UTF-8"?>
 <beans xmlns="http://www.springframework.org/schema/beans"
 	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 	xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

 	<bean id="beanPostProcessorBean" class="org.xrq.action.BeanPostProcessorBean" />

 	<bean id="beanFactoryPostProcessorBean" class="org.xrq.action.BeanFactoryPostProcessorBean" />

 	<bean id="multiFunctionBean" class="org.xrq.action.MultiFunctionBean" init-method="initMethod">
 		<property name="propertyA" value="abc" />
 	</bean> 
 </beans>

至于Bean是什么并不重要,有设置文件就够了。

Bean界说加载流程—-从Refresh到Bean界说加载前

首先看一下Bean加载前整个代码流程走向。Spring上下文刷新始于AbstractApplicationContext的refresh()要领:

public void refresh() throws BeansException, IllegalStateException {
     synchronized (this.startupShutdownMonitor) {
     // Prepare this context for refreshing.
     prepareRefresh();

     // Tell the subclass to refresh the internal bean factory.
     ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

     // Prepare the bean factory for use in this context.
     prepareBeanFactory(beanFactory);

         ...
 }

代码不全帖了,第7行的obtainFreshBeanFactory()要领进去:

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}

第2行的refreshBeanFactory()要领进去,它是AbstractApplicationContext的子类AbstractRefreshableApplicationContext中的要领:

@Override
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
   destroyBeans();
   closeBeanFactory();
 }
 try{
   DefaultListableBeanFactory beanFactory = createBeanFactory();
   beanFactory.setSerializationId(getId());
   customizeBeanFactory(beanFactory);
   loadBeanDefinitions(beanFactory);
   synchronized (this.beanFactoryMonitor) {
   this.beanFactory = beanFactory;
   }
 }
 catch (IOException ex) {
 throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
 }
}

首先第8行获取DefaultListableBeanFactory,然后执行第11行的要领,传入当前获取的BeanFactory,筹备加载Bean界说。BeanFactory中有存储了些什么数据在【Spring源码阐明】Bean加载流程概览一文中有画表格具体说明,看过表格的伴侣应该知道为什么第8行要获取的是DefaultListableBeanFactory而不是它的接口BeanFactory,因为Bean界说存储在Map<String, BeanDefinition>中,这个Map的位置就是在DefaultListableBeanFactory里,因此这里直接获取DefaultListableBeanFactory并作为参数层层向后传,加载完Bean界说后直接向Map<String, BeanDefinition>里put键值对。

看下loadBeanDefinitions要领,它是AbstractRefreshableApplicationContext子类AbstractXmlApplicationContext中的一个要领:

protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
    // Create a new XmlBeanDefinitionReader for the given BeanFactory.
    XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

    // Configure the bean definition reader with this context's
    // resource loading environment.
    beanDefinitionReader.setResourceLoader(this);
    beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

    // Allow a subclass to provide custom initialization of the reader,
    // then proceed with actually loading the bean definitions.
    initBeanDefinitionReader(beanDefinitionReader);
    loadBeanDefinitions(beanDefinitionReader);
}

第3行的XmlBeanDefinitionReader是Bean加载的焦点类,先构建出来,后头代码没什么值得看的,直接看第13行代码,传入XmlBeanDefinitionReader:

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
    Resource[] configResources = getConfigResources();
    if (configResources != null) {
        reader.loadBeanDefinitions(configResources);
    }
    String[] configLocations = getConfigLocations();
    if (configLocations != null) {
        reader.loadBeanDefinitions(configLocations);
    }
}