XmlBeanFactory容器创建
- 测试代码
//省略get/set
public class MyTestBean {
private String testStr = "testStr";
}
//配置
<bean id="myTestBean" scope="singleton" class="com.bean.MyTestBean" >
<property name="testStr" value="haha" />
</bean>
//这里先把classpath下的资源文件读取到resource
Resource resource = new ClassPathResource("beanFactoryTest.xml");
//容器的创建
BeanFactory beanFactory = new XmlBeanFactory(resource);
MyTestBean myTestBean = (MyTestBean) beanFactory.getBean("myTestBean");
- 先看时序图
时序图中对xmlbeanFactory的逻辑顺序一目了然 - xmlbeanFactory解析
public class XmlBeanFactory extends DefaultListableBeanFactory {
private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);
public XmlBeanFactory(Resource resource) throws BeansException {
this(resource, null);
}
public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {
super(parentBeanFactory);
this.reader.loadBeanDefinitions(resource);
}
}
这里spring定义了一个XmlBeanDefinitionReader 来加载资源,继续跟进代码
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
return loadBeanDefinitions(new EncodedResource(resource));
}
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
Assert.notNull(encodedResource, "EncodedResource must not be null");
if (logger.isInfoEnabled()) {
logger.info("Loading XML bean definitions from " + encodedResource.getResource());
}
Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
if (currentResources == null) {
currentResources = new HashSet<EncodedResource>(4);
this.resourcesCurrentlyBeingLoaded.set(currentResources);
}
if (!currentResources.add(encodedResource)) {
throw new BeanDefinitionStoreException(
"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
}
try {
InputStream inputStream = encodedResource.getResource().getInputStream();
try {
InputSource inputSource = new InputSource(inputStream);
if (encodedResource.getEncoding() != null) {
inputSource.setEncoding(encodedResource.getEncoding());
}
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
}
finally {
inputStream.close();
}
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(
"IOException parsing XML document from " + encodedResource.getResource(), ex);
}
finally {
currentResources.remove(encodedResource);
if (currentResources.isEmpty()) {
this.resourcesCurrentlyBeingLoaded.remove();
}
}
}
这里比较啰嗦,其实就一句话
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
其他都是处理编码,IO,以及一些异常的东西,继续
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
try {
Document doc = doLoadDocument(inputSource, resource);
return registerBeanDefinitions(doc, resource);
}catch(){
//异常部分省略了
}
}
到这里我们大致就清楚了,其实 XmlBeanDefinitionReader 加载xml文件中的内容就做了两件事
1.读取资源文件转换成 document
2.注册文档中的bean,也就是xml配置文件中的bean