BeanDefinition的Resource定位——3
1.我们重点看看AbstractRefreshableApplicationContext的refreshBeanFactory方法的实现,这个refreshBeanFactory被FileSystemXmlApplicationContext构造函数中的refresh调用。在这个方法中,通过createBeanFactory构建了一个IoC容器供ApplicationContext使用。这个IoC容器就是我们前面提到过的DefaultListableBeanFactory,同时,它启动了loadBeanDefinitions来载入BeanDefinition,这个过程和前面以编程的方式来使用IoC容器(XmlBeanFacoty)的过程非常类似。
protected final void refreshBeanFactory() throws BeansException {
// 这里判断,如果已经建立了BeanFactory,则销毁并关闭该BeanFactory
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
// 这里是创建并设置持有的DefaultListableBeanFactory的地方
// 同时调用loadBeanDefinitions载入BeanDefinition的信息
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);
}
}
AbstractRefreshableApplicationContext对容器的初始化
// 这就是在上下文中创建DefaultListableBeanFactory的地方,而getInternalParentBeanFacoty()
// 的具体实现可以
// 查看AbstractApplicationContext中的实现,会根据容器已有的双亲IoC容器的信息来生成
// DefaultListableBeanFactory的双亲IoC容器
protected DefaultListableBeanFactory createBeanFactory() {
return new DefaultListableBeanFactory(getInternalParentBeanFactory());
}
createBeanFactory
// 这里是使用BeanDefinitionReader载入Bean定义的地方,因为允许有多种载入方式,虽然用得
// 最多的事XML定义的形式,这里通过一个抽象函数把具体的实现委托给子类来完成
protected abstract void loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
throws BeansException, IOException;
loadBeanDefinitions
// 对于取得Resource的具体过程,我们可以看看DefaultResourceLoader是怎样完成的
public Resource getResource(String location) {
Assert.notNull(location, "Location must not be null");
//
if (location.startsWith("/")) {
return getResourceByPath(location);
}
else if (location.startsWith(CLASSPATH_URL_PREFIX)) {
return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader());
}
else {
try {
// Try to parse the location as a URL...
URL url = new URL(location);
return new UrlResource(url);
}
catch (MalformedURLException ex) {
// No URL -> resolve as resource path.
return getResourceByPath(location);
}
}
}
getResource
2.前面我们看到的getResourceByPath会被子类FileSystemXmlApplicationContext实现,这个方法返回的是一个FileSystemResource对象,通过这个对象,Spring可以进行相关的I/O操作,完成BeanDefinition的定位。分析到这里已经一目了然,它实现的就是对path进行解析,然后生成一个FileSystemResource对象并返回,代码清单如下所示。
protected Resource getResourceByPath(String path) {
if (path != null && path.startsWith("/")) {
path = path.substring(1);
}
return new FileSystemResource(path);
}
FileSystemXmlApplicationContext生成FileSystemResource对象
3.如果是其他的ApplicationContext,那么会对应生成其他种类的Resource,比如ClassPathResource、ServletContextResource等。
4.关于Spring中Resource的种类,可以在图1的Resource类的继承关系中了解。作为接口Resource定义了许多与I/O相关的操作,这些操作也都可以从图1种的Resource的接口定义中看到。这些接口对不同的Resource实现代表着不同的意义,是Resource的实现需要考虑的。Resource接口的实现在Spring中的设计如图1所示。

