BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("applicationConfig.xml"));
MyBean myBean = (MyBean) beanFactory.getBean("myBean");
上面是一个最基础的spring的使用方式,简单的两行代码包含的逻辑是确是值得深究的.
首先通过传入一个classPathResource的对象.将这个对象传入beanFactory的构造器其中.我们跟如XMLBeanFactory代码中可以看到如下代码:
public XmlBeanFactory(Resource resource)throws BeansException {
this(resource, null);
}
public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory)throws BeansException {
super(parentBeanFactory);
this.reader.loadBeanDefinitions(resource);
}
可以看到,在XMLbeanFactory对象中使用了XMLBeanDefinitionReader,来进行解析XML文件,
我们可以看到调用了this.reader.loadBeanDefinitions(resource)来解析.
继续跟如这个方法之后可以看到更为复杂的逻辑:
public int loadBeanDefinitions(Resource resource)throws BeanDefinitionStoreException {
// new EncodeResource 将resource对象包装EncodeResource, 主要用来设置编码属性
return loadBeanDefinitions(new EncodedResource(resource));
}
这方法首先将传入的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 currentResources =this.resourcesCurrentlyBeingLoaded.get();
if (currentResources ==null) {
currentResources =new HashSet<>(4);
this.resourcesCurrentlyBeingLoaded.set(currentResources);
}
if (!currentResources.add(encodedResource)) {
throw new BeanDefinitionStoreException(
"Detected cyclic loading of " + encodedResource +" - check your import definitions!");
}
try {
// 从原始的resource对象中取到inputStream
InputStream inputStream = encodedResource.getResource().getInputStream();
try {
// 构造InputSource对象
InputSource inputSource =new InputSource(inputStream);
if (encodedResource.getEncoding() !=null) {
// 为inputResource设置编码
inputSource.setEncoding(encodedResource.getEncoding());
}
// 进入加载beanDefinitions方法,传入的资源是inputSource 和原本的Resource对象
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();
}
}
}
首先会在xmlBeandefinitionReader的属性中记录下已经加载的资源文件
然后从原始的resource对象中取到inputStream, inputStream有封装称了inputSource,这个对象是为了读取XML文件准备的,最后进入真正的逻辑核心部分
doLoadBeanDefition(inputResource, encodeResource.getResource());
明天继续!!!