BeanDefinition的Resource定位——3

1.我们重点看看AbstractRefreshableApplicationContextrefreshBeanFactory方法的实现,这个refreshBeanFactoryFileSystemXmlApplicationContext构造函数中的refresh调用。在这个方法中,通过createBeanFactory构建了一个IoC容器供ApplicationContext使用。这个IoC容器就是我们前面提到过的DefaultListableBeanFactory,同时,它启动了loadBeanDefinitions来载入BeanDefinition,这个过程和前面以编程的方式来使用IoC容器(XmlBeanFacoty)的过程非常类似。

 1 protected final void refreshBeanFactory() throws BeansException {
 2         // 这里判断,如果已经建立了BeanFactory,则销毁并关闭该BeanFactory
 3         if (hasBeanFactory()) {
 4             destroyBeans();
 5             closeBeanFactory();
 6         }
 7         // 这里是创建并设置持有的DefaultListableBeanFactory的地方
 8         // 同时调用loadBeanDefinitions载入BeanDefinition的信息
 9         try {
10             DefaultListableBeanFactory beanFactory = createBeanFactory();
11             beanFactory.setSerializationId(getId());
12             customizeBeanFactory(beanFactory);
13             loadBeanDefinitions(beanFactory);
14             synchronized (this.beanFactoryMonitor) {
15                 this.beanFactory = beanFactory;
16             }
17         }
18         catch (IOException ex) {
19             throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
20         }
21     }

AbstractRefreshableApplicationContext对容器的初始化

1 // 这就是在上下文中创建DefaultListableBeanFactory的地方,而getInternalParentBeanFacoty()
2     // 的具体实现可以
3     // 查看AbstractApplicationContext中的实现,会根据容器已有的双亲IoC容器的信息来生成
4     // DefaultListableBeanFactory的双亲IoC容器
5     protected DefaultListableBeanFactory createBeanFactory() {
6         return new DefaultListableBeanFactory(getInternalParentBeanFactory());
7     }

createBeanFactory

1 // 这里是使用BeanDefinitionReader载入Bean定义的地方,因为允许有多种载入方式,虽然用得
2     // 最多的事XML定义的形式,这里通过一个抽象函数把具体的实现委托给子类来完成
3     protected abstract void loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
4             throws BeansException, IOException;

loadBeanDefinitions

 1 // 对于取得Resource的具体过程,我们可以看看DefaultResourceLoader是怎样完成的
 2     public Resource getResource(String location) {
 3         Assert.notNull(location, "Location must not be null");
 4         //
 5         if (location.startsWith("/")) {
 6             return getResourceByPath(location);
 7         }
 8         else if (location.startsWith(CLASSPATH_URL_PREFIX)) {
 9             return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader());
10         }
11         else {
12             try {
13                 // Try to parse the location as a URL...
14                 URL url = new URL(location);
15                 return new UrlResource(url);
16             }
17             catch (MalformedURLException ex) {
18                 // No URL -> resolve as resource path.
19                 return getResourceByPath(location);
20             }
21         }
22     }

getResource

2.前面我们看到的getResourceByPath被子类FileSystemXmlApplicationContext实现,这个方法返回的是一个FileSystemResource对象,通过这个对象,Spring可以进行相关的I/O操作,完成BeanDefinition的定位。分析到这里已经一目了然,它实现的就是对path进行解析,然后生成一个FileSystemResource对象并返回,代码清单如下所示。

1 protected Resource getResourceByPath(String path) {
2         if (path != null && path.startsWith("/")) {
3             path = path.substring(1);
4         }
5         return new FileSystemResource(path);
6     }

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的定位,就类似于水源已经找到了,下面就是打水的过程了,类似于把找到的水装到水桶里的过程。找水不简单,但是与打水相比,我们发现打水更需要技巧。

时间: 2024-10-15 00:46:17

BeanDefinition的Resource定位——3的相关文章

BeanDefinition的Resource定位

1.以编程的方式使用DefaultListableBeanFactory时,首先定义一个Resource来定位容器使用的BeanDefiniton.这时使用的是ClassPathResource,这意味着Spring会在类路径中去寻找以文件形式存在的BeanDefinition信息. ClassPathResource res = new ClassPathResource("beans.xml"); 这里定义的Resource并不能由DefaultListableBeanFactor

IOC容器初始化——BeanDefinition的Resource定位

