spring IOC加载流程

看了网上、书上很多对于spring IOC容器加载过程的分析。大多都只是粗略的讲一下加载流程。其实这样也不错,简单粗暴。清晰记得之前和一个前辈交流时他说的一句话:什么设计模式、设计框架都是扯淡,能实现这个功能就是最好的。其实这样的说法是话走偏锋的,为什么要有各种框架、设计模式,主要还是因为没有它们不能够很好的实现功能。就比如说IOC容器加载中常用的FileSystemXmlApplicationContext,这个类到最顶层的BeanFactory接口,之间有8层集成实现关系。为什么只需要一个类行进工作,缺是存在了这么多的集成实现关系呢?其实是为了更好的拓展和兼容,为了更好的解耦。对于这些源码的阅读分析,如果只是在停留在看懂了实现流程的地步上,不会有太多的收获。
一、spring的总体框架:
1、spring的三个主要的部分,beans、context、core:
在这三个主要部分中的核心是什么呢?那就非beans莫属了。spring的核心就是把我们平时使用的对象配置文件化,而配置文件中的对象就是被解析为beans来供开发人员来使用的。要说一个spring是一个舞台剧,那么beans就是一个个演员,没有演员怎么来的舞台剧?bean在spring中的重要性可想而知。而context的作用就是封装一下beans。如果没有context的话,我们每次使用spring的编程模式就一定要使用编程式使用spring的ioc容器了,而有了context只有,使用spring的ioc容器变得简单了许多,可以使用声明式的方式了。那么core的作用是什么呢?其实core就是一个工具类,如果我们想要将其改名为utils其实都是可以的。
2、beans:·
BeanFactory是所有的bean工厂的父接口,bean工厂的继承实现关系很是错综复杂,其中的一条主线继承关系就如下图所示。BeanFactory中定义getBean()等基本方法。而HierachicalBeanFactrory主要是说明Bean工厂是可以继承实现的,所以其中定义了getParentBeanFactory()这个接口。而ConfigurableBeanFactory这个类就是我们常用的bean工厂了。
3、context:
ApplicationContext 是 Context 的顶级父类。如下图:
可以看到Application其实是继承自BeanFactory的。其就是对于BeanFactory环境的一个更好的整合。有了BeanFactory我们可以进行编程式Ioc,那么有了ApplicationContext之后我们就可以使用声明式Ioc了,Context对于各种类型的配置文件的兼容整合大大提升了使用者的使用效率。
Context 作为 Spring 的 Ioc 容器,基本上整合了 Spring 的大部分功能,或者说是大部分功能的基础。
二、容器加载流程:
1、首先看FileSystemApplicationContext这个context容器的使用过程中内部都做了什么:
a、 可以看到FileSystemApplicationContext的类继承关系如下图所示:
FileSystemApplicationContext之上还有AbstractApplicationContext抽象类等等,如此设计的原因就是为了灵活性、解耦的原因。AbstractApplicationContext中增加了context容器相对于beanFactory容器新增加的特性功能,之后AbstractXmlApplicationContext又增加了对于xml配置文件解析的一些特性方法。每一层继承实现的类,都是实现了职责功能的单一性。目前我接触到的类继承设计形式大部分都是一个接口、一个抽象类、一个实现类。如果考虑到拓展性和解耦兼容的话,就要实现多层继承,每一层有多个实现类,就比如AbstractXmlApplicationContet这一层,就有多个实现,有xml配置文件解析功能类,有web数据解析的功能类,等等。每一层的每个实现类都划分出单一职责。
b、FileSystemXmlApplicationContext解析xml配置文件载入IOC容器:
         流程图如下:
可以看到,真正对于配置文件的解析是在BeanDefinitionParserDelegate类中的parseBeanDefinitionElement方法来实现的。其中该方法的代码如下:
/**
* Parse the bean definition itself, without regard to name or aliases. May return
* {@code null} if problems occurred during the parsing of the bean definition.
*/
public AbstractBeanDefinition parseBeanDefinitionElement(
Element ele, String beanName, BeanDefinition containingBean) {

this.parseState.push(new BeanEntry(beanName));

String className = null;
if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
}

try {
String parent = null;
if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
parent = ele.getAttribute(PARENT_ATTRIBUTE);
}
AbstractBeanDefinition bd = createBeanDefinition(className, parent);

parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));

parseMetaElements(ele, bd);
parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
parseReplacedMethodSubElements(ele, bd.getMethodOverrides());

parseConstructorArgElements(ele, bd);
parsePropertyElements(ele, bd);
parseQualifierElements(ele, bd);

bd.setResource(this.readerContext.getResource());
bd.setSource(extractSource(ele));

return bd;
}
catch (ClassNotFoundException ex) {
error("Bean class [" + className + "] not found", ele, ex);
}
catch (NoClassDefFoundError err) {
error("Class that bean class [" + className + "] depends on not found", ele, err);
}
catch (Throwable ex) {
error("Unexpected failure during bean definition parsing", ele, ex);
}
finally {
this.parseState.pop();
}

