Ioc容器(1)XML 解析

IoC容器的初始化流程分析 前言:本文参考了《Spring核心内幕 - 深入解析Spring架构与设计原理(第2版)》一书,结合笔者对源码的阅读得到的关于Spring IoC容器初始化流程的理解。一、什么是控制反转(IoC,Inversion of Control)?    在进入正题之前,首先我们有必要先了解一下控制反转这个概念,“反转”的是什么?为什么要进行控制反转?1.传统的对象依赖关系管理public class M... 阅读详情

/**

*针对某个Element进行操作

*/

 

public interface ElementReader {

 

    /**

     * 判断一个bean元素是否需要延迟加载

     */

    boolean isLazy(Element element);

   

    /**

     * 获得一个bean元素下的constructor-arg

     */

    List<Element> getConstructorElements(Element element);

   

    /**

     * 得到元素属性为name的属性值

     */

    String getAttribute(Element element, String name);

   

    /**

     * 判断一个元素是否为单态

     */

    boolean isSingleton(Element element);

   

    /**

     * 获得一个bean元素下所有property元素

     */

    List<Element> getPropertyElements(Element element);

   

    /**

     * 返回一个bean元素对应的Autowire对象

     */

    Autowire getAutowire(Element element);

   

    /**

     * 获取bean元素下所有constructor-arg的值(包括value和ref)

     */

    List<DataElement> getConstructorValue(Element element);

   

    /**

     * 获取bean元素下所有property元素的值(包括value和ref)

     */

    List<PropertyElement> getPropertyValue(Element element);

}

 

 

public class ElementLoaderImpl implements ElementLoader {

 

    private Map<String, Element> elements = new HashMap<String, Element>();

 

    /**

     * 将某个DOC下的elements全都加进MAP中

     */

 

    public void addElements(Document doc) {

       List<Element> eles = doc.getRootElement().elements();

       for (Element e : eles) {

           String id = e.attributeValue("id");

           elements.put(id, e);

       }

    }

 

    /**

     * 得到指定ID的ELEMENT

     */

 

    public Element getElement(String id) {

       return elements.get(id);

    }

   

/**

     * 得到ROOT下的所有ELEMENTS

     */

    public Collection<Element> getElements() {

       return this.elements.values();

    }

   

}

beans 节点:根节点为 beans,beans 的属性有 default-lazy-init 和 autowire,这两个属性的默认值(不需要显式提供)为 false 和 no。

bean 节点:beans 下面有多个 bean 节点,bean 节点必须要显式提供 id 和 class 属性,可以不必显式提供 lazy-init,singleton 和 autowire 属性,lazy-init 的默认值为 default,表示该值由beans 的 default-lazy-init 来决定,singleton 的默认值为 true,而且只允许有 true 和 false 两个值,autowire 属性的默认值是 default,由 beans 的 default-autowire 来决定。

construct-arg 节点:ref、value 和 null 都可以作为该节点的子节点,该节点没有属性。 property 节点:ref、value 和 null 都可以作为该节点的子节点,property 节点有一个 name 属性,而且是必须指定的。

ref 节点:该节点没有子节点,只有一个必须指定的 bean 属性。

value 节点:value 节点只有一个 type 属性,用于指定该值的类型。

 

 

 

public class ElementReaderImpl implements ElementReader {

 

    @Override

    public boolean isLazy(Element element) {

       String lazy = getAttribute(element, "lazy-init");

       Element parent = element.getParent();

      

       Boolean  parentLazy =  new Boolean(getAttribute(parent, "default-lazy-init"));

      

       if(parentLazy){

           if("false".equals(lazy))

              return false;

           else

              return true;

       }else{

           if("true".equals(lazy))

              return true;

          

              return false;

       }

    }

 

    @Override

    public List<Element> getConstructorElements(Element element) {

       List<Element> children =  element.elements();

       List<Element> result = new ArrayList<Element>();

      

       for(Element e:children){

           if("constructor-arg".equals(e.getName())){

              result.add(e);

           }

       }

       return result;

    }

 

    @Override

    public String getAttribute(Element element, String name) {

       String value = element.attributeValue(name);

       return value;

    }

 

    @Override

    public boolean isSingleton(Element element) {

       Boolean singleton = new Boolean(getAttribute(element, "singleton"));

       return singleton;

    }

 

    @Override

    public List<Element> getPropertyElements(Element element) {

       List<Element> children = element.elements();

       List<Element> result = new ArrayList<Element>();

      

       for(Element e:children){

           if("property".equals(e.getName())){

              result.add(e);

           }

       }

       return result;

    }

 