以编程的方式使用DefaultListableBeanFactory时,首先定义一个Resource来定位容器使用的BeanDefinition.这是使用的是ClassPathResource,意味着Spring会在类路径中去寻找以文件形式存在的BeanDefinition的信息. ClassPathResource res =new ClassPathResource('beans.xml'); 这里定义的Resource不能由DefaultListableBeanFactory直接使用,Sp

BeanDefinition的Resource定位——2

1.FileSystemXmlApplicationContext的实现 1 public class FileSystemXmlApplicationContext extends AbstractXmlApplicationContext { 2 3 /** 4 * Create a new FileSystemXmlApplicationContext for bean-style configuration. 5 * @see #setConfigLocation 6 * @see #s

Resource 定位、BeanDefinition 的载入和解析,BeanDefinition 注册。

在前文提过,IOC 容器的初始化过程分为三步骤:Resource 定位.BeanDefinition 的载入和解析,BeanDefinition 注册. Resource 定位.我们一般用外部资源来描述 Bean 对象,所以在初始化 IOC 容器的第一步就是需要定位这个外部资源.BeanDefinition 的载入和解析.装载就是 BeanDefinition 的载入.BeanDefinitionReader 读取.解析 Resource 资源,也就是将用户定义的 Bean 表示成 IOC 容器

【初探Spring】------Spring IOC(三):初始化过程---Resource定位

我们知道Spring的IoC起到了一个容器的作用,其中装得都是各种各样的Bean.同时在我们刚刚开始学习Spring的时候都是通过xml文件来定义Bean,Spring会某种方式加载这些xml文件,然后根据这些信息绑定整个系统的对象,最终组装成一个可用的基于轻量级容器的应用系统. Spring IoC容器整体可以划分为两个阶段,容器启动阶段,Bean实例化阶段.其中容器启动阶段蛀牙包括加载配置信息.解析配置信息,装备到BeanDefinition中以及其他后置处理,而Bean实例化阶段主要包括实

BeanDefinition的载入和解析

1.在完成对代表BeanDefinition的Resource定位的分析后,下面来了解整个BeanDefinition信息的载入过程. 2.对IoC容器来说,这个载入过程,相当于把定义的BeanDefinition在IoC容器中转化成一个Spring内部表示的数据结构的过程. 3.IoC容器对Bean的管理和依赖注入功能的实现,是通过对其持有的BeanDefinition进行各种相关操作来完成的. 4.这些BeanDefinition数据在IoC容器中通过一个HashMap来保持和维护.当然这只

Spring技术内幕——Spring Framework的IOC容器实现(二)

三.IOC容器的初始化过程 IOC容器的初始化时由前面介绍的refresh方法来启动的,这个方法标志着IOC容器的正式启动.这个启动包括BeanDefinition的Resource定位.载入和注册.下面我们将详细分析这三个实现过程,Spring把这三个过程分开,并使用不同的模块来完成,通过这样的设计让用户更加灵活的这三个过程进行剪裁和扩展,定义出最适合自己的IOC容器的初始化过程. 第一个过程: Resource定位过程,是指BeanDefinition的资源定位,他由ResourceLoad

Spring:源码解读Spring IOC原理

Spring IOC设计原理解析:本文乃学习整理参考而来 一. 什么是Ioc/DI? 二. Spring IOC体系结构 (1) BeanFactory (2) BeanDefinition 三. IoC容器的初始化 1. XmlBeanFactory(屌丝IOC)的整个流程 2. FileSystemXmlApplicationContext 的IOC容器流程 1.高富帅IOC解剖 2. 设置资源加载器和资源定位 3.AbstractApplicationContext的refresh函数载入

Spring IoC容器总结(未完)

在面向对象系统中,对象封装了数据和对数据的处理,对象的依赖关系常常体现在对数据和方法的依赖上.这些依赖关系可以通过把对象的依赖注入交给框架或IOC容器来完成,这种从具体对象手中交出控制的做法是非常有价值的,它可以在解耦代码的同时提高代码的可测试性. 在Spring中,IoC容器是实现这个模式的载体,它可以在对象生成或初始化时直接将数据注入到对象中,也可以通过将对象引用注入到对象数据域中的方式来注入对方法调用的依赖.setter注入和构造器注入是主要的注入方式. IoC容器系列的设计与实现:Bea