Spring 源码阅读之标签解析

全局目录.md

引子

1、容器最基本使用.md

系列1 - bean 标签解析:

2、XmlBeanFactory 的类图介绍.md

3、XmlBeanFactory 对xml文件读取.md

4、xml配置文件解析之【默认】命名空间【标签】的解析.md

5、xml配置文件解析之【自定义】命名空间【标签】的解析.md

系列2 - bean 获取: getBean() 做了什么

前言

说到 spring 是个学 java的人都能说上两嗓子,人均三板斧不过分吧。

两年前我走马观花一样的过了一遍 spring 源码,自以为已经渐渐上道了。实际上过了两年到了今天,忘了太多太多东西了,所以只好再拿起来看看。

先进入第一个专题, spring-bean.xml 的解析

到了如今,各种好用、便捷的注解已经漫天飞了,相信几乎不会再有新项目通过这种方式开发了,但是我觉得如果真的需要深入理解spring的源码,我们再去仔细揣摩这个加载过程,想必也会有所得。

正所谓,万变不离其宗,虽然通过一系列注解简化了太多太多的配置,但是我觉得我们从最初的样子,往往更能从本质上去理解他。

1、极简的测试案例

xml 配置

可能格式不一定对,我从源码包里拷了一个过来改了一下当作案例

测试伪代码

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;

public class XmlBeanFactoryTest {
	BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("bean.xml"));
	Object object = beanFactory.getBean("action");
}

上述就是 spring 最原始的使用方式了,我想只要路径、命名空间配置对了,运行起来问题不大。

别看方法体内只有两行代码:

  • 1.将xml 文件加载到 BeanFactory
  • 2.从BeanFactory 获取Bean

为了讲清楚这两行代码背后发生了什么,我们后边将会分成多个章节,进行叙述。

【相信我绝对是万恶之源了】

2、一些猜想

正式进入文章分析之前,我们不妨大胆的猜想一下,假如由我们自己来实现,spring 的容器功能,那我们要怎么做呢?

我们先问一个问题:java是面向对象的语言,那么对象怎么来的?当然不是相亲相出来的对象。

以前写过一篇博客,对象的来源就如图中这么几种:

地址:

https://www.cnblogs.com/bokers/p/15904369.html

克隆和序列化都不是无中生有的方案,所以我们暂且忽略

那么剩下如下的方式可以无中生有:

  • new 创建
  • 反射 创建

前文的例子中,我们也没有显式的创建我们在bean.xml 中定义的对象,所以是反射。

再看 bean.xml 中定义的 bean的class 属性,这不妥妥的类路径么?

总结一下,那么我们可以猜测 spring 源码中可能会包含如下的组件:

  • bean.xml 配置文件读取 ----- 组件
  • 配置文件:格式校验、内容解析,以及解析结果的缓存 ----- 组件
  • 根据解析结果读取类信息 ----- 组件
  • 应用反射工具获取类的实例对象 ----- 组件

2.1 拓展:

  • 更进一步,如果要保证单例,那么势必会有一个bean的全局缓存等等,"工厂" 这不他就悄悄的来了。

    spring 源码中大量的用到了 "工厂模式"

  • 如果懂代理的童鞋,应该知道一个叫做动态代理的东西,CGLIB 你可识得?面向切面编程,这不他就来了?

    在解析bean的时候,我们完全可以通过动态代理(为原类生成子类),附加一些行为上去,比如方法的拦截实现:

    • 生成动态代理后,在方法调用前后植入我们想要的操作,这就是AOP了

2.2 套娃拓展:

想必你也会注意到这么一个问题:

比如很多工具明明不见得是spring 官方推出的,为什么他们就是能跟spring 进行很好的整合呢? 比如日常使用的各种数据源、ORM框架、日志框架、消息队列,他们往往能通过几个注解轻松注入spring 容器中。

这是因为spring 官方不仅仅授人以鱼,还授人以渔。

没错spring 还提供了第三方插件接入的手段,只需要按照spring给出的规范去开发我们自己的 xml标签、自定义注解及其配套的解析工具。
自然就能实现把自己的工具整合到spring框架上。

不过不用担心,实际上接入spring配适的活,基本都由各个插件官方自己干了。 不然你以为凭什么,你写个 xml配置,你就敢跟人吹水:我把某某插件整合到spring框架上了。

实际上别人已经把粘合剂生产出来了,我们只是拉了个皮条。

废话讲完,接下来就应该去看看那两行代码到底干了啥了:

2.3 丑话说在前头

XmlBeanFactory 实际上已经被废弃了,这里依然还要讲它的目的主要是为了学习;虽然这个类被废弃了,但是它的父类:DefaultListableBeanFactory 至今任然是 spring 中绝对的主角之一。

这里名为学习 XmlBeanFactory,实际上是学习它的父类:DefaultListableBeanFactory。

都是从 xml 配置文件切入,实际上现今官方推荐使用的是:ClassPathXmlApplicationContext 而非 XmlBeanFactory。

