• 《系列一》-- 1、容器最基本使用





    阅读之前要注意的东西:本文就是主打流水账式的源码阅读,主导的是一个参考,主要内容需要看官自己去源码中验证。全系列文章基于 spring 源码 5.x 版本。



    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");

  • 相关阅读:
    【Spring】使用 MyBatis 操作数据库
    Linux常用指令--时间操作指令
    Vue进阶(幺陆玖)项目部署后IE报 SCRIPT1002:语法错误 解决方案探讨
    LeetCode 1765 Map of Highest Peak (多源点BFS 推荐)
    生成式AI新篇章:亚马逊云科技助力重塑数字未来
    安全典型配置(五)SNMP中应用ACL过滤非法网管案例
    uniapp 学习笔记三十四 加载用户地址列表和默认地址的在线数据修改
    线程池、Lambda表达式
    服务端NioSocketChannel泄漏案例
    【VRP问题】基于蚁群算法求解配送路径最短问题附matlab代码
  • 原文地址:https://www.cnblogs.com/bokers/p/17294645.html