    @Override

    public Autowire getAutowire(Element element) {

       String value = this.getAttribute(element, "autowire");

       String parentValue = this.getAttribute(element.getParent(), "default-autowire");

      

       if("no".equals(parentValue)){

           if("byName".equals(value))

              return new ByNameAutowire(value);

          

           return new NoAutowire(value);

       }

       else if("byName".equals(parentValue)){

           if("no".equals(value))

              return new NoAutowire(value);

          

           return new ByNameAutowire(value);

       }

       return new NoAutowire(value);

    }

 

    @Override

    public List<DataElement> getConstructorValue(Element element) {

      

       List<Element> cons = getConstructorElements(element);

       List<DataElement> result = new ArrayList<DataElement>();

      

       for(Element e:cons){

           List<Element> els = e.elements();

          

           DataElement  dataElement = getDataElement(els.get(0));

           result.add(dataElement);

       }

       return result;

    }

 

    private DataElement getDataElement(Element dataElement) {

      

      

       String name = dataElement.getName();

      

       if("value".equals(name)){

           String classTypeName = dataElement.attributeValue("type");

           String data = dataElement.getText();

           return new ValueElement(getValue(classTypeName,data));

       }else if("ref".equals(name)) {

           return new RefElement(this.getAttribute(dataElement, "bean"));

       }

       return null;

    }

 

    private Object getValue(String classTypeName, String data) {

      

       if(isType(classTypeName,"Integer"))

           return Integer.parseInt(data);

       else if(isType(classTypeName,"Boolean"))

           return Boolean.parseBoolean(data);

       else if(isType(classTypeName,"Long"))

           return Long.parseLong(data);

       else if(isType(classTypeName,"Short"))

           return Short.parseShort(data);

       else if(isType(classTypeName,"Double"))

           return Double.parseDouble(data);

       else if(isType(classTypeName,"Float"))

           return Float.parseFloat(data);

       else if(isType(classTypeName,"Character"))

           return data.charAt(0);

       else if(isType(classTypeName,"Byte"))

           return Byte.parseByte(data);

       else

           return data;

    }

 

    private boolean isType(String classTypeName, String type) {

       if (classTypeName.indexOf(type) != -1) return true;

       return false;

    }

 

    @Override

    public List<PropertyElement> getPropertyValue(Element element) {

       List<Element> properties = getPropertyElements(element);

       List<PropertyElement> result = new ArrayList<PropertyElement>();

      

       for(Element e:properties){

           List<Element> els = e.elements();

           DataElement dataElement = getDataElement(els.get(0));

           String propertyNameAtt = this.getAttribute(e, "name");

           PropertyElement pe = new PropertyElement(propertyNameAtt,dataElement);

           result.add(pe);

       }

      

       return result;

    }

 

}

 

 

 

public class XmlDocumentHolder implements DocumentHolder {

 

   

    private Map<String, Document> docs = new HashMap<String, Document>();

   

    @Override

    public Document getDocument(String filePath) {

       Document doc = this.docs.get(filePath);

       if(doc == null){

           this.docs.put(filePath, readDocument(filePath));

       }

       return this.docs.get(filePath);

    }

   

 

    private Document readDocument(String filePath) {

       try { 

       SAXReader reader = new SAXReader(true);

       reader.setEntityResolver(new IoCEntityResolver());

       File xmlFile = new File(filePath);

           Document doc = reader.read(xmlFile);

           return doc;

       } catch (Exception e) {

           e.printStackTrace();

           throw new DocumentException(e.getMessage());

       }

    }

 

 

}

 

 

Spring中的IOC容器的实现原理 缘起 通过前面的章节,我们知道了如何搭建spring源码的阅读环境,本篇文章主要了解Spring的IOC容器是如何实现的。 下面直接开始 IOC容器 我们可以通过一个简单的main方法来调试应用 跟踪进ClassPathXmlApplicationContext源码可以看到 这里主要做了3件事 动态确定使用哪个加载器加载配置文件 获取配置文件的路径 加载配置文件 我们直接看refresh()... 阅读详情

相关推荐

从零玩转GD32单片机CAN总线:手把手实战配置与源码解析

本文提供了一份基于GD32单片机的CAN总线实战入门指南。从硬件连接(GD32F103C8T6与TJA1050收发器)到软件配置,详细解析了CAN初始化、波特率计算、过滤器设置及中断收发等核心源码。通过手把手的回环测试示例与常见问题排查,帮助开发者快速掌握CAN总线通信的关键配置与调试技巧。