而这里还把 XmlBeanFactory 拿出来讲,还有一个目的:

  • 我们可以窥见,spring的发展历程:从 XmlBeanFactory 到当下的 ClassPathXmlApplicationContext
  • XmlBeanFactory 足够简单。
    • ClassPathXmlApplicationContext 足够强大,但是它也要比 XmlBeanFactory 复杂得多;

      实际上 我们对 XmlBeanFactory 的学习成果,可以作为 ClassPathXmlApplicationContext 的子集

      所以 就算 XmlBeanFactory 已经废弃了,我们还是可以继续学习它的。

系好安全带,发车了。

3. 这是第一行

BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("bean.xml"));

这里会有4篇博客:

3.1 介绍 XmlBeanFactory 的类图:

3.2 介绍 XmlBeanFactory 解析xml配置文件的过程

3.3 spring 默认命名空间标签解析

例如: beans、import、bean、alias

3.4 用户自定义命名空间标签解析

可以认为是我们自己对 spring 默认标签的魔改。

4. 这是第二行

  • todo

还不知道需要多少篇幅介绍它

Object object = beanFactory.getBean("action");

0 条评论
请不要发布违法违规有害信息,如发现请及时举报或反馈
还没有人评论呢,速度抢占沙发!
相关文章
  • Spring Security可以通过xml配置或者注解方式初始化,其实只是配置方式不同,初始化过程大致相同。所以我们只分析通过注解方式的初始化。注解方式的初始化也会根据你的项目采用的框架不同而有所不...

  • 实现Controller的三种方式分析 每种实现的方式对应的HanderAdapter都不同。 实现Controller接口 该接口对应的HanderAdapter为SimpleControlle...

  • Spring开发中我们我们常常用到@Transaction和@Async,但这2个注解加在一起很多的开发者不敢用,担心事务不生效。下面我们就仔细讲解一下这2个注解同时运用,文章用3个场景讲述它们之间的...

  • Spring Bean参数校验Validator以下2种方式可以用于所有的 Spring bean 不仅仅是 Controller 控制器。一、原始类型参数在控制器(或者其他Bean)上使用@Vali...

  • 一、概述 1.Spring Context概念 创建上下文并将BeanPostProcessor加载到spring 2.Spring Application Context概念 Spring通过应用上...

  • Spring事务底层原理 😄生命不息,写作不止 🔥 继续踏上学习之路,学之分享笔记 👊 总有一天我也能像各位大佬一样 🏆 一个有梦有戏的人 @怒放吧德德 🌝分享学习心得,欢迎指正,大家一起...

  • 实现Spring底层机制-01 主要实现:初始化IOC容器+依赖注入+BeanPostProcessor机制+AOP 前面我们实际上已经使用代码简单实现了: Spring XML 注入 bean...

  • 1. 什么是循环依赖 Java循环依赖指的是两个或多个类之间的相互依赖,形成了一个循环的依赖关系,这会导致程序编译失败或运行时出现异常。下面小岳就带大家来详细分析下Java循环依赖。 简单来讲就是:...

  • 当大家了解了如何编写一个简单的Spring MVC程序后,大家心中应该会有一些好奇:这背后到底发生了什么? Spring MVC是怎么把这些功能串联起来的?我们只是写了一个控制器而已,HTTP请求是怎...

  • Spring Spring为简化开发而生,让程序员只关心核心业务的实现,尽可能的不在关注非业务逻辑代码(事务控制,安全日志等)。 1,Spring八大模块 这八大模块组成了Spring 1.1 S...

  • 1、方式一:基于spring.xml方式配置Bean user import lombok.Data; /** * @author : ly */ @Data public class User...

  • 本文目的 完成Spring Framework5.x的源码构建 准备 官网:Spring Framework 使用5.x版本源码包构建 项目管理工具 gradle(没学过的先去找资料学习) 说明 ...

  • 引言     spring实现的bean自动注入在项目开发中是一个经常使用到的功能,但自动装配两个或多个bean时,会抛出NoUniqueBeanDefinitionException:No qual...

  • 为啥要用 Spring张三是一个编程小白,他每次在 service 层写代码都要自己 new 一堆 Dao 接口的实现类。public class ProjectServiceImpl impleme...

  • 您好,我是湘王,这是我的博客园,欢迎您来,欢迎您再来~ Spring Security使用MySQL保存cookie记录虽然方便,但是目前更多的主流互联网应用都是用NoSQL来保存非业务数据的,Sp...

  • 1.使用MessageSource (1) 有时,我们的项目可能会面临国际化需求,例如:对不同国家的人,我们需返回不同语言的消息,而java本身已经给我们提供了ResourceBundle类实现国际化...

  • Spring管理Bean-IOC-04 3.基于注解配置bean 3.1基本使用 3.1.1说明 基本说明:基于注解的方式配置bean,主要是项目开发中的组件,比如Controller,Service...

  • 前面我们对Spring事务框架以及Spring启用事务管理的@EnableTransactionManagement进行了学习,了解了Spring事务管理的底层工作机制。有关Spring事务管理剩余尚...

  • "Most of you are familiar with the virtues of a programmer. There are three, of course: laziness, im...

  • 上文已经讲过@EnableAsync的bean构建过程,这里继续分解@Async执行过程,以及spring 的AOP调用过程。先上demopublic class ApiGatewayApplicat...