Spring实战系列(三)了解容器的基本实现

news2024/11/19 11:27:41

我们可以通过GitHub或者码云下载spring-framework源码,这边是基于5.X版本进行下载学习的。

地址:https://github.com/spring-projects/spring-framework

分析Spring源码是非常一件的难的事情,只能一步步学习,一步步记录。

       前面在第一章Spring整体架构中,bean是Spring中最核心的部分,在没有接触Spring的时候,我们使用bean是通过new 的方式进行创建,spring bean容器就是将这些对象交给spring去创建和管理,我们只需要在配置文件或者注解的方式告诉spring容器需要创建哪些bean对象。所以需要先在配置文件中定义好需要创建的bean对象,这些配置统称为bean定义配置元数据信息,spring容器通过读取这些bean配置元数据信息来构建和组装我们需要的对象,

我们通过一个入门案例来揭开Spring 容器是如何实现的

1.  创建一个简单的bean
public class TestBean {

    private String msg;

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}
2.  定义配置元数据信息,通过XML的方式
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="testBean" class="com.spring.demo.beans.TestBean">
        <property name="msg" value="put test bean msg"/>
    </bean>
</beans>
3.   测试通过Spring获取bean
public class TestBeanMain {
    @Test
    public void testBeanLoad(){
        //在3.2版本以后不推荐使用 这里方便了解Spring内部原理
        // spring主要有2个容器,一个BeanFactory 一个ApplicationContext,后者是前者一个扩展容器
        BeanFactory xmlBeanFactory = new XmlBeanFactory(new ClassPathResource("bean-config.xml"));
        TestBean testBean = (TestBean) xmlBeanFactory.getBean("testBean");
        System.out.println(testBean.getMsg());
    }
}

运行结果:

用于实现上面功能的是org.springframework.bean.jar
功能分析

     通过上面的一个简单案例,主要完成的功能步骤如下:

  • 读取配置文件bean-config.xml
  • 根据配置文件中的配置元信息找到对应类的配置,并进行反射实例化
  • 调用实例化的实例
源码分析
XmlBeanFactory对DefaultListableBeanFactory进行了扩展,主要用于从XML文档中读取BeanDefinition,注册和获取bean都是从父类通过继承的方式去实的。代码如下:

进入XmlBeanDefinitionReader类的loadBeanDefinitions方法,这是资源加载的真正实现。

	@Override
	public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
		// 对资源文件进行编码处理
		return loadBeanDefinitions(new EncodedResource(resource));
	}
	public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
		// 资源不可为空验证
		Assert.notNull(encodedResource, "EncodedResource must not be null");
		if (logger.isTraceEnabled()) {
			logger.trace("Loading XML bean definitions from " + encodedResource);
		}
        // 通过属性来记录已经加载过的资源
		Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
        // 添加失败抛出异常 当已存在
		if (!currentResources.add(encodedResource)) {
			throw new BeanDefinitionStoreException(
					"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
		}
		//从encodedResource中获取已经封装好的resource资源并从中获取inputStream
		try (InputStream inputStream = encodedResource.getResource().getInputStream()) {
			InputSource inputSource = new InputSource(inputStream);
			if (encodedResource.getEncoding() != null) {
				// 设置编码
				inputSource.setEncoding(encodedResource.getEncoding());
			}
			//真正进入加载核心内容
			return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
		}
		catch (IOException ex) {
			throw new BeanDefinitionStoreException(
					"IOException parsing XML document from " + encodedResource.getResource(), ex);
		}
		finally {
			//加载完记录中移除
			currentResources.remove(encodedResource);
			if (currentResources.isEmpty()) {
				this.resourcesCurrentlyBeingLoaded.remove();
			}
		}
	}
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
			throws BeanDefinitionStoreException {

		try {
			// 获取XML文件的验证模式,对XML进行加载并得到对应的Document
			Document doc = doLoadDocument(inputSource, resource);
			// 返回根据XML文件中注册bean的个数
			int count = registerBeanDefinitions(doc, resource);
			if (logger.isDebugEnabled()) {
				logger.debug("Loaded " + count + " bean definitions from " + resource);
			}
			return count;
		}
        //省略其他代码
		.......
	}

