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

文章目录

    • 概要
    • 根据需求编写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.mfbz.cn/a/884220.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

蓝桥杯【物联网】零基础到国奖之路:十二. TIM

蓝桥杯【物联网】零基础到国奖之路:十二. TIM 第一节 理论知识第二节 cubemx配置 第一节 理论知识 STM32L071xx器件包括4个通用定时器、1个低功耗定时器&#xff08;LPTIM&#xff09;、2个基本定时器、2个看门狗定时器和SysTick定时器。 通用定时器&#xff08;TIM2、TIM3、…

Spring Cloud Alibaba-(6)Spring Cloud Gateway【网关】

Spring Cloud Alibaba-&#xff08;1&#xff09;搭建项目环境 Spring Cloud Alibaba-&#xff08;2&#xff09;Nacos【服务注册与发现、配置管理】 Spring Cloud Alibaba-&#xff08;3&#xff09;OpenFeign【服务调用】 Spring Cloud Alibaba-&#xff08;4&#xff09;Sen…

数据分析工具julius ai如何使用

什么是julius ai Julius AI 是一款强大的ai数据分析工具。用户可以使用excel、数据库、文本文件等多种格式的数据&#xff0c;Julius AI 会自动分析这些数据并提供详细的解释和可视化图表。官网显示它目前已经有三十万用户。它也支持手机版。 虽然openai也支持生成图表&#xf…

asp.net core grpc快速入门

环境 .net 8 vs2022 创建 gRPC 服务器 一定要勾选Https 安装Nuget包 <PackageReference Include"Google.Protobuf" Version"3.28.2" /> <PackageReference Include"Grpc.AspNetCore" Version"2.66.0" /> <PackageR…

项目实战:k8s部署考试系统

一、新建nfs服务器&#xff08;192.168.1.44&#xff09; 1.基础配置&#xff08;IP地址防火墙等&#xff09; 2.配置时间同步 [rootlocalhost ~]# yum -y install ntpdate.x86_64 [rootlocalhost ~]# ntpdate time2.aliyun.com 27 Sep 10:28:08 ntpdate[1634]: adjust tim…

MySql在更新操作时引入“两阶段提交”的必要性

日志模块有两个redo log和binlog&#xff0c;redo log 是引擎层的日志&#xff08;负责存储相关的事&#xff09;&#xff0c;binlog是在Server层&#xff0c;主要做MySQL共嗯那个层面的事情。redo log就像一个缓冲区&#xff0c;可以让当更新操作的时候先放redo log中&#xf…

node.js npm 安装和安装create-next-app -windowsserver12

1、官网下载windows版本NODE.JS https://nodejs.org/dist/v20.17.0/node-v20.17.0-x64.msi 2、安装后增加两个文件夹目录node_global、node_cache npm config set prefix "C:\Program Files\nodejs\node_global" npm config set prefix "C:\Program Files\nod…

基于SpringBoot的新冠检测信息管理系统的设计与实现

文未可获取一份本项目的java源码和数据库参考。 国内外在该方向的研究现状及分析 新型冠状病毒肺炎疫情发生以来&#xff0c;中国政府采取积极的防控策略和措施&#xff0c;经过两个多月的不懈努力&#xff0c;有效控制了新发病例的増长&#xff0c;本地传播已经趋于完全控制…

Mysql高级篇(中)——锁机制

锁机制 一、概述二、分类1、读锁2、写锁★、FOR SHARE / FOR UPDATE&#xff08;1&#xff09;NOWAIT&#xff08;2&#xff09;SKIP LOCKED&#xff08;3&#xff09;NOWAIT 和 SKIP LOCKED 的比较 ★、 脏写3、表级锁之 S锁 / X锁&#xff08;1&#xff09;总结&#xff08;2…

自动化学习3:日志记录及测试报告的生成--自动化框架搭建

