Spring Ioc底层原理代码详细解释

news2024/12/24 20:44:16

文章目录

    • 概要
    • 根据需求编写XML文件,配置需要创建的bean
    • 编写程序读取XML文件,获取bean相关信息,类,属性,id
    • 前提知识点Dom4j
    • 根据第二步获取到的信息,结合反射机制动态创建对象,同时完成属性赋值
    • 将创建好的bean存入到Map集合,设置key-value映射
    • 提供方法从Map中通过id获取到对象的value

概要

文章是看楠哥的视频做的总结,加上自己一些补充,为了方便以后的复习
视频地址

Spring ioc核心技术
xml解析和反射

根据需求编写XML文件,配置需要创建的bean

实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Car {
    private Integer num;
    private String brand;
}

xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       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="car1" class="network.hylnetwork.entity.Car">
        <property name="num" value="1"></property>
        <property name="brand" value="奥迪"></property>
    </bean>
    <bean id="car2" class="network.hylnetwork.entity.Car">
        <property name="num" value="2"></property>
        <property name="brand" value="奥拓"></property>
    </bean>
</beans>

编写程序读取XML文件,获取bean相关信息,类,属性,id

前提知识点Dom4j

DOM4J简介
DOM4J是 dom4j.org 出品的一个开源 XML 解析包。DOM4J应用于 Java 平台,采用了 Java 集合框架并完全支持 DOM,SAX 和 JAXP。

DOM4J 使用起来非常简单。只要你了解基本的 XML-DOM 模型,就能使用。

Dom:把整个文档作为一个对象。

DOM4J 最大的特色是使用大量的接口。

了解更多参考:Dom4j完整教程详解

导入dom4j依赖

<!--        dom4j-->
        <dependency>
            <groupId>dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>1.6.1</version>
        </dependency>

仿写ClassPathXmlApplicationContext实现ApplicationContext

public class MyClassPathXmlApplicationContext implements ApplicationContext{

}

实现ApplicationContext的方法
在这里插入图片描述
测试能否获取xml文件,在MyClassPathXmlApplicationContext添加无参构造和parseXMl方法

 public MyClassPathXmlApplicationContext(String path){
        parseXML(path);
    }
    public void  parseXML(String path){
        SAXReader saxReader = new SAXReader();
        try {
            Document document = saxReader.read("src/main/resources/"+path);//看提示
            System.out.println(document);
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }

测试类

public class Test {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new MyClassPathXmlApplicationContext("spring-ioc.xml");
    }
}

成功获取xml文件,也就是我们获取到了spring-ioc.xml文件,如下运行结果在这里插入图片描述提示因为路径不完整,需要手动拼接不完整部分项目路径,否则就会出现如下错误)可以看到缺少了“src/main/resources/”部分,所以我们手动拼接上