return null;
}
(1)解析:可以看到parsePropertyElements()等方法就是对于配置文件中property属性的解析。解析到的元素放置在AbstractBeanDefinition中,而AbstractBeanDefinition由BeanDefinitionHolder来持有。
    (2)注册:得到了解析信息要怎么来使用呢,从我们平时根据beanName通过getBean()来获取到指定对象的方式,可以看到应该是由一个HashMap来持有的配置文件信息。所以接下来spring IOC做的事就是把解析得到的BeanDefinitionHolder中的信息注册到一个HashMap中去。注册是怎么做的呢?
  在DefaultBeanDefinitionDocumentReader中调用BeanDefinitionReaderUtils中的registerBeanDefinition()方法,最终是使用了DefaultListableBeanFactory这个BeanFactory工厂来最总实现了注册。
   (3)使用:最后就是如何使用了:通过getBean()方法来调用使用。
四、算了~~  本来还想继续详细写的,我认怂了~~  真的好费事!!!  有空继续补充吧。

转载于:https://www.cnblogs.com/shiru/p/5223961.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/573958.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

pytorch 模型可视化_【深度学习】高效使用Pytorch的6个技巧:为你的训练Pipeline提供强大动力...

作者:Eugene Khvedchenya 编译:ronghuaiyang导读只报告模型的Top-1准确率往往是不够的。将train.py脚本转换为具有一些附加特性的强大pipeline每一个深度学习项目的最终目标都是为产品带来价值。当然,我们想要最好的模型。什么是“最好的”…

c语言 %-20s,一次 Rust 和C语言的混搭

存在内存泄露extern crate libc;use libc::size_t;use libc::{FILE,c_char};use std::string;#[repr(C)]pub struct mntent {mnt_fsname :*mut c_char, /* 挂载的文件系统的名字 */mnt_dir :*mut c_char, /* 挂载点 */mnt_type :*mut c_char, /* 文件系统类型:ufs、…

KMP算法———模板

做出KMP字符串匹配算法心情也是好好哒&#xff0c;萌萌哒。 感谢黄学长&#xff0c;感谢栋栋&#xff01; #include<cstdio>#include<string>#include<iostream>using namespace std;int p[101];int main(){ string a,b; cin>>a>>b; int na.leng…

tstringlist怎么查看是否存在该数据_注意!研究生招生信息只公开1个月!应该怎么用?...

请注意&#xff01;全国硕士研究生招生信息公开平台&#xff08;以下简称“研招信息公开平台”&#xff09;已于2019年7月1日开放-2019年7月30日结束。招生信息怎么看&#xff1f;老师在线教你看懂研究生招生信息&#xff01;本篇目录&#xff1a;1.全国硕士研究生招生信息公开…

山东外贸职业学院王彩霞老师网上考试系统及c语言考试题库》,2015年山东外贸职业学院单招考试内容...

测试方式及内容1、夏季高考考生&#xff1a;文化考试、基本技能测试、面试(总分400分)(1)文化考试&#xff1a;考试形式为笔试&#xff0c;考试科目&#xff1a;语文、数学。两科一套卷子&#xff0c;分值为&#xff1a;语文100分、数学100分&#xff0c;总分200分&#xff0c;…

5.UiScrollable API 详细介绍

Tip&#xff1a; 1.扫动过程中如果界面停留在滚动条的中间部分会先回到起点再进行滚动 2.扫动过程中设置的步长长短决定划过内容的多少&#xff0c;步长越长滑过的内容就越少&#xff1b;步长越短划过的内容就越长 一、UiScrollable 类介绍 1.UiScrollable类说明 1&#xff09;…

delphi读取xml中的内容property name传递参数_Python 进阶知识全篇-XML 解析

什么是 XML&#xff1f;XML 指可扩展标记语言&#xff08;eXtensible Markup Language&#xff09;&#xff0c;标准通用标记语言的子集&#xff0c;是一种用于标记电子文件使其具有结构性的标记语言。 你可以通过本站学习 XML 教程XML 被设计用来传输和存储数据。XML 是一套定…

c语言getline读取一行命令行,如何从文件的特定行中获取getline()? C ++

这个问题非常不清楚。您如何确定具体线&#xff1f;如果是第n行&#xff0c;最简单的解决方案就是调用getlinen次&#xff0c;扔掉除最后一个结果以外的所有结果&#xff1b;呼唤ignoren-1次可能会快一点&#xff0c;但我怀疑如果您总是读入相同的字符串(而不是构造一个每次都更…

12.UiAutomator 获取系统信息

一、Build构建信息 1.build类&#xff1a; Build类提供了硬件厂商、编号、序列号、SDK版本等重要信息。 类名&#xff1a;android.os.Build 常量名 说明 BOARD底层板名称BOOTLOADERBootloader版本号BRAND品牌CPU_ABICPU指令集CPU_ABI2CPU第二指令集DEVICE工业设计名称DISPLAY显…