g5h6i7j的博客 481

IOC和DI(通过xml解析)

在本文章中主要介绍IOC和DI还XML的解析

一个学习的人的博客 250

从理论到实践:笛卡尔空间阻抗控制的实现挑战与变体解析

本文深入探讨了笛卡尔空间阻抗控制的核心原理、工程实现中的五大挑战及经典变体实战解析。通过详细的数学建模和实际案例分析,揭示了阻抗控制在工业机器人、医疗设备等领域的应用价值,特别是在力感知精度、动力学模型校准和实时计算等方面的关键技术突破。

weixin_30952535的博客 448

spring源码---IOC:解析xml

接着上一篇,写道refresh(),在这个方法里面有14个方法,加载流程,我们一个一个的进去看一看到底发生了什么。 第一个方法:prepareRefresh(); 功能:调用容器准备刷新的方法,获取容器的当前时间,同时给容器设置同步表示。 参考:https://www.cnblogs.com/feng-jq/p/10282179.html protected void prepareRefresh() { //切换到活动状态。 this.startupDate = System.current

阿七 381

Dify工作流实践—根据word需求文档编写测试用例到Excel中

文章介绍了用dify工作流实现从word需求文档到测试用例写入excel的详细落地过程

weixin_42476668的博客 5333

Ubuntu22.04下3分钟搞定GitHub加速:SwitchHosts+小鱼工具保姆级配置指南

本文提供Ubuntu22.04下快速解决GitHub下载超时问题的保姆级教程,通过SwitchHosts图形化工具和小鱼一键换源工具实现高效加速。详细步骤包括环境准备、工具安装配置及验证方法,帮助开发者轻松优化GitHub访问速度,提升工作效率。

weixin_29258297的博客 564

实现简单的 IOC 容器

最近在看Spring的源码,对依赖xml配置文件的IOC容器的实现部分阅读起来比较吃力。主要是因为自己对IOC实现机制不是很了解,于是萌生了按其原理实现一个简单的IOC容器,来以便自己对Spring 的 IOC 实现能有更深入的了解。 什么是 IOC IOC 是英文控制反转的缩写,是一种设计思想。对于Spring 框架来说,IOC 就是由 Spring 来负责对象的生命周期和对象间的关系。以前

老夫聊发少年狂 489

蓝牙学习笔记之HCI协议(一)

目录 协议浅述 HCI简介 HCI协议数据格式 HCI Command Packet HCI ACL Data Packet HCI Synchronous(SCO) Data Packet HCI Event Packet HCI命令和事件介绍 Inquiry command Write Local Name Command Read BD_ADDR Command H...

在云巅的博客 2万+

IOC实现之XML元素解析过程(四)

