Spring源码笔记
Spring
Version:5.1.12
ApplicationContext
常用的实例化方式:
- ClassPathXmlApplicationContext
- FileSystemXmlApplicationContext
- XmlWebApplicationContext
通过Spring源码可见多钟方式进行实例化:

ClassPathXmlApplicationContext 比较常用的方式,通过加载xml文件实例化Spring容器,加载bean。
继承结构;
ClassPathXmlApplicationContext:

FileSystemXmlApplicationContext:

XmlWebApplicationContext:

Spring容器初始化过程
通过ClassPathXmlApplicationContext构造方法,调用了其父级AbstractXmlApplicationContext类中的refresh()方法;
1 public ClassPathXmlApplicationContext(
2 String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
3 throws BeansException {
4 //初始化父级容器
5 super(parent);
6 setConfigLocations(configLocations);
7 if (refresh) {
8 refresh(); //初始化工作
9 }
10 }
Spring容器初始化核心方法是refresh();该方法进行了准备环境、初始化容器、执行bean实例化、通知事件等操作。
refresh():
1 public void refresh() throws BeansException, IllegalStateException {
2 //该锁用于防止refresh和destory()同事进行
3 synchronized (this.startupShutdownMonitor) {
4 //容器初始化前,准备工作:
5 //设置状态、启动时间、实例化配置文件、准备环境
6 prepareRefresh();
7
8 // 获得beanFactory
9 /**
10 * 初始化DefaultListableBeanFactory beanFactory = createBeanFactory();
11 * getInternalParentBeanFactory() -- > getParent() --> return this.parent; this.parent 为null
12 * return new new DefaultListableBeanFactory();
13 */
14 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
15
16 // 配置BeanFactory context上下文环境
17 prepareBeanFactory(beanFactory);
18
19 try {
20 //BeanFactoryPostProcessor 后置处理操作
21 postProcessBeanFactory(beanFactory);
22
23 // 调用注册过的 BeanFactoryPostProcessor的相关方法
24 invokeBeanFactoryPostProcessors(beanFactory);
25
26 // 注册BeanPostProcessor
27 registerBeanPostProcessors(beanFactory);
28
29 //初始化国际化信息
30 initMessageSource();
31
32 // 初始化事件
33 initApplicationEventMulticaster();
34
35 // 调用子类实现的onRefresh方法
36 onRefresh();
37
38 // 注册监听
39 registerListeners();
40
41 // 初始化bean操作、注入属性、调用BeanPostProcessor后置处理器方法
42 finishBeanFactoryInitialization(beanFactory);
43
44 // 完成容器加载、执行通知事件
45 finishRefresh();
46 }
47 catch (BeansException ex) {
48 if (logger.isWarnEnabled()) {
49 logger.warn("Exception encountered during context initialization - " +
50 "cancelling refresh attempt: " + ex);
51 }
52 destroyBeans();
53
54 cancelRefresh(ex);
55 throw ex;
56 }
57 finally {
58 resetCommonCaches();
59 }
60 }
61 }
Spring容器简单描述可认为是一个BeanFactory,BeanFactory为一个顶层接口,Spring针对该接口作了大量的实现操作,不同的操作和功能通过大量的子类来进行实现;
Bean加载和初始化
在refresh方法中,Spring对Bean的加载和初始化分开进行,先加载bean的定义loadBeanDefinitions(),在最后才执行bean加载的操作为finishBeanFactoryInitialization();
bean的加载的方式有多种,上面提到的不同方式的容器子类,有classPath(xml方式) 、FileSystem(文件方式)、xmlWeb(远程加载xml)、Annotation(注解,SpringBoot的主要方式)等
Bean信息加载过程:

Bean实例化,finishBeanFactoryInitialization(),通过BeanDefinition Map中的信息逐个创建对象。ConfigurableListableBeanFactory.preInstantiateSingletons()该方法实例化所有懒加载的单例对象。由于懒加载的对象在使用时才根据BeanDefinition信息创建对象。对于scop ="prototype"的对象,Spring只负责创建,不负责管理,所以Spring容器初始化时没有创建懒加载和非单例对象。
Bean创建过程:

Spring循环依赖
目前Spring只支持单例bean通过Set方法和@Autowired注解的方式进行循环依赖。因为Spring通过构造来创建对象。在对象创建完成之后才进行属性设置。

FactoryBean
工厂Bean,接口类
1 public interface FactoryBean<T> {
2 //返回FactoryBean创建的bean实例,isSingleto返回true,则放入到Spring单例池中。
3 T getObject() throws Exception;
4 //返回FactoryBean创建的bean类型
5 Class<?> getObjectType();
6 //是否单例
7 boolean isSingleton();
8
9 }
未完待续。。。。。。。
Spring源码笔记的更多相关文章
- 厉害!这份阿里面试官 甩出的Spring源码笔记,GitHub上已经爆火
前言 时至今日,Spring 在 Java 生态系统与就业市场上,面试出镜率之高,投产规模之广,无出其右.随着技术的发展,Spring 从往日的 IoC 框架,已发展成 Cloud Native 基础 ...
- 【初学】Spring源码笔记之零:阅读源码
笔记要求 了解Java语言 了解Spring Framework的基础 会使用Maven 关于本笔记 起因 本职数据分析,为公司内部人员开发数据处理系统,使用了Python/Django+Bootst ...
- 首发!Alibaba内部:Spring源码培训课件笔记曝光!
本文包含的内容 Spring占有的市场 阅读源码的重要性 阅读源码困难度 课件笔记的主要内容 Spring占有的市场 先来简单说一下现在各个企业常用并与Spring相关的: ssh = spring ...
- Spring源码阅读笔记
前言 作为一个Java开发者,工作了几年后,越发觉力有点不从心了,技术的世界实在是太过于辽阔了,接触的东西越多,越感到前所未有的恐慌. 每天捣鼓这个捣鼓那个,结果回过头来,才发现这个也不通,那个也不精 ...
- Spring源码阅读笔记01:源码阅读环境准备
1. 写在前面 对于做Java开发的同学来说,Spring就像是一条绕不过去的路,但是大多数也只是停留在对Spring的简单使用层面上,对于其背后的原理所知不多也不愿深究,关于这个问题,我在平时的生活 ...
- Spring源码学习笔记9——构造器注入及其循环依赖
Spring源码学习笔记9--构造器注入及其循环依赖 一丶前言 前面我们分析了spring基于字段的和基于set方法注入的原理,但是没有分析第二常用的注入方式(构造器注入)(第一常用字段注入),并且在 ...
- Spring 源码学习笔记10——Spring AOP
Spring 源码学习笔记10--Spring AOP 参考书籍<Spring技术内幕>Spring AOP的实现章节 书有点老,但是里面一些概念还是总结比较到位 源码基于Spring-a ...
- Spring 源码学习笔记11——Spring事务
Spring 源码学习笔记11--Spring事务 Spring事务是基于Spring Aop的扩展 AOP的知识参见<Spring 源码学习笔记10--Spring AOP> 图片参考了 ...
- Spring源码学习笔记12——总结篇,IOC,Bean的生命周期,三大扩展点
Spring源码学习笔记12--总结篇,IOC,Bean的生命周期,三大扩展点 参考了Spring 官网文档 https://docs.spring.io/spring-framework/docs/ ...
随机推荐
- windows10 热点一直显示正在断开中
解决方法: Windows+x,打开"windows Powershell(管理员),执行以下命令:netsh winsock reset 重启电脑,就OK了
- C++中memset函数的用法
转载:https://blog.csdn.net/qq_22122811/article/details/52738029 //复习数组的时候,第一次见到了memset,学之. memset:char ...
- Apache账户密码加密方式介绍
一.apache密码存储格式 apache的用户密码一般会生成保存在.htpasswd文件中,保存路径由用户创建时确定,根据使用加密算法有五种保存格式: [注]:如果用户指定了保存密码的文件名,视用户 ...
- 跟我一起学.NetCore之WebApi接口裸奔有风险(Jwt)
前言 撸码需谨慎,裸奔有风险.经常在一些技术交流群中了解到,还有很多小伙伴的项目中Api接口没有做任何安全机制验证,直接就裸奔了,对于一些临时项目或是个人小项目还好,其余的话,建议小伙伴们酌情考虑都加 ...
- 在Windows7系统中设置虚拟内存大小
当我们的电脑物理内存空间不够用时,操作系统就会自动从硬盘空间上分出一块空间来当内存使用,这就是虚拟内存.可以说虚拟内存是物理内存的补充,是备用的物理内存.一般来说,如果电脑里的程序不多,占用内存资源不 ...
- docker-管理镜像常用命令
1. docker管理镜像常用命令 指令 说明 docker run [容器 CONTAINER ID] 创建一个新的容器并运行一个命令 docker start [容器 CONT ...
- Avoid mutating a prop directly since the value will be overwritten whenever the parent component re
子组件修改父组件的值踩坑 Vue1.0升级至2.0之后,直接在子组件修改父组件的值是会报错的 目的是为了阻止子组件影响父组件的数据. 我们都知道在vue中,父组件传入子组件的变量是存放在props属性 ...
- 在linux下搭建l2tp隧道
搭一个l2tp隧道,拓扑如下 两台机器是CentOS5,内核选上CONFIG_LEGACY_PTYS选项后自己编译的,l2tp是已经停更的l2tpd-0.69.先在LS上配置IP地址,iptables ...
- Java9系列第三篇-同一个Jar支持多JDK版本运行
我计划在后续的一段时间内,写一系列关于java 9的文章,虽然java 9 不像Java 8或者Java 11那样的核心java版本,但是还是有很多的特性值得关注.期待您能关注我,我将把java 9 ...
- docker19.03使用数据卷
一,查看当前的docker版本 [root@localhost data]# docker --version Docker version 19.03.8, build afacb8b 说明:刘宏缔 ...