Spring通过ResourceLoader来处理得到的Resource。在前面我们知道容器初始化是以refresh()方法为入口的,内部的实现首先准备上下文,然后通过obtainFreshBeanFactory()方法获取beanFactory,

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}

进入AbstractRefreshableApplicationContext类的refreshBeanFactory()方法:

protected final void refreshBeanFactory() throws BeansException {
//如果已经存在beanfactory则先销毁之后再重新创建
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
//通过createBeanFactory()方法创建一个Ioc容器供容器使用,可以看到这个容器的类型是DefaultListableBeanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
// 启动loadBeanDifinitions来载入BeanDifinition,因为有多种载入方式,这里通过一个抽象函数把具体的实现委托给子类来完成
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}

BeanDefinition的具体载入过程委托给了AbstractRefreshableApplicationContext的子类完成,我们测试代码中实现该逻辑的子类就是AbstractXMLApplicationContext类,进入loadBeanDefinitions()方法:

protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// 为指定的BeanFactory创建一个XmlBeanDefinitionReader
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); // 使用此上下文的资源加载环境配置BeanDefinitionReader,由于AbstartactXmlApplication继承了DefaultResourceLoader,所以这里的ResourceLoader传的是this
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this)); // Allow a subclass to provide custom initialization of the reader, then proceed with actually loading the bean definitions.
initBeanDefinitionReader(beanDefinitionReader);
loadBeanDefinitions(beanDefinitionReader);
}

上面的loadBeanDefinitions方法中设置了ResourceLoader对象用来定位Resource,由于AbstartactXmlApplicationContext继承自DefaultResourceLoader,所以该类本身就是一个加载器。Spring设计的时候解耦的非常好,实际上BeanDefinition的定位,读入,注册过程是分开进行的。我们看下DefaultResourceLoader是如何实现资源定位的,

public Resource getResource(String location) {
Assert.notNull(location, "Location must not be null");
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);
}
}
}

上面的getResourceByPath()方法会根据路径加载Resource对象

protected Resource getResourceByPath(String path) {
return new ClassPathContextResource(path, getClassLoader());
}

上面方法返回的是一个ClassPathContextResource对象,通过这个对象Spring就可以进行相关的I/O操作了。到这里我们就已经完成BeanDefinition的定位了。在BeanDefinition定位完成的基础上我们就可以通过返回的Resource对象进行BeanDefinition的载入了。

Spring-IOC源码解读2.1-BeanDefinition的Resource定位的更多相关文章

  1. Spring IoC源码解读——谈谈bean的几种状态

    阅读Spring IoC部分源码有一段时间了,经过不断的单步调试和参阅资料,对Spring容器中bean管理有了一定的了解.这里从bean的几个状态的角度出发,研究下IoC容器. 一.原材料 Xml中 ...

  2. Spring IOC 源码分析

    Spring 最重要的概念是 IOC 和 AOP,本篇文章其实就是要带领大家来分析下 Spring 的 IOC 容器.既然大家平时都要用到 Spring,怎么可以不好好了解 Spring 呢?阅读本文 ...

  3. spring IoC源码分析 (3)Resource解析

    引自 spring IoC源码分析 (3)Resource解析 定义好了Resource之后,看到XmlFactoryBean的构造函数 public XmlBeanFactory(Resource  ...

  4. Spring IoC源码解析之invokeBeanFactoryPostProcessors

    一.Bean工厂的后置处理器 Bean工厂的后置处理器:BeanFactoryPostProcessor(触发时机:bean定义注册之后bean实例化之前)和BeanDefinitionRegistr ...

  5. Spring IoC源码解析之getBean

    一.实例化所有的非懒加载的单实例Bean 从org.springframework.context.support.AbstractApplicationContext#refresh方法开发,进入到 ...

  6. Spring IoC 源码分析 (基于注解) 之 包扫描

    在上篇文章Spring IoC 源码分析 (基于注解) 一我们分析到,我们通过AnnotationConfigApplicationContext类传入一个包路径启动Spring之后,会首先初始化包扫 ...

  7. Spring Ioc源码分析系列--Ioc源码入口分析

    Spring Ioc源码分析系列--Ioc源码入口分析 本系列文章代码基于Spring Framework 5.2.x 前言 上一篇文章Spring Ioc源码分析系列--Ioc的基础知识准备介绍了I ...

  8. Spring Ioc源码分析系列--Ioc容器BeanFactoryPostProcessor后置处理器分析

    Spring Ioc源码分析系列--Ioc容器BeanFactoryPostProcessor后置处理器分析 前言 上一篇文章Spring Ioc源码分析系列--Ioc源码入口分析已经介绍到Ioc容器 ...

  9. Spring Ioc源码分析系列--Ioc容器注册BeanPostProcessor后置处理器以及事件消息处理

    Spring Ioc源码分析系列--Ioc容器注册BeanPostProcessor后置处理器以及事件消息处理 前言 上一篇分析了BeanFactoryPostProcessor的作用,那么这一篇继续 ...

  10. Spring Ioc源码分析系列--Bean实例化过程(一)

    Spring Ioc源码分析系列--Bean实例化过程(一) 前言 上一篇文章Spring Ioc源码分析系列--Ioc容器注册BeanPostProcessor后置处理器以及事件消息处理已经完成了对 ...

随机推荐

  1. php随机生成国内ip地址

    获得一个国家所有ip段,随机生成国内ip地址的缩水实现.注意:  $ip_long数组中后5个值在64位系统中可能是错误的(下面代码中  $ip_long 数组的后五个值在32位系统中为负数,64位系 ...

  2. MVC视图特性

    在主界面的视图中可以使用viewdata,引用主界面的分布视图界面也可以调用主界面的分部视图,但是分部视图不可以定义viewdata并使用 例子如下: // // GET: /Home/ public ...

  3. gendiff - 致力于创建无错的 diff 文件的工具

    SYNOPSIS gendiff <directory> <diff-extension> DESCRIPTION gendiff 是一个简单的脚本,目标是根据单一的目录生成一 ...

  4. IjkPlayer播放器秒开优化以及常用Option设置

    https://blog.csdn.net/shareus/article/details/78585260 ijkplayer点播和直播视频 问题 解决及优化  https://blog.csdn. ...

  5. iPhone Scrollbars with iScroll

    Since we've had web browsers and JavaScript, we've been intent on replacing native browser functiona ...

  6. 使用Spring AOP实现业务依赖解耦

    Spring IOC用于解决对象依赖之间的解耦,而Spring AOP则用于解决业务依赖之间的解耦: 统一在一个地方定义[通用功能],通过声明的方式定义这些通用的功能以何种[方式][织入]到某些[特定 ...

  7. 微信开发 access_token 数量限制问题

    微信对access_token的请求有数量限制, 如果用户量特别多的话, access_token  可能会不够用 两种方案: 1.  access_token 加入缓存并设置2小时的失效时间,每次从 ...

  8. JS 绘制心形线

    JS 绘制心形线 <!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> < ...

  9. keypoint && DMatch

    下面单独介绍KEYPOINT 与DMatch的内在联系 std::vector<cv::Point2f> points1, points2; for (std::vector<cv: ...

  10. HDU 3790 (最短路 + 花费)

    题意: 给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的. #include<bits/stdc ...