org.dom4j.DocumentException: G:\AllSpace\IdeaSpace\Spring\spring-ioc.xml (系统找不到指定的文件。) Nested exception: G:\AllSpace\IdeaSpace\Spring\spring-ioc.xml (系统找不到指定的文件。

获取根节点,也就是我们xml文件中的beans

 public void  parseXML(String path){
        SAXReader saxReader = new SAXReader();
        try {
            Document document = saxReader.read("src/main/resources/"+path);//看提示
            Element rootElement = document.getRootElement();
            System.out.println(rootElement);
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }

运行结果如下
在这里插入图片描述

xml解析就像剥洋葱一样,是一层一层往下走的
获取根节点的迭代器,其实也就是为了得到beans中的bean

 public void  parseXML(String path){
        SAXReader saxReader = new SAXReader();
        try {
            Document document = saxReader.read("src/main/resources/"+path);//看提示
            Element rootElement = document.getRootElement();
            Iterator<Element> rootIter = rootElement.elementIterator();//根节点迭代器
            while (rootIter.hasNext()){
                Element bean = rootIter.next();//获取bean
                System.out.println(bean);
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }

运行结果如下
将beans中的两个bean都获取到了在这里插入图片描述在这里插入图片描述
获取到bean之后就是获取bean的类、属性、id信息

  public void  parseXML(String path){
        SAXReader saxReader = new SAXReader();
        try {
            Document document = saxReader.read("src/main/resources/"+path);//看提示
            Element rootElement = document.getRootElement();
            Iterator<Element> rootIter = rootElement.elementIterator();//根节点迭代器
            while (rootIter.hasNext()){
                Element bean = rootIter.next();//获取bean
                String idstr = bean.attributeValue("id");  //获取bean中的id
                String className = bean.attributeValue("class");  //获取bean中的class
                System.out.println(idstr);
                System.out.println(className);
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }

结果如下
在这里插入图片描述
可以看到和xml配置文件中的信息相匹配
在这里插入图片描述
获取属性 也就是bean中的property

  给属性赋值
                Iterator<Element> beanIter = bean.elementIterator();
                while (beanIter.hasNext()){
                    Element property = beanIter.next();
                    System.out.println(property);
                }

结果如下
在这里插入图片描述
对应了四个property
在这里插入图片描述

根据第二步获取到的信息,结合反射机制动态创建对象,同时完成属性赋值

//              反射动态创建对象
                Class clazz = Class.forName(className);
                Constructor constructor = clazz.getConstructor();

将创建好的bean存入到Map集合,设置key-value映射

  private Map<String,Object> iocMap; //创建map集合

    public MyClassPathXmlApplicationContext(String path){
        iocMap = new HashMap<>(); 
        parseXML(path);
    }
    public void  parseXML(String path){
        SAXReader saxReader = new SAXReader();
        try {
            Document document = saxReader.read("src/main/resources/"+path);//看提示
            Element rootElement = document.getRootElement();
            Iterator<Element> rootIter = rootElement.elementIterator();//根节点迭代器
            while (rootIter.hasNext()){
                Element bean = rootIter.next();//获取bean
                String idstr = bean.attributeValue("id");  //获取bean中的id
                String className = bean.attributeValue("class");  //获取bean中的class
//              反射动态创建对象
                Class clazz = Class.forName(className);
                Constructor constructor = clazz.getConstructor();
                Object object = constructor.newInstance();
                iocMap.put(idstr,object); //将bean存入map集合中,设置key-value映射
            }
        } catch (DocumentException | ClassNotFoundException | NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

提供方法从Map中通过id获取到对象的value

修改getBean方法

  @Override
    public Object getBean(String s) throws BeansException {
        return iocMap.get(s);
    }

测试类

public class Test {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new MyClassPathXmlApplicationContext("spring-ioc.xml");
        Object car1 = applicationContext.getBean("car1");
        System.out.println(car1);
    }
}

运行结果如下
在这里插入图片描述

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

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

相关文章

【移植】标准系统方案之扬帆移植案例

往期知识点记录&#xff1a; 鸿蒙&#xff08;HarmonyOS&#xff09;应用层开发&#xff08;北向&#xff09;知识点汇总 鸿蒙&#xff08;OpenHarmony&#xff09;南向开发保姆级知识点汇总~ 持续更新中…… 本文章是基于瑞芯微RK3399芯片的yangfan开发板&#xff0c;进行标准…

一些写论文必须要知道的神仙级网站!芝士AI(paperzz)

说实话&#xff0c;写论文真的是挺头疼&#xff0c;尤其到了毕业季的时候&#xff0c;没有过任何写作毕业论文的经验的毕业生而言更是如此&#xff0c;相信大家都有过这种状态&#xff0c;不知从何下笔&#xff0c;还需要面对论文进度的压力&#xff0c;并且时常需要寻找各种资…

HDF5文件浏览软件--H5View

概述 H5View是一款轻量级桌面软件&#xff0c;旨在提供用户友好的界面以读取和展示 HDF5 文件中的数据结构。该软件允许用户查看文件的数据目录和数据集&#xff0c;并支持将选定的数据集导出为多种格式。 功能特点 读取 HDF5 文件 支持打开和读取 HDF5 格式的文件。显示文件…

Lenovo SR850服务器亮黄灯维修和升级CPU扩展模块

佛山市三水区某高校1台Lenovo Thinksystem SR850服务器黄灯故障到现场检修 和 升级3号和4号CPU。加强服务器的计算性能&#xff1b; 故障情况是该学校it管理员这一天看到这台SR850服务器前面板亮了一个黄灯&#xff0c;但是目前系统运行正常&#xff0c;出于安全考虑&#xff0…

JavaFX 如何加载系统资源

简介 问题描述&#xff1a;JavaFX 加载图片资源异常&#xff0c;即使路径正确 如何解决&#xff1a;使用反射 API 如何解决 import javafx.scene.image.Image; import org.junit.jupiter.api.Test;import java.util.Objects;public class ImageTest {Testvoid name() {Image…

golang web笔记-1.创建Web Server和Handler请求

1. 创建http web server的两个方法 1.1. 方式一&#xff1a;http.ListenAndServe(addr string, handler Handler) addr string&#xff1a;监听地址&#xff0c;如果为"" ,那么就是所有网络接口的80接口handler Handler&#xff1a;如果为nil&#xff0c;那么就是D…

TypeScript 设计模式之【状态模式】

文章目录 状态模式&#xff1a;优雅切换的交通信号灯状态模式的奥秘状态模式有什么利与弊?如何使用状态模式来优化你的系统代码实现案例状态模式的主要优点状态模式的主要缺点状态模式的适用场景总结 状态模式&#xff1a;优雅切换的交通信号灯 当你站在繁忙的十字路口&#…

RabbitMQ 实验入门

使用 spring-amqp 实验 发布订阅模型 fanoutExchange 实验 实验步骤&#xff1a; 编写定义 队列 和 交换机 绑定关系的代码创建接口&#xff0c;模拟生产者&#xff0c;方便调试&#xff08;接受参数 队列名、路由键、[消息]&#xff09;定义消费者 代码示例&#xff1a; C…

证件照制作小程序源码

预览&#xff1a; 证件照制作小程序官方有推出对应的api接口&#xff0c;也有demo示例&#xff0c;大家有需要的可以直接拿 证件照规格列表 接口地址&#xff1a;https://api.zheyings.cn/item/list 请求方式&#xff1a;POST(application/x-www-form-urlencoded) 返回格式&…

DERT目标检测—End-to-End Object Detection with Transformers

DERT&#xff1a;使用Transformer的端到端目标检测 论文题目&#xff1a;End-to-End Object Detection with Transformers 官方代码&#xff1a;https://github.com/facebookresearch/detr 论文题目中包括的一个创新点End to End(端到端的方法&#xff09;简单的理解就是没有使…

Elixir求解螺旋矩阵问题

题目是构造一个 n 维的顺时针螺旋矩阵&#xff0c;那么什么是螺旋矩阵呢&#xff1f;就是从左上角开始按顺时针方向从外向内依次递增的二维矩阵。一个3维螺旋矩阵示例如下&#xff1a; 我们是在 elixir 中求解&#xff0c;没有变量&#xff0c;没有循环&#xff0c;但是我们有…

中国篆刻—孙溟㠭浅析碑帖《张黑女墓志》

中国篆刻——孙溟㠭浅析碑帖《张黑女墓志》 《张黑女墓志》 《张黑女墓志》全称是《魏南阳张玄墓志》&#xff0c;又称《张玄墓志》&#xff0c;是北魏时期的墓志&#xff0c;属正书体&#xff0c;北魏普泰元年&#xff08;公元531年&#xff09;立碑。原碑已经丢失&#xf…

5个最佳开源RPA框架之一UI.Vision介绍

博主介绍&#xff1a; 大家好&#xff0c;我是Yuperman&#xff0c;互联网宇宙厂经验&#xff0c;17年医疗健康行业的码拉松奔跑者&#xff0c;曾担任技术专家、架构师、研发总监负责和主导多个应用架构。技术范围&#xff1a; 目前专注java体系&#xff0c;以及golang、.Net、…

【ADC】SAR 型 ADC 和 ΔΣ ADC 的选型决策方法

本文学习于TI 高精度实验室课程&#xff0c;介绍如何选择 SAR 或 delta-sigma 型 ADC。 文章目录 一、选型决策树二、特定传感器的应用三、需要 DC 精度但分辨率较低的应用四、需要 DC 精度且分辨率较高的应用五、极低噪声的 DC 精密测量六、需要捕获瞬态信号值的应用七、需要高…

产品需求-聊天框中发送的文件,要求文件名过长是保留后缀名省略中间的文字部分

介绍一下之前做过的一个需求&#xff0c;是要实现pc的一个聊天软件的消息引用功能。对于文件的引用&#xff0c;产品是这样做要求的&#xff1a; 消息框无固定长度&#xff0c;根据回复的文字长度决定消息框长度对于一个pc项目&#xff0c;当页面窗口变化时要实现响应式文件名…

个人账号(学校+个人)申请专利过程中遇见的问题

一、请指定一位申请人作为代表人 因为是拿个人账号申请的专利&#xff0c;同时要求学校是第一申请人&#xff0c;所以可以再添加一个第二申请人&#xff0c;然后勾选第二申请人为代表人就可以提交申请了&#xff08;注意&#xff1a;两个申请人只能减免75%&#xff0c;也就是要…

Kubernetes配置管理(kubernetes)

实验环境&#xff1a; 在所有节点上拉取镜像&#xff1b;然后把资源清单拉取到第一个master节点上&#xff1b; 同步会话&#xff0c;导入镜像&#xff1a; configmap/secret 配置文件的映射 变量&#xff1a; 基于valuefrom的方式 cm--》pod 特点&#xff1a;变量的名称可…

109.游戏安全项目:信息显示二-利用游戏通知辅助计算基址

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a;易道云信息技术研究院 本人写的内容纯属胡编乱造&#xff0c;全都是合成造假&#xff0c;仅仅只是为了娱乐&#xff0c;请不要盲目相信…

C++之二叉搜索

1.二叉搜索树的概念 二叉搜索树又称为二叉排序树&#xff0c;它有以下的特点。 1.如果它的左子树不为空&#xff0c;则左子树上所以结点的值都小于等于根结点的值 2.如果它的右子树不为空&#xff0c;则右子树上所有结点都大于等于根结点的值 3.它的左右子树也分别为二叉搜…

Lab1:虚拟机kolla安装部署openstack,并创建实例

实验内容&#xff1a; 创建并配置虚拟机安装OpenStack创建镜像创建实例类型选择网络配置创建实例 1、选择一个适合你的系统的虚拟机管理软件&#xff1a; VirtualBox &#xff08;推荐&#xff09; VMWare 其他 2、下载 .iso 镜像文件 openstack S 版本 iso 链接&#xff1…