后续会对上面XML验证加载以及获取bean信息进行深入。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1338094.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

人工智能的弱点有哪些?

尽管人工智能&#xff08;Artificial Intelligence&#xff0c;AI&#xff09;在许多领域取得了巨大的进展和成就&#xff0c;但它仍然存在一些弱点和挑战。以下是人工智能的一些常见弱点&#xff1a; 1. 数据依赖性&#xff1a;人工智能算法通常需要大量的高质量数据进行训练…

每日一题(LeetCode)----二叉树-- 二叉树的右视图

每日一题(LeetCode)----二叉树-- 二叉树的右视图 1.题目&#xff08;199. 二叉树的右视图&#xff09; 给定一个二叉树的 根节点 root&#xff0c;想象自己站在它的右侧&#xff0c;按照从顶部到底部的顺序&#xff0c;返回从右侧所能看到的节点值。 示例 1: 输入: [1,2,3,nu…

flex--伸缩性

1.flex-basis flex-basis 设置的是主轴方向的基准长度&#xff0c;会让宽度或高度失效。 备注&#xff1a;主轴横向&#xff1a;宽度失效&#xff1b;主轴纵向&#xff1a;高度失效 作用&#xff1a;浏览器根据这个属性设置的值&#xff0c;计算主轴上是否有多余空间&#x…

微信小程序picker组件扩展选择时间到秒插件

创建插件seldatetime // 插件JS部分 Component({// 一些选项options: {// 样式隔离&#xff1a;apply-shared 父影响子&#xff0c;shared父子相互影响&#xff0c; isolated相互隔离styleIsolation:"isolated",// 允许多个插槽multipleSlots: true},// 组件的对外属…

k8s的二进制部署(一)

k8s的二进制部署&#xff1a;源码包部署 环境&#xff1a; k8smaster01: 20.0.0.71 kube-apiserver kube-controller-manager kube-schedule ETCD k8smaster02: 20.0.0.72 kube-apiserver kube-controller-manager kube-schedule Node节点01: 20.0.0.73 kubelet kube-pr…

2008年AMC8数学竞赛中英文真题典型考题、考点分析和答案解析

今天我们来看看2008年AMC8竞赛的五道典型考题。欢迎您查看历史文章了解之前各年的真题解析&#xff0c;本系列会持续更新&#xff0c;直到大家参加完2024年的比赛。您有任何关于AMC8比赛的任何问题都可以问我&#xff0c;关于题目的解析也可以交流。 【推荐】为帮助孩子们更便…

人工智能_机器学习076_Kmeans聚类算法_体验_亚洲国家队自动划分类别---人工智能工作笔记0116

我们开始来看聚类算法 可以看到,聚类算法,其实就是发现事物之间的,潜在的关联,把 有关联的数据分为一类 我们先启动jupyter notebook,然后 我们看到这里我们需要两个测试文件 AsiaFootball.txt里面记录了,3年的,亚洲足球队的成绩

C语言转WebAssembly的全流程,及测试

第一步&#xff1a;安装环境 参考网址&#xff1a;https://emscripten.org/docs/getting_started/downloads.html 具体过程&#xff1a; 克隆代码&#xff1a;git clone https://github.com/emscripten-core/emsdk.git进入代码目录&#xff1a;cd emsdk获取最新远端代码&…

阿赵UE学习笔记——5、创建关卡元素

阿赵UE学习笔记目录 大家好&#xff0c;我是阿赵。   之前介绍了从空白模板创建关卡&#xff0c;接下来尝试着在这个空白的世界里面&#xff0c;创建一些内容。 一、创建地面 1、创建面片作为地面 创建——形状——平面&#xff0c;可以创建一个面片 在细节面板设置合适的…

深入了解云原生:定义与特征解析