图1 Resource的定义和继承关系
5.从图1中我们可以看到Resource的定位和它的继承关系,通过对前面的实现原理的分析,我们以FileSystemXmlApplicationContext的实现为例子,了解Resource定位问题的解决方案,即以FileSystem方式存在的Resource的定位实现。
6.在BeanDefinition定位完成的基础上,就可以通过返回的Resource对象来进行BeanDefinition的载入了。
7.在定位过程完成以后,为BeanDefinition的载入创造了I/O操作的条件,但是具体的数据还没有开始读入。这些数据的读入将在下面的BeanDefinition的载入和解析中来完成。
8.任然以水桶为例子,这里就像用水桶去打水,要先找到水源。这里完成对Resource的定位,就类似于水源已经找到了,下面就是打水的过程了,类似于把找到的水装到水桶里的过程。找水不简单,但是与打水相比,我们发现打水更需要技巧。
BeanDefinition的Resource定位——3的更多相关文章
- Spring源码解析(二)BeanDefinition的Resource定位
IOC容器的初始化过程主要包括BeanDefinition的Resource定位.载入和注册.在实际项目中我们基本上操作的都是ApplicationContex的实现,我们比较熟悉的ClassPath ...
- BeanDefinition的Resource定位
1.以编程的方式使用DefaultListableBeanFactory时,首先定义一个Resource来定位容器使用的BeanDefiniton.这时使用的是ClassPathResource,这意 ...
- IOC容器初始化——BeanDefinition的Resource定位
以编程的方式使用DefaultListableBeanFactory时,首先定义一个Resource来定位容器使用的BeanDefinition.这是使用的是ClassPathResource,意味着 ...
- BeanDefinition的Resource定位——2
1.FileSystemXmlApplicationContext的实现 public class FileSystemXmlApplicationContext extends AbstractXm ...
- Resource 定位、BeanDefinition 的载入和解析,BeanDefinition 注册。
在前文提过,IOC 容器的初始化过程分为三步骤:Resource 定位.BeanDefinition 的载入和解析,BeanDefinition 注册. Resource 定位.我们一般用外部资源来描 ...
- 【初探Spring】------Spring IOC(三):初始化过程---Resource定位
我们知道Spring的IoC起到了一个容器的作用,其中装得都是各种各样的Bean.同时在我们刚刚开始学习Spring的时候都是通过xml文件来定义Bean,Spring会某种方式加载这些xml文件,然 ...
- Spring IOC容器的初始化—(一)Resource定位
前言 上一篇博文“ Spring IOC是怎样启动的 ”中提到了refresh()方法,这个就是容器初始化的入口.容器初始化共有三个阶段: 第一阶段:Resource定位 第二阶段:BeanDefin ...
- Spring-IOC源码解读2.1-BeanDefinition的Resource定位
Spring通过ResourceLoader来处理得到的Resource.在前面我们知道容器初始化是以refresh()方法为入口的,内部的实现首先准备上下文,然后通过obtainFreshBeanF ...
- BeanDefinition的载入和解析
1.在完成对代表BeanDefinition的Resource定位的分析后,下面来了解整个BeanDefinition信息的载入过程. 2.对IoC容器来说,这个载入过程,相当于把定义的BeanDef ...
随机推荐
- 微信lbs---返回两个经纬度坐标点的距离
微信开发:lbs附近的商家,在数据库里记录商家的坐标,lbs设置里管理搜索半径,查询的时候,查询 客户当前坐标的半径内的所有商家列表.个人喜欢不一样,我选择了执行sql ,毕竟效果高点.微信开发必须得 ...
- 在android market发布个人免费应用的步骤
写了一段时间的android应用了,只是在自己手机上面安装. 上周申请了android developer,需要一次性25美元的程序开发注册费用.费用需要用google checkout,所以还要先申 ...
- Qt动画效果的实现,QPropertyAnimation
Qt动画架构中的主要类如下图所示: 动画框架由基类QAbstractAnimation和它的两个儿子QVariantAnimation和QAnimationGroup组成.QAbstractAnima ...
- nginx1.4.6+php5.5.11+mysql5.6.17+mecache+opcache
要用到的软件:libiconv-1.13.tar.gz libmcrypt-2.5.8.tar.gz mcrypt-2.6.8.tar.gz mhash-0.9.9.9.tar.gz memcache ...
- Design Mode 之 结构模式
这里我们主要介绍7种结构型模式:适配器模式.装饰模式.代理模式.外观模式.桥接模式.组合模式.享元模式.其中对象的适配器模式是各种模式的起源,我们看下面的图: B1.适配器模式(Adapter) 模式 ...
- solr 竞价排行
在理想的情况下,搜索引擎只返回与用户查询相关的文档.而在现实的查询中,编辑(没发现更合适的表达)通常需要指定特定文档在搜索结果中的特定位置.这样做有很多原因.或许 “置顶” 的文档就是最好的查询结果. ...
- SQL中VARCHAR与NVARCHAR存储区别
DATALENGTH 与LEN的查询区别 插入结果 总结:DATALENGTH计算字节长度,LEN计算字符串长度 VARCHAR(2)是指允许存取字节长度小于或等于2的字符串 NVA ...
- Java中transient有何作用?
transient关键字用来防止序列化域.如果一个引用类型被transient修饰,则其反序列化的结果是null.基本类型则为0.如果引用类型时不可序列化的类,则也应该使用transient修饰,它在 ...
- iOS - UI - UIPageControl
1.UIPageControl 分页控件 //分页控件初始化 UIPageControl * pageControl = [[UIPageControl alloc] init]; //分页页数 pa ...
- request.getHeader("Referer")理解【转载】
request.getHeader("Referer")用于获取来源页地址,但有时却为空值,这是怎么回事.原因如下: getHeader("Referer")要 ...