c语言编写网页图形界面代码,「分享」C语言如何编写图形界面

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼贴吧内经常有人问C语言是不是只能用于字符终端界面开发&#xff0c;不能用于图形界面。大家也都有回答&#xff0c;需要其他的库。MFC&#xff0c;GTK&#xff0c;QT。本人近期刚用GTK库加上纯C写成了第一个LINUX实用程序。现在与大…

python 读取word_教你怎么使用 Python 对 word文档 进行操作

使用Python对word文档进行操作一、安装Python-docxPython-docx是专门针对于word文档的一个模块&#xff0c;只能读取docx 不能读取doc文件。说白了&#xff0c;python就相当于windows操作系统&#xff0c;QQ就是跑在windows操作系统上的软件&#xff0c;QQ最大的作用是可以去聊…

[国嵌攻略][084][信号同步编程]

进程同步 一组并发进程进行相互合作、相互等待&#xff0c;使得各进程按一定的顺序执行的过程称为进程间的同步。 进程同步与进程互斥 进程同步问题的关键在于生产者不需要获取信号量&#xff0c;消费者不需要释放信号量&#xff0c;所以信号量的初值设置为0。但是进程互斥问题…

android 控件覆盖关系,安卓子控件抢占父控件点击事件或者焦点问题

开发中很常见的一个问题&#xff0c;项目中的lListview不仅仅是简单的文字&#xff0c;常常需要自己定义listview&#xff0c;自己的Adapter去继承BaseAdapter&#xff0c;在adapter中按照需求进行编写&#xff0c;问题就出现了&#xff0c;可能会发生点击每一个item的时候没有…

stm32cubemx adc_STM32CubeMX__Exp5_ADC1_2CH_DMA_TIM3_Trig__简明指导文件__jyb

用定时器TIM3触发DMA方式的双通道ADC定时采样&#xff1a;拷贝STM32CubeMX工程文件LED_Flash_PC12.ioc&#xff0c;修改为&#xff1a;Exp5_ADC1_2CH_DMA_TIM3_Trig.ioc(1)配置ADC1的通道和参数配置ADC通道参数(2)配置ADC1的DMA①通过点"Add"按钮&#xff0c;添加ADC…

JS 实现 jQuery的$(function(){});

1、浏览器渲染引擎的HTML解析流程 何谓“渲染”&#xff0c;其实就是浏览器把请求到的HTML内容显示出来的过程。渲染引擎首先通过网络获得所请求文档的内容&#xff0c;通常以8K分块的方式完成。下面是渲染引擎在取得内容之后的基本流程&#xff1a; 1&#xff0c;解析html以构…

linux ora-00031,kill session遇到ORA-00031錯誤

今天在處理一個表被鎖死的問題時&#xff0c;遇到ORA-00031: 這個階段作業將被標示為要終結的階段作業具體操作步驟如下&#xff1a;1. 先確認鎖定資源的session信息select OS_USER_NAME,s.MACHINE ,object_name as對象名稱,s.sid,s.serial#,p.spid as系統進程號from v$locked_…

html 分页_MySQL——优化嵌套查询和分页查询

Java识堂&#xff0c;一个高原创&#xff0c;高收藏&#xff0c;有干货的微信公众号&#xff0c;欢迎关注优化嵌套查询嵌套查询(子查询)可以使用SELECT语句来创建一个单列的查询结果&#xff0c;然后把这个结果作为过滤条件用在另一个查询中。嵌套查询写起来简单&#xff0c;也…

从原理上搞定编码-- Base64编码

开发者对Base64编码肯定很熟悉&#xff0c;是否对它有很清晰的认识就不一定了。实际 上Base64已经简单到不能再简单了&#xff0c;如果对它的理解还是模棱两可实在不应该。大概介绍一下Base64的相关内容&#xff0c;花几分钟时间就可以彻底理解它。文 章下边贴了一个Base64的编…

android 点击选择文件夹,Android----弹出框选择文件夹目录以及启用新Task打开文件_IT168文库.pdf...

Android弹弹 出出框框 选选择择 文文件件 夹夹 目目录录 以以及及 启启用用新新 的的T ask打打 开开文文件件首首先先看看效效果果 图图第第一一个个 Act iv it y很很简简单单就就 一一个个按按钮钮 But t o n 加加一一个个 T ext View见见 main.xm l[[ cc -- ss hh aa rr pp ]…

docker mysql总是退出_Docker提升测试效率之路

现如今&#xff0c;Docker已经成为了很多公司部署应用、服务的首选方案。依靠容器技术&#xff0c;我们能在不同的体系结构之上轻松部署几乎任何种类的应用。作为测试一方&#xff0c;我们应与时俱进&#xff0c;将Docker容器技术应用到测试工作中。为了让小伙伴们可以快速上手…