文章目录 一、云原生概述1.1 什么是云原生1.2 云原生组成要素1.3 补充资料 二、云原生的目标2.1 云原生关键目标2.2 云原生特性 三、云原生应用 VS 传统单体应用参考资料 一、云原生概述 1.1 什么是云原生 (1)云原生定义 云原生(Cloud Native) 是一种软件架构和开发方法论&a…

云计算IaaS、PaaS和SaaS之

提供的服务来比较如下两图 示例图 示例图

PYTHON基础:决策树与随机森林算法

决策树与随机森林算法 决策树和随机森林都是用于分类和回归的的算法。决策树的原理是通过一系列的问题进行if、else的推导。随机森林是集合学习算法&#xff0c;即把很多的机器学习算法综合在一起组成一个更大的模型。 决策树的优劣势&#xff1a;处理容易&#xff0c;不需要…

DS八大排序之归并排序和计数排序

前言 前几期我们详细介绍了插入排序&#xff08;直接插入排序和希尔排序&#xff09;、选择排序&#xff08;直接选择和堆排序&#xff09;、交换排序&#xff08;冒泡排序和快速排序&#xff09;。并对快排的各个版本做了详细的介绍&#xff0c;本期我们来介绍把最后两个即外…

关于“Python”的核心知识点整理大全41

目录 scoreboard.py game_functions.py game_functions.py 14.3.8 显示等级 game_stats.py scoreboard.py scoreboard.py scoreboard.py game_functions.py game_functions.py alien_invasion.py 14.3.9 显示余下的飞船数 ship.py scoreboard.py 我们将最高得分圆整…

大数据与人工智能|全面数字化战略与企业数字化转型(第1节 )

要点一&#xff1a;培养跨学科思维 在分析时&#xff0c;需要采用多学科的思维方式 结果不重要&#xff0c;重要的是如何提炼现象、分析问题和得出结论的过程。 1. 介绍了锤子精神和多学科思维方式的重要性。指出了只从自身学科出发解决问题的局限性。 2. 提倡跨学科思维方式&a…

家校互通小程序实战开发02首页搭建

目录 1 创建应用2 搭建首页总结 我们上一篇介绍了家校互通小程序的需求&#xff0c;创建了对应的数据源。有了这个基础的分析之后&#xff0c;我们就可以进入到开发阶段了。开发小程序&#xff0c;先需要创建应用。 1 创建应用 登录控制台&#xff0c;点击创建应用&#xff0c…

2024年深度学习、计算机视觉与大模型面试题综述,六大专题数百道题目

DeepLearning-Interview-Awesome-2024 本项目涵盖了大模型(LLMs)专题、计算机视觉与感知算法专题、深度学习基础与框架专题、自动驾驶、智慧医疗等行业垂域专题、手撕项目代码专题、优异开源资源推荐专题共计6大专题模块。我们将持续整理汇总最新的面试题并详细解析这些题目&a…

元宇宙与VR虚拟现实的未来如何?

从科幻小说到商业现实 自从 Facebook年更名为 Meta 以来&#xff0c;关于元宇宙的热议不断&#xff0c;人们对虚拟世界的兴趣也重新燃起&#xff0c;因为尽管虚拟现实 (VR) 的概念由来已久&#xff0c;但该技术现在才开始真正得以应用。 定义元宇宙和虚拟现实 首先是 The Met…

玩客云 青龙面板

一、刷机 需要的工具&#xff0c;镊子&#xff0c;双公头USB&#xff08;可以自己做&#xff09;&#xff0c;U盘 青龙面板全教程 | Anubis的小窝 powersee教程 玩客云导航固件使用说明 安装教程 玩客云乱七八糟的坑 静态IP配置 玩客云第二版固件说明 docker 下载器 …

摇杆控制人物移动

摇杆控制人物移动 一、UI搭建二、3d模型搭建三、脚本JoyStickBar.csPlayerController.cs 工程在我资源里名字叫Joystickbar.unitypackage [连接](https://download.csdn.net/download/qq_42194657/12043019?spm1001.2014.3001.5503) 一、UI搭建 JoyStickBar是图片背景 JoySt…