ClassPathResource res = new ClassPathResource("bean.xml");
DefaultListAbleFacttory dlaf = new DefaultListAbleFacttory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(dlaf);
reader.loadBeanDefinitions(res);
从上面编程的方式来说,如果要找到BeanDefiniton的定位,需要使用DefaultListAbleFactory,同时也是需要使用Resource接口的
在上面的是使用ClassPathResourcee这个类的,其实对资源的定位并不是有DefaultListAbleFacotory直接使用的,而是通过XmlBeanDefinitionReader来处理的
换一句话说就是DefaultListAbleFactory只是一个单纯的容器,需要为他匹配相应的Reader才能够使用它
从我们常用ApplicationContext 中的FileSystemXmlApplicationContext可以文件系统,ClassPathXmlApplicationContext 从classPath读取Resource , XmlWebApplicationContext
可以从web容器中载入resource
下面主要是从FileSystemXmlApplicationContext来讲述资源定位
FileSystemXmlApplicationContext已经通过继承AbstractApplicationContext具备了ResourceLoader读入以Resource定义的BeanDifinition的能力(具体的是指代DefaultResourceLoader这个接口的功能)
以下就是FileSystemXmlApplicaition的源代码BeanFactory系列的容器
public class FileSystemXmlApplicationContext extends AbstractXmlApplicationContext {
public FileSystemXmlApplicationContext() {
}
public FileSystemXmlApplicationContext(ApplicationContext parent) {
super(parent);
}
//configLocation包含的是BeanDifinition的路径
public FileSystemXmlApplicationContext(String configLocation) throws BeansException {
this(new String[]{configLocation}, true, (ApplicationContext)null);
}
//包含多个BeanDifinition的路径
public FileSystemXmlApplicationContext(String... configLocations) throws BeansException {
this(configLocations, true, (ApplicationContext)null);
}
public FileSystemXmlApplicationContext(String[] configLocations, ApplicationContext parent) throws BeansException {
this(configLocations, true, parent);
}
public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh) throws BeansException {
this(configLocations, refresh, (ApplicationContext)null);
}
//调用了refresh启动容器,并且载入beanDefinition
public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException {
super(parent);
this.setConfigLocations(configLocations);
if (refresh) {
this.refresh();
}
}
//通过文件路径获取resource
protected Resource getResourceByPath(String path) {
if (path != null && path.startsWith("/")) {
path = path.substring(1);
}
return new FileSystemResource(path);
}
}
具体实现的编程,就是通过Refresh()中调用了refreshBean()方法,在这个方法中同时又实用createBeanFactory创建一个容器,供给ApplicationContext使用,这个容器也就是我们常说的DefaultListAbleFacotry容器,同时它也可以使用loadBeanDefinitio来载入BeanDifinition,下面的refresh方法其实在new 对象时候已经启动了
其实涉及到资源的定位主要就是在AbstractRefreshBeanFacotoryContext中的getResourceLoader()方法吗,这个方法其实使用的就是DefaultResource方法
//DefaultResource,我去源码中去没有查询到该行源码
ResourceLoader resourceLoader = getResouirce() ;
//在上面这行代码上调用的
Url url = new Url(location);
return new UrlResource(url);
//说明就是利用io来获取resourcei资源定位
另外需要说明的就是getResourceByPath()会被子类FileSystemXmlApplicationContext实现的,返回的是FileSystemResource对象,通过这个对象可以实现相关的io操作,万完成BeanDifinition的定位
//注意看下面实现的代码
protected Resource getResourceVypath(String path){
if(path != null && path.startWith("/")){
path = path.substring(1);
}
return new FileSystemResource(path);
}
主要的io操作有
getUrl(); getFileName(); isOpen();v isReadAble();
总结:
具体的代码思路流程
1:以FileSystem方式存在的Resource的定位实现
2:在BeanDefinition定位完成的基础上,通过返回的Resource来进行BeanDefinition
3:在定位过程完成之后,为BeanDifinition的载入创造i/o操作条件