【深度剖析】Spring1.0源码--2、初识Spring工厂

有兴趣的小伙伴可以看b站相关视频:https://www.bilibili.com/video/BV1bY41167rg/?spm_id_from=333.999.0.0

前言

本文主要从BeanFactory接口定义的行为和注释作为切入点,以ClassPathXmlApplicationContext入口梳理Spring加载配置和创建对象的总体方法流程,构建Spring的主干流程。先有主干再学习枝干,像一棵树一样不断生长。

一、BeanFactory接口

大家都知道BeanFactory接口是Spring的核心,先来看该接口提供了什么方法。(温馨提示:看源码先看接口
在这里插入图片描述
从上图可以看出,主要是通过名称获取对象,并且接口名称后缀是Factory,可以大胆猜想就是通过getBean方法来创建对象。接着看接口的注释,看能不能挖掘一些东西出来。
在这里插入图片描述
在这里插入图片描述
根据接口的第一段注释和第三段注释可知,持有一些BeanDefinition的信息,每个Bean的定义信息拥有唯一名字;从配置文件(如XML)中读取配置进行解析,再结合之前对spring的了解,画出一个简单的轮廓。主要是两个步骤,读取配置文件,解析配置文件为BeanDefinition,如下图。
在这里插入图片描述

其他功能都是在该轮廓的基础上扩充,目的都是为创建对象服务。如果掌握了这个流程,那么可以自行看源码,然后将功能添加到上图中。

二、Spring主干

class Demo{
    public static void main(String[] args){
        ClassPathXmlApplicationContext context =
                new ClassPathXmlApplicationContext("applicationContext.xml");
        DemoService service = (DemoService)context.getBean("demoService");
        // service CRUD 业务逻辑
    }
}

以上是使用Spring的基操,创建ClassPathXmlApplicationContext,指定xml配置路径。

先来看一下ApplicationContext的命名,很有意思,看名字,基本上就可以猜出功能,将ClasspathXmlApplicationContext分割为Classpath、Xml、ApplicationContext,Classpath说明是在classpath文件目录下,xml表示配置的类型;再看一下父类FileSystemXmlApplicationContext,说明是文件系统下的xml配置,后面大家可以去看看其他的,是不是也有这个规律。

​ 接下来,进入我们的重头戏refresh方法【refresh方法在AbstractApplicationContext类】温馨提示:看源码主要看主干,先了解主干,再到细节

​ 首先,我们先看下注释,这里提到加载配置信息,这个方法实现了接口,我们看下接口上对这个方法的解释,一般接口上的方法都有注释,用来说明它的功能。refresh方法是用来加载配置的,我们来看下它如何加载的。

​ 我们先总体浏览一下refresh这个方法

public final void refresh() throws ApplicationContextException, BeansException {
		if (this.contextOptions != null && !this.contextOptions.isReloadable())
			throw new ApplicationContextException("Forbidden to reload config");

		refreshBeanFactory();

		// invoke configurers that can override values in the bean definitions
		invokeContextConfigurers();

		// load options bean for this context
		loadOptions();

		// initialize message source for this context
		initMessageSource();

		// initialize other special beans in specific context subclasses
		onRefresh();

		// check for listener beans and register them
		refreshListeners();

		// instantiate singletons this late to allow them to access the message source
		preInstantiateSingletons();

		// last step: publish respective event
		publishEvent(new ContextRefreshedEvent(this));
	}

​ 判断contextOptions是否为null,是否可以加载,先记住有这么一个东西,往后看你就会知道它是做什么的?

​ 获取当前时间,这个不重要,我们先删掉

​ 接下来是refreshBeanFactory,通过名字猜测刷新bean工厂,那我们点进去看一下注释,子类需要实现实现这个方法,完成配置的加载,而且这个方法必须在其他初始化动作之前完成。

​ 下面打印日志的,我们直接跳过

​ 再往后走是invokeContextConfigurers,先看下注释,(停顿一下),回调修改Bean定义信息的配置,具体是什么,我们后面再详细讲解,先有个印象就可以

​ 下一个是loadOptions,这个看不出是做什么用的,点进去看一下,这个方法做了什么。发现创建了一个类,这个类在哪里用呢,我们搜一下,发现这个类在refresh方法一进来的时候的判断条件,通过注释也可以很清楚地了解到,就是在运行的过程中,能不能重新加载配置信息,也就是能不能重复调用refresh方法。

​ 继续往下走是initMessageSource,通过注释看不出是做什么用的,不过没关系,要记住我们现在是了解refresh的总体过程,这个看不懂的先跳过,后面回过头来一个方法一个方法讲,

​ 再往下就是onRefresh方法,还是老规矩,先看注释,子类实现的初始化一些特殊的bean,点进去看下,发现是空方法,说明在这里没有实现,相当于是一个钩子函数,给自己去做一些特殊的操作。高版本的WebServer就是在这里加载,有兴趣的小伙伴可以先去看一看。

​ 往后再走一步到refreshListeners,通过方法名字 + 注释可以了解到,就是检查和加载监听器。

​ 再往后走到preInstantiateSingletons,实例化单例,这个方法是重点,后面会详细讲。

​ 接下来到最后一步,发送ContextRefreshedEvent事件。

总结:

​ 第一步:刷新BeanFactory,加载配置,当前是XML

​ 第二步:提供修改Bean定义信息的回调函数

​ 第三步:允不允许重复加载配置,也就是重复调用refresh方法

​ 第四步:初始化消息源,

​ 第五步:给子类去实现,初始化特殊的bean

​ 第六步:检查和加载监听器

​ 第七步:初始化单例

​ 第八步:发送上下文完成刷新的事件

上一期:1、Spring是什么
下一期:3、工厂方法模式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值