千家信息网

如何构建Spring源码运行环境

发表于:2025-12-02 作者:千家信息网编辑
千家信息网最后更新 2025年12月02日,本篇内容主要讲解"如何构建Spring源码运行环境",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"如何构建Spring源码运行环境"吧!为什么研究Sprin
千家信息网最后更新 2025年12月02日如何构建Spring源码运行环境

本篇内容主要讲解"如何构建Spring源码运行环境",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"如何构建Spring源码运行环境"吧!

为什么研究Spring源码

自己研究源码的初心就是想看看那些牛逼的框架到底是有多牛逼,代码到底有多优雅,怎么利用设计模式去构建程序,如何漂亮实现解耦,如何设计扩展点灵活让第三方开发者干预框架的运行,如何与框架进行整合。说出来可能有人还不信,个人并不是因为想去BAT这些大厂而研究源码,估计像我这个年龄别人也不会要了。。。自嘲一下!

希望自己通过阅读Spring源码提高如下能力:

1.首先肯定是阅读源代码的能力,找到阅读源码的基本方法,提高DEBUG的能力,加强如何定位问题的技巧

2.让自己心里的大象迈出一小步,让自己熟悉阅读源码,培养习惯,以后看更多的源码

3.从源码中找到写出漂亮代码的底层逻辑,比如设计模式、如何解耦、优雅的语法或者API、非常棒的工具类

4.提高项目脚手架质量,提升编码能力,加快BUG定位速度

5.将阅读源码的结果分享出来,尽量可以让路过的人可以产生阅读源码的兴趣,解决工作中遇到问题

构建Spring源码

最新的Spring源码是通过Gradle构建的,因此只接触过Maven构建的朋友建议花几个小时在网上找一个Gradle的学习视频,大概了解一下grovvy和Gradle相关知识,不然真的看不懂gradle.build文件。比如闭包、Gradle特有的API等,还有Gradle的安装、IDEA如何提升Gradle编译速度等。

基于自己的环境写了一篇博客:https://my.oschina.net/u/3049601/blog/3113019 欢迎参考

准备工作

1.简单学习grovvy和Gradle相关知识

2.了解一下设计模式,比如装饰者、模板方法、工厂方法,还有抽象类、接口的运用,里面用了大量的设计模式,不提前了解一下,代码看起来比较吃力

3.学习Java8的Lamda表达式

4.学习Idea的快捷键,DEBUG的一些技巧

如何去看Spring源码

等Spring源码构建完成后,该如何着手去看喃,当然是写一个工程,通过DEBUG Spring源码看执行过程等,总结自己看源码几点经验

1.一定要从GIT上下载源码并构建,反编译看源码,特别是复杂的代码会发蒙的。

2.在工程中开启新的工程或者module,引用项目中的module进行调试

3.看源码之前一定要对框架的使用比较熟悉,千万不要对框架的使用都不熟悉就跑去看源码,那样一定会发蒙的。所以花点钱买点框架使用的书或者视频先看看,不要吝啬那几分钱,等你看完工资一定会涨的。比如SpringMVC,你就只知道加@Controller @Service @Component完成业务代码可不行。

4.看源码时通过DEBUG对框架有总体上的认识,不要一来就往深、细了抠,如果那样的话,你会发现自己很快就看不下去了

5.DEBUG时着重先关注每行代码执行完后关键变量的变化,比如Spring源码当中的beanDefinitionMap singletonObjects beanPostProcessors等,返回的对象或者值是不是可能你需要关注的

6.善用DEBUG的条件断点,否则可能你按了无数次F6也到不了你关注的触发点或者执行点

7.一定要边看边加注释、做笔记、画图什么的,因为一两天你是看不完的,很可能因为其他事情耽搁了,等下次来看又蒙了

8.GOOGLE 百度是常用工具,也可以试着搜索一下gitee或者github上面是否已经有别人看过的源码分析的项目,DOWN下来接着看,可以提高阅读速度,但是一定要写代码去验证,因为有人直接翻译的英文,也许那并没有什么Luan用。既然是看源码,是基本的东西,凡是别人的东西一定要多方面验证才能吸收成正确的自己的,否则看了半天结果是错的就麻烦了。我就遇到了这样的问题,在搜索引擎上找到的内容其实在Spring5已经变了。

Spring大概的工作流程

开始王婆卖瓜。。。。因为现在开发都是基于注解的,因此也是拿AnnotationConfigApplicationContext作为分析对象

概要流程

非常概要的图描述Spring容器初始化过程

Spring核心类实例化

核心类起的作用就好像汽车的发动机,没它都跑不了咯,还能指望它带你去撩妹、看帅哥么。同样,Spring的核心类能够保证容器或者叫上下文能够正常工作,基于它管理我们的业务对象,实现业务逻辑,比如:

AnnotationConfigApplicationContext:也就是Spring的整个容器,Spring还有另外一个类似的叫ClassPathXmlApplicatonContext(基于XML配置的),在它里面包含了所有实例化的单例Bean、系统参数与配置文件加载后的键值对、后置处理器、每个Bean的定义等等

