Spring IOC-XmlBeanFactory如何加载xml及如何存储转换后的信息
来源:互联网 发布:淘宝账号自助开通网址 编辑:程序博客网 时间:2024/05/16 04:35
本文主要介绍我们定义的xml配置文件是怎样被Spring加载封装到bean工厂的。
我们写代码使用Spring的IOC通常是这样的:
Resource resource=new FileSystemResource("benas-config.xml"); BeanFactory factory=new XmlBeanFactory(resource); HelloBean hello=(HelloBean)factory.getBean("helloBean"); System.out.println(hello.getHelloWord());
配置文件通常是这样的
<bean id="helloBean" class="spring2.HelloBean"> <property name="helloWord"> <value>hello</value> </property> </bean></beans>
那么我们就直接看底层代码是怎么实现的,转到XmlBeanFactory中,在这个类构造的时候就会去读取我们传入的xml文件,像这样:
public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException { super(parentBeanFactory); this.reader.loadBeanDefinitions(resource);}
那么我们自然转到XmlBeanDefinitionReader类中的实现代码:
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException { try { //转换为输入流 InputStream inputStream = encodedResource.getResource().getInputStream(); try { //构造InputSource InputSource inputSource = new InputSource(inputStream); if (encodedResource.getEncoding() != null) { inputSource.setEncoding(encodedResource.getEncoding()); } //把xml中的bean的定义解析出来 return doLoadBeanDefinitions(inputSource, encodedResource.getResource()); } finally { inputStream.close(); } }
转到doLoadBeanDefinitions(InputSource inputSource, Resource resource)中,主要代码如下:
………………try { int validationMode = getValidationModeForResource(resource); //调用[com.sun.org.apache.xerces.internal //.jaxp.DocumentBuilderImpl.parse(inputSource)]解析为Document对象 Document doc = this.documentLoader.loadDocument( inputSource, getEntityResolver(), this.errorHandler, validationMode, isNamespaceAware()); return registerBeanDefinitions(doc, resource); } ………………
在转到registerBeanDefinitions方法:
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException { BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader(); documentReader.setEnvironment(this.getEnvironment()); int countBefore = getRegistry().getBeanDefinitionCount(); //注册当前解析到的bean到工厂,注意这里会初始化“读环境”,初始化换进过的时候会将当前的beanFactory的对象引用传入,这样以后这个环境里就维持了一个到工厂的引用 documentReader.registerBeanDefinitions(doc, createReaderContext(resource));//在这里报错 return getRegistry().getBeanDefinitionCount() - countBefore;//DefaultBeanDefinitionDocumentReader }
注意这里的BeanDefinitionDocumentReader对象实际为DefaultBeanDefinitionDocumentReader(作用完成bean的定义读取和封装到bean工厂),然后看这个类:
public class DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocumentReader { protected void doRegisterBeanDefinitions(Element root) { preProcessXml(root); //实际的解析过程 parseBeanDefinitions(root, this.delegate); postProcessXml(root); } }
然后我们在把代码定位到parseBeanDefinitions方法,因为要贴的代码有点多,这里就截图了:
图上注释说的很清楚,这个解析的过程是用Spring定义的一套标签的解析类来完成的,每一个标签都对应自己的解析类,这里要注意几个特殊的标签,是没有解析类的,它们是alias、name、import和bean,对于这四个标签,Spring直接调用在DefaultBeanDefinitionDocumentReader中的方法解析。
具体解析过程我们以标签为例说明(最终的解析封装过程在BeanDefinitionParserDelegate类中)。
我们看到一些列的解析,最终构造出了AbstractBeanDefinition类,就是说bean工厂在读取配置文件之后是转换为了一系列的AbstractBeanDefinition类,然后在工厂会判断一个bean定义的是不是单例的,如果是单例的那么就会实例化,如果不是单例的,是发生在用户第一次请求的时候实例化。
- Spring IOC-XmlBeanFactory如何加载xml及如何存储转换后的信息
- Spring如何利用XmlBeanFactory类加载bean的配置文件?
- spring的applicationContext.xml如何自动加载
- Spring是如何加载Xml文件的
- spring 如何加载applicationContext.xml
- spring xmlbeanfactory加载活动图
- Spring源码学习IOC(2):XmlBeanFactory导读
- Spring - 如何实现IOC
- Spring IOC如何运行
- Spring是如何加载XML文件中的标签的
- .net 将字典数据转换成xml 字符串, 以及传参至存储过程后如何取值
- Spring如何实现IOC与AOP的
- Spring如何实现IOC与AOP的
- 如何理解Spring的IoC和DI
- Spring如何实现IOC与AOP的
- Spring如何实现IOC与AOP的
- Spring如何实现IOC与AOP的
- Spring如何实现IOC与AOP的
- undefined reference to 'pthread_create'问题解决
- 一致性哈希和负载均衡
- android 实用代码
- 本地搭建nuget服务器
- 一些关于socket的好的文章记载
- Spring IOC-XmlBeanFactory如何加载xml及如何存储转换后的信息
- Android 4.4 终成主流,最新安卓版本比例调查结果出炉
- 笔记
- 算法实践——数独的基本解法
- 计组的那些坑
- 【Leetcode Algorithm】Merge Two Sorted Lists
- Android动画之图片动画
- Xcode的报错崩溃 - unrecognized selector sent to instance
- 如何修改 VC6.0 4.0 2010 打印预览界面上的文字