(转) Spring源码阅读 之 Spring整体架构
标签(空格分隔): Spring
声明:本文系转载,原地地址:spring framework 4 源码阅读
Spring骨架
Spring的骨架,也是Spring的核心包。主要包含三个内容
- context:spring的上下文 ---> 导演(个人觉得其实称为 舞台更合适)
- core:spring的核心包,主要包括spring所有用到的工具 ---> 道具
- beans:spring的bean实例 ---> 演员
导演负责安排演出,演员负责按照导演的指示来演出,演出过程中需要使用道具。我想大家看完这些图片之后就明白大致的包关系了。
Spring包结构
大家看到相应包内容:
- core包侧重于工具类。
- beans包更侧重于bean实例的描述。
- context更侧重于全局控制,功能衍生。
下面我们就针对于context和factory类的关系继续一个基本概况:
核心类之前的关系
我们先来看下bean包下的beanfactory类 以及抽象类等。
可以看到在接口的实现泛化的过程中,每一个接口在继承父接口的同时,也继承了父接口的一些方法。这就可以看出面向接口的微妙之处。
BeanFactory(所有BeanFactory的父类)
可以看到beanFactory中定义了一些基本方法,包括根据名称获取bean实例等。
HierarchicalBeanFactory(层次化的BeanFactory)
可以看到此接口实现了层次化,及获取beanFactory的父容器。
ListableBeanFactory(列表式BeanFactory)
可以看到为beanfactory设置了列表的功能,并且规划了如何从列表中取出相应的方法的能力。
小结
从上述类命名以及接口规划可以看到,通过接口的不断继承,beanfactory被不断的丰富抽象起来。层层细分之后,每个类的职责都变的非常单一了,同时在扩展起来也更加方便了。针对源代码,最好的办法还是根据名称来,最方便。
context(上下文)
可以看到context的初始化不同于beanfactory,可以侧重于抽象类型,具体的方法实现。
里面大部分方法使用了模板方法设计模式,父类调用抽象方法,抽象方法在子类中实现,对象的独立性。
主要分成三种context:XML Annotation Groovy 三种形式。
registry(实例或者bean描述注册器)
将初始化完成的bean注册到容器中,针对于单例部分,缓存单例实例。针对beanDefinition部分,缓存bean的描述。
Strategy(初始化策略)
两种初始化策略:一种是简单策略,一种是cglib的策略,这里使用的模式是策略模式。
context的初始化
/**
* 在parent下创建ClassPathXmlApplicaitonContext,
* 从XML中读取所有Bean定义.
* @param configLocations 配置文件路径如c:\simpleContext.xml
* @param refresh 是否需要自动刷新context,refresh-->重新加载
* 加载所有的bean定义,创建所有单例.
* refresh为true的时候, 根据context来手工刷新
* @param parent the parent context
* @throws BeansException if context creation failed
* @see #refresh()
*/
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException {
//初始化XmlApplicationContext
super(parent);
//转换配置文件的路径
setConfigLocations(configLocations);
if (refresh) {
//重新刷新原有的context,这一篇的重点
refresh();
}
}
下面我们来看下AbstractApplicationContext.refresh()方法
//加载或刷新持久的配置,可能是xml文件,properties文件,或者关系型数据库的概要。
//做为一个启动方法,如果初始化失败将会销毁已经创建好的单例,避免重复加载配置文件。
//换句话说,在执行这个方法之后,要不全部加载单例,要不都不加载
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 初始化配置准备刷新,验证环境变量中的一些必选参数
prepareRefresh();
// 告诉继承类销毁内部的factory创建新的factory的实例
// 初始化Bean实例
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 初始化beanFactroy的基本信息,包括classloader,environment,忽略的注解等
prepareBeanFactory(beanFactory);
try {
// beanfactory内部的postProcess,可以理解为context中PostProcess的补充
beanFactory.postProcessBeanFactory(beanFactory);
// 执行BeanFactoryPostProcessor(在beanFactory初始化过程中,bean初始化之前,修改beanfactory参数)
// BeanDefinitionRegistryPostProcessor 其实也是继承自BeanFactoryPostProcessor,
// 多了对BeanDefinitionRegistry的支持invokeBeanFactoryPostProcessors(beanFactory);
// 执行postProcess,那BeanPostProcessor是什么呢,是为了在bean加载过程中修改bean的内容,
// 使用分的有两个而方法Before、After分别对应初始化前和初始化后
registerBeanPostProcessors(beanFactory);
// 初始化MessageSource,主要用作I18N本地化的内容
initMessageSource();
// 初始化事件广播ApplicationEventMulticaster,使用观察者模式,对注册的ApplicationEvent时间进行捕捉
initApplicationEventMulticaster();
// 初始化特殊bean的方法
onRefresh();
// 将所有ApplicationEventListener注册到ApplicationEventMulticaster中
registerListeners();
// 初始化所有不为lazy-init的bean,singleton实例
finishBeanFactoryInitialization(beanFactory);
// 初始化lifecycle的bean并启动(例如quartz的定时器等),如果开启JMX则将ApplicationContext注册到上面
finishRefresh();
} catch (BeansException ex) {
//销毁已经创建单例
resources.destroyBeans();
// 将context的状态转换为无效,标示初始化失败
flag.cancelRefresh(ex);
// 将异常传播到调用者
throw ex;
}
}
}
我们从时序图来看启动上述初始化(门面模式facade)
(转) Spring源码阅读 之 Spring整体架构的更多相关文章
- Spring源码阅读系列总结
最近一段时间,粗略的查看了一下Spring源码,对Spring的两大核心和Spring的组件有了更深入的了解.同时在学习Spring源码时,得了解一些设计模式,不然阅读源码还是有一定难度的,所以一些重 ...
- Bean实例化(Spring源码阅读)-我们到底能走多远系列(33)
我们到底能走多远系列(33) 扯淡: 各位: 命运就算颠沛流离 命运就算曲折离奇 命运就算恐吓着你做人没趣味 别流泪 心酸 更不应舍弃 ... 主题: Spring源码阅读还在继 ...
- 初始化IoC容器(Spring源码阅读)
初始化IoC容器(Spring源码阅读) 我们到底能走多远系列(31) 扯淡: 有个问题一直想问:各位你们的工资剩下来会怎么处理?已婚的,我知道工资永远都是不够的.未婚的你们,你们是怎么分配工资的? ...
- Spring源码阅读-ApplicationContext体系结构分析
目录 继承层次图概览 ConfigurableApplicationContext分析 AbstractApplicationContext GenericApplicationContext Gen ...
- Sping学习笔记(一)----Spring源码阅读环境的搭建
idea搭建spring源码阅读环境 安装gradle Github下载Spring源码 新建学习spring源码的项目 idea搭建spring源码阅读环境 安装gradle 在官网中下载gradl ...
- Spring源码阅读笔记02:IOC基本概念
上篇文章中我们介绍了准备Spring源码阅读环境的两种姿势,接下来,我们就要开始探寻这个著名框架背后的原理.Spring提供的最基本最底层的功能是bean容器,这其实是对IoC思想的应用,在学习Spr ...
- Spring源码阅读 之 配置的读取,解析
在上文中我们已经知道了Spring如何从我们给定的位置加载到配置文件,并将文件包装成一个Resource对象.这篇文章我们将要探讨的就是,如何从这个Resouce对象中加载到我们的容器?加载到容器后又 ...
- 搭建 Spring 源码阅读环境
前言 有一个Spring源码阅读环境是学习Spring的基础.笔者借鉴了网上很多搭建环境的方法,也尝试了很多,接下来总结两种个人认为比较简便实用的方法.读者可根据自己的需要自行选择. 方法一:搭建基础 ...
- Spring源码-IOC部分-Spring是如何解决Bean循环依赖的【6】
实验环境:spring-framework-5.0.2.jdk8.gradle4.3.1 Spring源码-IOC部分-容器简介[1] Spring源码-IOC部分-容器初始化过程[2] Spring ...
随机推荐
- 洛谷3258:[USACO2012 MAR]Flowerpot 花盆——题解
https://www.luogu.org/problemnew/show/P2698#sub 老板需要你帮忙浇花.给出N滴水的坐标,y表示水滴的高度,x表示它下落到x轴的位置. 每滴水以每秒1个单位 ...
- BZOJ1834 [ZJOI2010]network 网络扩容 【最大流,费用流】
1834: [ZJOI2010]network 网络扩容 Time Limit: 3 Sec Memory Limit: 64 MB Submit: 3394 Solved: 1774 [Subm ...
- 添加网站标题logo
如何在标题栏title前添加网站logo? 第一种方法:据说在网站根目录下放着我们的ico型logo,命名为favicon.ico,浏览器会自动去找到并显示.试了试,在firefox23和ie8下都没 ...
- node.js 与java 的主要的区别是什么
node.js 与java都是服务器语言,但是两者存在很大区别:(1)Node.js比Java更快 :node.js开发快,运行的效率也算比较高,但是如果项目大了就容易乱,而且javascript不是 ...
- Web前端工程师-优秀简历汇总
Web前端工程师-优秀简历汇总 1. http://www.linqing07.com/resume.html 2. http://www.flqin.com/#page2 3. ht ...
- git branch 重命名
有时候你会有重命名一个git branch的冲动,不要怀疑,这是真的.command bellow will give u a big help,no thanks~ git branch - m o ...
- 精通BIRT:Eclipse商务智能报表工具开发实践指南
http://blog.csdn.net/birtbird/article/details/8935520 [置顶] 精通BIRT:Eclipse商务智能报表工具开发实践指南 分类: BIRT 201 ...
- vijos 1004 伊甸园日历游戏 博弈+打表找规律
描述 Adam和Eve玩一个游戏,他们先从1900.1.1到2001.11.4这个日期之间随意抽取一个日期出来.然后他们轮流对这个日期进行操作: 1 : 把日期的天数加1,例如1900.1.1变到19 ...
- 【BZOJ4816】【SDOI2017】数字表格 [莫比乌斯反演]
数字表格 Time Limit: 50 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description Doris刚刚学习了fibonac ...
- Network(POJ3694+边双连通分量+LCA)
题目链接:http://poj.org/problem?id=3694 题目: 题意:给你一个n个点m条边的无向连通图,进行q次操作,每次操作在u和v之间加一条边,问每次操作之后“桥”的数量. 思路: ...