接着上篇文章我们继续来做构造器配置与属性配置的解析过程分析; 我们先来看看BeanDefinitionParserDelegate是怎么来解析构造属性配置的; public void parseConstructorArgElements(Element beanEle, BeanDefinition bd) { //拿到子元素集合 NodeList nl = beanEle.getC

打着吊瓶写代码的博客 597

46、聚类算法在智能交通数据分析中的应用

本文探讨了聚类算法在智能交通数据分析中的应用,介绍了K-均值算法、K-中心点算法和基于模型的聚类算法的基本原理及特点,并结合实际交通数据讨论了其应用场景与挑战。通过聚类分析,能够从海量交通数据中发现隐藏模式,为交通管理和规划提供科学依据。文章还展示了具体的案例分析和实现流程,为未来智能交通系统的发展提供了参考。

zz67890的博客 133

【Bug已解决】openclaw max turns reached / Tool calls exceeded limit — OpenClaw 最大轮次超限解决方案

OpenClaw 在执行过程中达到最大轮次限制任务未完成,本质是 --max-turns 设置过小或任务过于复杂。文中给出增加轮次、--continue 继续、分步执行等完整方案。

一键难忘的博客 5505

EntityResolver作用

EntityResolver是org.xml.sax包下的一个接口(InputSource也是) 1.1 何为 EntityResolver : 官方解释: 如果SAX应用程序实现自定义处理外部实体,则必须实现此接口, 并使用setEntityResolver方法向SAX 驱动器注册一个实例. 也就是说,对于解析一个xml,sax 首先会读取该xml文档上的声明,根据声明去寻找相应的

sicofield的专栏 5723

华为OD面试手撕真题 【合并相邻且相等的元素】多语言题解

华为OD面试高频手撕真题【合并相邻且相等的元素】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解。

qq_45776114的博客 547

ioc容器的实现方法有哪些_长文预警!Spring源码之IoC容器的基本实现

Spring源码之容器的基本实现概述Spring是一个开放源代码的设计层面框架,他解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用。Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson创建。简单来说,Spring是一个分层的JavaSE/EE full-stack(一站式) 轻量级开源框架。本文以Spring 5.1.X版本...

weixin_39825854的博客 509

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Spring之IOC容器

Spring之IOC容器从入门都手写源码

从基础到源码解析的学习记录 2146

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

IOC容器(详细讲解)

IOC容器(详细讲解) 一、IOC底层原理 二、IOC接口 三、Bean管理

酷小亚 1万+

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Spring IoC容器的概念以及基于XML的IoC装配【一万字】

基于最新Spring 5.x,详细介绍了Spring入门案例的搭建,以及基于XML的核心IoC机制的配置和使用。适合Spring初学者。

终生学习践行者 4601

spring6-IOC容器

IOC 是 Inversion of Control 的简写,译为“控制反转”,它不是一门技术,而是一种设计思想,是一个重要的面向对象编程法则,能够指导我们如何设计出松耦合、更优良的程序。

m0_62946761的博客 3284

Spring IoC容器

核心技术 发行版5.0.8 这一部分的指导文档覆盖了所有的完全集成到Spring框架中的技术。 这些技术中首要的便是Spring框架的控制反转(IoC)容器。Spring框架的IoC容器的全面的处理是与Spring的面向切面编程(AOP)的彻底实现紧密相关的。Spring框架拥有他自己的AOP框架,该技术在概念上是很容器理解的,并且成功的解决了在Java企业编程中的AOP需求的80%的点。 该框...

hongbochen1223的专栏 1万+

Spring IoC容器初始化源码(1)—容器初始化入口以及setConfigLocations设置容器配置信息【一万字】

基于最新Spring 5.x,对于基于XML的Spring IoC容器初始化过程中的setConfigLocations设置容器配置信息方法的源码进行了详细分析,最后给出了比较详细的方法调用时序图!

终生学习践行者 8986

深入解析Spring框架之IoC容器

IoC(Inversion of Control,控制反转)是一种编程原则,它的核心思想是将程序的控制权从组件内部转移到外部。在传统的程序设计中,组件(如类或模块)通常负责创建或查找其依赖的其他组件。而在IoC架构中,这些依赖关系由外部容器(如Spring IoC容器)来管理和注入,组件不再负责查找其依赖,而是依赖于外部容器来提供这些依赖。实例化Bean:IoC容器负责创建Java对象的实例。开发者可以通过配置文件或注解来指定哪些类应该被实例化。依赖注入:IoC容器通过依赖注入(Dependenc

鱼干的博客 3260

Spring3-IoC1-IoC容器、基于xml管理bean

IoC 是 Inversion of Control 的简写,译为“控制反转”,它不是一门技术,而是一种设计思想,是一个重要的面向对象编程法则,能够指导我们如何设计出松耦合、更优良的程序Spring 通过IoC 容器来管理所有 Java 对象的实例化和初始化,控制对象与对象之间的依赖关系。我们将由 IoC 容器管理的 Java 对象称为 Spring Bean,它与使用关键字 new 创建的 Java 对象没有任何区别控制反转是一种思想控制反转是为了降低程序耦合度,提高程序扩展力。

m0_73902080的博客 1329

Spring的IOC容器分析

Spring的IOC从入门到深入

caozhisanguo的专栏 4296

深入解析 Spring IOC 容器的初始化流程

掌握 IOC 容器的初始化流程是深入理解 Spring 框架的关键一步,也是开发高效、稳定的 Spring 应用的基础。

潜意识Java的博客 1477

Java-29 深入浅出 Spring - IoC 基础 启动IoC容器的方式 Java方式与Web(XML、配置)方式

Spring IoC 容器是 Spring 框架的核心,理解 BeanFactory 与 ApplicationContext 的区别是 Java 后端开发者的必修课。本文基于 Spring Framework 5.1.12.RELEASE(2019 年末发布的 5.1.x 稳定线版本,5.1.13.RELEASE 于 2020-01-14 作为最终维护版本发布),系统讲解两者的继承关系、功能差异和典型使用场景。BeanFactory 作为 IoC 容器顶层接口,提供延迟加载的 Bean 管理能力,适合底层

谢谢你的喜欢 我们一起无限进步 1万+
上一篇: N个鸡蛋M个篮子
下一篇: java知识架构
easyjsf
博客等级 码龄17年 19粉丝 82原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值