Spring-IOC源码解读2.1-BeanDefinition的Resource定位
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定位的更多相关文章
- Spring IoC源码解读——谈谈bean的几种状态
阅读Spring IoC部分源码有一段时间了,经过不断的单步调试和参阅资料,对Spring容器中bean管理有了一定的了解.这里从bean的几个状态的角度出发,研究下IoC容器. 一.原材料 Xml中 ...
- Spring IOC 源码分析
Spring 最重要的概念是 IOC 和 AOP,本篇文章其实就是要带领大家来分析下 Spring 的 IOC 容器.既然大家平时都要用到 Spring,怎么可以不好好了解 Spring 呢?阅读本文 ...
- spring IoC源码分析 (3)Resource解析
引自 spring IoC源码分析 (3)Resource解析 定义好了Resource之后,看到XmlFactoryBean的构造函数 public XmlBeanFactory(Resource ...
- Spring IoC源码解析之invokeBeanFactoryPostProcessors
一.Bean工厂的后置处理器 Bean工厂的后置处理器:BeanFactoryPostProcessor(触发时机:bean定义注册之后bean实例化之前)和BeanDefinitionRegistr ...
- Spring IoC源码解析之getBean
一.实例化所有的非懒加载的单实例Bean 从org.springframework.context.support.AbstractApplicationContext#refresh方法开发,进入到 ...
- Spring IoC 源码分析 (基于注解) 之 包扫描
在上篇文章Spring IoC 源码分析 (基于注解) 一我们分析到,我们通过AnnotationConfigApplicationContext类传入一个包路径启动Spring之后,会首先初始化包扫 ...
- Spring Ioc源码分析系列--Ioc源码入口分析
Spring Ioc源码分析系列--Ioc源码入口分析 本系列文章代码基于Spring Framework 5.2.x 前言 上一篇文章Spring Ioc源码分析系列--Ioc的基础知识准备介绍了I ...
- Spring Ioc源码分析系列--Ioc容器BeanFactoryPostProcessor后置处理器分析
Spring Ioc源码分析系列--Ioc容器BeanFactoryPostProcessor后置处理器分析 前言 上一篇文章Spring Ioc源码分析系列--Ioc源码入口分析已经介绍到Ioc容器 ...
- Spring Ioc源码分析系列--Ioc容器注册BeanPostProcessor后置处理器以及事件消息处理
Spring Ioc源码分析系列--Ioc容器注册BeanPostProcessor后置处理器以及事件消息处理 前言 上一篇分析了BeanFactoryPostProcessor的作用,那么这一篇继续 ...
- Spring Ioc源码分析系列--Bean实例化过程(一)
Spring Ioc源码分析系列--Bean实例化过程(一) 前言 上一篇文章Spring Ioc源码分析系列--Ioc容器注册BeanPostProcessor后置处理器以及事件消息处理已经完成了对 ...
随机推荐
- 自己开发的在线视频下载工具,基于Java多线程
比如这个在线视频: 我们可以正常播放,但是找不到下载按钮. 打开Chrome开发者工具,在Network标签页里能看到很多网络传输请求: 随便看一个请求的响应,发现类型为video,大小为500多k. ...
- OpenGL 渲染上下文-context
context理解 OpenGL在渲染的时候需要一个Context,这个Context记录了OpenGL渲染需要的所有信息,可以把它理解成一个大的结构体,它里面记录了当前绘制使用的颜色.是否有光照计算 ...
- KissXML的XPath选取问题
XMPPFramework用的XML解析库还是大神自己写的KissXML,有些人生下来就是让人仰望的,哎. 进入主题,如下一段XML: <paramsxmlns="namespace& ...
- 利用python实现整数转换为任意进制字符串
假设你想将一个整数转换为一个二进制和十六进制字符串.例如,将整数 10 转换为十进制字符串表示为 10 ,或将其字符串表示为二进制 1010 . 实现 以 2 到 16 之间的任何基数为参数: def ...
- JavaScript -- 语法和数据类型
前戏 前面学了HTML和CSS相关的知识,那JavaScript是做什么的呢?你在网页上看到的那些炫酷的特效都是通过JS来实现的,所以,想要开发一个逼格满满的web页面,JS是必须要会的 什么是Jav ...
- 原 荐 使用Spring Boot Actuator、Jolokia和Grafana实现准实时监控
原 荐 使用Spring Boot Actuator.Jolokia和[可视化]Grafana实现准实时监控. 监控系统: 日志- 基础处理 - 表格 - 可视化一体化解决方案. ...
- Xcode的Git管理
在Xcode中创建工程的时候,我们很容易的可以将新创建的工程添加到Git中,如图: 但是如果是本地已经有的工程,那该如何添加到Git中呢? 首先终端进入到该工程的目录. 然后: git init gi ...
- 自写小函数处理 javascript 0.3*0.2 浮点类型相乘问题
const reg = /^([-+]?)([0-9]+)\.([0-9]*)$/; // 判断是不是浮点数 const isFloat = function(number){ return reg. ...
- Linux-ngnix服务(二)
Nginx介绍 特性: 模块化设计,较好的扩展性 高可靠性 支持热部署:不停机更新配置文件,升级版本,更换日志文件 低内存消耗:10000个keep-alive连接模式下的非活动连接,仅需2.5M内存 ...
- 利用js实现图片展开与收缩
1.元素居中放大: 1>除了要改变元素的宽高以外,还要改变元素的定位(left,top),如果图片放大一倍,那么位移放大宽高的一半. 2>元素必须是定位的.所以,在css中设置为浮动布局, ...