AnnotatedBeanDefinitionReader:负责读取被注解修饰了的Bean的定义,并添加到某一个Bean定义的集合当中。典型的场景就是我的ImportResourceAppConfig.class传入到AnnotatedBeanDefinitionReader.register()方法中,在BeanDefinitionMap中会新增一个对应的元素。

DefaultListableBeanFactory:这个就相当相当重要了。。。它包含了注册BeanDefinition-registerBeanDefinition(),然后利用BeanDefinition获取或者创建Bean的逻辑-getBean(),对应的就有两个方法常使用的四个变量:

private final Map beanDefinitionMap;--存放所有的Spring Bean定义(BeanDefinition),关于BeanDefinition详解查看:https://my.oschina.net/u/3049601/blog/3127635

private final Map singletonObjects --存放所有的单例Spring Bean

private final Map earlySingletonObjects --存放循环依赖时需要提前被暴露的Bean,这些Bean并没有被很多PostProcessor(中文翻译为后置处理器)处理,以解决循环依赖不会出现无限制的递归(这里没明白没关系,知道它和解决循环依赖有很重要关系即可,后面会详细说明)

private final Set singletonsCurrentlyInCreation --存放当前容器中正在被创建的beanName(它也和循环依赖有很大关系)

核心组件类定义的注册

图中的就是Bean定义集合的元素截图,这些组件会完成@ComponentScan注解的包扫描,以及被扫描到的类定义注册,实例化裸对象,完成SpringBean的初始化(包含了各种PostProcessor的处理,比如依赖注入)

图中截图Map中Key对应的类如下顺序:

ConfigurationClassPostProcessor:扫描@ComponentScan中指定包路径下所有符合Spring规则的类,如加了@Configuration @Component等的类,将他们的BeanDefinition注册到beanDefinitionMaps当中。还有另外一个功能就是添加一个ImportAwareBeanPostProcessor,它可以让你的Bean获取到将@Import作为元注解时自定义注解的属性键值对(此功能可以先不管)

DefaultEventListenerFactory:和Application Event有关,还没详细查看以后再补充

EventListenerMethodProcessor:和Application Event有关,还没详细查看以后再补充

AutowiredAnnotationBeanPostProcessor:负责依赖注入和属性注入,比如@Autowired @Value的相应动作

CommonAnnotationBeanPostProcessor:负责JSR250相关注解的解析与执行,比如@PostContruct @Resource等

注册配置类

使用AnnotatedBeanDefinitionReader.register(ImportResourceAppConfig.class)将ImportResourceAppConfig的BeanDefinition注册到beanDefinitionMaps当中。完成这个动作之后Spring才能拿到配置类做下一步的包扫描、依赖注入等操作

解析配置类上的注解,并完成BeanDefinition注册

主要就是ConfigurationClassPostProcessor和AutowiredAnnotationBeanPostProcessor两个类启核心作用(当然还有这两个牵扯出来的其他类),比如ConfigurationClassPostProcessor.ConfigurationClassPaser就是负责完成包扫描的,包含了@ComponentScan @Component @Import @ImportResource @Bean 注解的解析完成所有的BeanDefinition的创建并注册到beanDefinitionMaps当中

根据BeanDefinition实例化Spring Bean

上一步已经将所有的BeanDefinition准备好,接下来就是遍历他们,使用动态代理完成对象的实例化,并最终得到Spring Bean(可能是裸对象,也可能是代理对象)。

总结:简单的说Spring并不是直接根据Class文件创建一个Bean,而是生成对应的BeanDefinition对象,再根据它创建想要的Bean,在这个过程当中Spring提供了丰富的扩展点去干预BeanDefinition状态和Bean的状态,这些扩展点就是Spring真正强大的原因。

到此,相信大家对"如何构建Spring源码运行环境"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

源码 对象 就是 注解 代码 框架 方法 学习 实例 核心 设计 配置 环境 运行 容器 模式 能力 设计模式 处理 工作 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 文件服务器怎么生成url 宝塔进不去怎么备份数据库 保存文件内容用什么数据库好 如何查看服务器出访ip地址 雪亮工程2019网络安全 患者主索引数据库 阿里巴巴软件开发管理 公安网络安全检查大概几天 刺激战场下载后不能连接服务器 迅雷下载为什么要登录服务器 前端直接连接sftp服务器 服务器温度多少正常 网络安全改编mv 台州用友软件开发公司 lucene文件怎么放到服务器 燃烧的远征会开新服务器吗 企业网络安全管理案例 电影放映服务器配置 软件开发工作室装修风格大全 医保网络安全周活动 常用的网络安全服务有 服务器主板只认一条内存 苏州起橙网络技术有限公司 汽车保养设备操作软件开发的企业 如何生成数据库模拟数据 黑龙江企业党建软件开发哪儿好 删除一个数据库 mysql数据库域名 滴滴被网络安全审查滴滴怎么了 jdbc数据库实验报告截图
0