一.日志记录 1.配置文件pytest.ini&#xff1a;将日志写入文件方便日后查询或查看执行信息。 需要将文件处理器&#xff08;文件存放位置/时间/格式等等&#xff09;添加到配置文件中的【日志记录器】 # pytest.ini [pytest] # ---------------日志文件&#xff0c;需要配合…

PMP--二模--解题--141-150

文章目录 14.敏捷--创建敏捷环境--团队构成--混合项目环境&#xff0c;通常是自组织团队&#xff0c;即团队成员自己决定谁做什么&#xff0c;而不是项目经理决定。易混--常见场景--一个新人加入141、 [单选] 在一个混合项目的执行过程中&#xff0c;不得不更换一个开发人员。新…

微软Win11 22H2/23H2 九月可选更新KB5043145发布!

系统之家于9月27日发出最新报道&#xff0c;微软针对Windows11系统&#xff0c;发布了九月最新可选更新补丁KB5043145&#xff0c;22H2用户安装后&#xff0c;系统版本号升至22621.4249&#xff0c;23H2用户安装后升至22631.4249。本次更新修复了Edge使用IE模式有时会停止响应等…

腾讯云SDK产品功能

本文主要介绍音视频终端 SDK&#xff08;腾讯云视立方&#xff09;的核心功能。 直播推流 音视频终端 SDK&#xff08;腾讯云视立方&#xff09;为终端直播场景提供强大的 RTMP、RTC 推流能力&#xff0c;配合云直播&#xff08;CSS&#xff09;全球布局的2000节点&#xff0…

GreenPlum数开手册【语法篇】

GreenPlum数开手册 一、数据类型 1、基本数据类型 类型长度描述范围bigint8字节大范围整数-9223372036854775808 到 9223372036854775807smallint2字节小范围整数-32768到32767integer(int)4字节常用整数-2147483648 到 2147483647decimal可变长用户指定的精度&#xff0c;精…

ARM_5_UART总线接口实验

一、总线相关的概念 1.1、总线的含义 定义&#xff1a;总线是不同设备间通信的桥梁 比如&#xff1a; PC ---------------- UART总线------------------ SOC SOC&#xff08;stm32mp157a&#xff09; --------------- IIC总线 ---------------- 空气温湿度芯片&#xff0…

【C++报错已解决】std::ios_base::failure

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 专栏介绍 在软件开发和日常使用中&#xff0c;BUG是不可避免的。本专栏致力于为广大开发者和技术爱好者提供一个关于BUG解决的经…

“JY901传感器“学习笔记

目录 一、产品概述 二、产品功能介绍 2.1、轴向说明 2.2、模块校准 2.3、姿态角 2.4、大地坐标系、地心地固坐标系、站心坐标系 三、参考文献 一、产品概述 模块集成高精度的陀螺仪、加速度计、地磁场传感器&#xff0c;采用高性能的微处理器和先进的动力解算与卡尔曼动…

征程6 上基于 DEB 工具实现包管理

1.引言 在开发、调测过程中&#xff0c;开发人员需要将系统软件、应用软件部署到 Soc 板端&#xff0c;以用于运行调试。传统的部署方式是通过解压复制或者调用部署脚本。这样的部署方式需要有着方式不统一、维护投入大的缺点。 在 linux 系统上&#xff0c;大多采用包管理的…

罕见,回复问询后闪电终止,业绩存下滑风险

《IPO魔女》认为&#xff0c;和美精艺利润低且大幅波动&#xff0c;报告期公司毛利率持续大幅下滑。而2023年同行业的上市公司均出现了业绩大幅下滑的情况&#xff0c;还未上市的和美精艺恐怕也存在业绩下滑的风险。此外&#xff0c;2020年至2022年&#xff0c;和美精艺研发投入…

docker的harbor仓库登录问题

目录 一、问题描述 二、证书信任问题 三、DNS解析问题 四、解决 参考链接&#xff1a;Docker login Harbor报错解决&#xff1a;Error response from daemon: Get https:..-阿里云开发者社区 一、问题描述 问题&#xff1a; 挂机或者挂机重启之后harbor登录不上 查看日…