Spring的学习(上)

1、Spring的Beans.xml

 一个beans.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">

    <!--配置一个Monster对象-->
    <!--
        1. 配置monster对象/javaBean
        2. 在beans中可以配置多个bean
        3. bean表示就是一个java对象
        4. class属性是用来指定类的全路径(因为底层是使用反射创建对象)
        5. id属性表示该java对象在Spring容器中的ID,通过ID可以获取到该对象
        6. <property name="monsterId" value="100"/> 用于给该对象的属性赋值
    -->
    <bean class="com.hspedu.spring.bean.Monster" id="monster01">
        <property name="monsterId" value="100"/>
        <property name="name" value="牛魔王"/>
        <property name="skill" value="芭蕉扇"/>
    </bean>

</beans>

获取Bean对象的过程:

    @Test
    public void getMonster() {

        // 1. 创建容器 ApplicationContext 该容器和容器配置文件关联
        ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");

        // 2. 通过getBean获取对应的对象
        // 默认返回Object 运行类型肯定是Monster
        Object monster01 = ioc.getBean("monster01");

        // 3. 输出
        System.out.println(monster01); // Monster{monsterId=100, name='牛魔王', skill='芭蕉扇'}
        System.out.println(monster01.getClass()); // 运行类型 class com.hspedu.spring.bean.Monster

        // 4. 也可以在获取的时候直接指定Class类型
        Monster monster = ioc.getBean("monster01", Monster.class);
        System.out.println(monster); // Monster{monsterId=100, name='牛魔王', skill='芭蕉扇'}

    }

getBean的运行流程:

获取容器中的所有BeanID:

1.1、自定义一个容器HspApplicationContext

自己写一个简单的Spring容器,通过读取beans.xml, 获取第一个JavaBean:Monster对象,并给该对象赋值,放入到容器中,输出该对象的信息

流程:

  • 先解析beans.xml
  • 得到第一个bean的信息,beanID、Class、属性、属性值
  • 使用反射生成对象,并赋值
  • 将创建好的bean对象,放入到singletonObjects集合中
  • 提供getBean(id)可以返回对应的bean对象

bean.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">

    <!--配置一个Monster对象-->
    <!--
        1. 配置monster对象/javaBean
        2. 在beans中可以配置多个bean
        3. bean表示就是一个java对象
        4. class属性是用来指定类的全路径(因为底层是使用反射创建对象)
        5. id属性表示该java对象在Spring容器中的ID,通过ID可以获取到该对象
        6. <property name="monsterId" value="100"/> 用于给该对象的属性赋值
    -->
    <bean class="com.hspedu.spring.bean.Monster" id="monster01">
        <property name="monsterId" value="100"/>
        <property name="name" value="牛魔王"/>
        <property name="skill" value="芭蕉扇"/>
    </bean>

    <bean class="com.hspedu.spring.bean.Monster" id="monster02">
        <property name="monsterId" value="1001"/>
        <property name="name" value="牛魔王1"/>
        <property name="skill" value="芭蕉扇1"/>
    </bean>

</beans>

Java代码:

package com.hspedu.spring.hspapplicationcontext;

import com.hspedu.spring.bean.Monster;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Author: lihaojie
 * @Description:
 * 1、这个程序用于实现Spring的一个简单容器机制
 * 2、后面还会详细的实现
 * 3、这里我们实现如何将beans.xml文件进行解析并生成对应对象放入到容器在中
 * 4、提供一个方法 getBean(String id) 返回对应的对象
 * @DateTime: 2024/1/29 15:14
 **/
public class HspApplicationContext {

    private ConcurrentHashMap<String, Object> singletonObjects = new ConcurrentHashMap<>();

    // 构造器接收一个容器的配置文件 比如beans.xml 该文件默认在src下
    public HspApplicationContext(String iocBeanXmlPath) throws Exception {
        // 1、得到类加载路径
        String path = this.getClass().getResource("/").getPath();
        // 2、使用dom4j读取 创建saxReader
        SAXReader saxReader = new SAXReader();
        // 3、得到文档对象Document
        Document document = saxReader.read(new File(path + iocBeanXmlPath));
        // 4、得到rootDocument
        Element rootElement = document.getRootElement();
        // 5、得到第一个bean
        Element bean = (Element) rootElement.elements("bean").get(0);
        // 6、把id class 属性 都拿出来
        String id = bean.attributeValue("id");
        String classFullPath = bean.attributeValue("class");
        List<Element> property = bean.elements("property");
        // 直接获取
        Map<String, String> kvs = new HashMap<>();
        for (Element element : property) {
            String name = element.attributeValue("name");
            String value = element.attributeValue("value");
            kvs.put(name, value);
        }
        // 7、使用反射创建对象
        Class<?> aClass = Class.forName(classFullPath);
        // 这里的o对象就是Monster对象
        Monster monster = (Monster)aClass.newInstance();
        // 用反射来赋值
        Field[] declaredFields = aClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            if (kvs.containsKey(declaredField.getName())) {
                declaredField.setAccessible(true);
                declaredField.set(monster, kvs.get(declaredField.getName()));
            }
        }
        // 8、放进容器
        singletonObjects.put(id, monster);
    }

    public Object getBean(String id) {
        return singletonObjects.get(id);
    }

}

1.2、Spring原生容器结构整理

思考:如果beans.xml中不去配id,会不会报错呢?

答案是不会,会正常运行,系统会默认分配ID,分配ID的规则:

全类名#0,全类名#1 这样的规则来分配ID

可以通过Debug的方式查看:

1.3、Spring配置Bean的基本介绍

Bean的管理分为两方面:

  • 创建bean对象
  • 给bean注入属性

1.4、从容器中获取bean的方式

1.4.1、按照类型去获取

案例:通过Spring的ioc容器,获取一个bean对象,获取bean的方式要求按照类型获取

但是,如果同类型的bean定义了两个,就会报错,看下面的例子:

这种使用Type赋值的场景有:

  • XXXAction/Servlet/Controller/XXXService 在一个线程中只需要一个对象实例的情况
  • 在容器配置文件中(比如beans.xml)中给属性赋值,底层是通过setter方法完成的,这也是为什么我们需要提供setter方法原因,没有setter运行会报错的

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

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

相关文章

树莓派Pico入门

文章目录 1. Pico概述1.1 微处理器1.2 GPIO引脚1.3 MicroPython优点 2. 硬件准备2.1 购买清单2.2 软件需求 3. 安装MicroPython3.1下载固件3.2把固件安装到硬件里3.3补充 4. 第一个程序5. 验证运行效果6. 扩展应用 1. Pico概述 1.1 微处理器 ARM Cortex-M0 (频率 133MHz) 1.…

代码随想录算法训练营第43天 | 1049.最后一块石头的重量 II + 494.目标和 + 474.一和零

今日任务 1049. 最后一块石头的重量 II 494. 目标和 474.一和零 1049.最后一块石头的重量 II - Medium 题目链接&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 有一堆石头&#xff0c;用整数数组 stones 表示。其中 stones[i] 表示…

高速接口PCB布局指南(五)高速差分信号布线(三)

高速接口PCB布局指南&#xff08;五&#xff09;高速差分信号布线&#xff08;三&#xff09; 1.表面贴装器件焊盘不连续性缓解2.信号线弯曲3.高速信号建议的 PCB 叠层设计4.ESD/EMI 注意事项5.ESD/EMI 布局规则 tips&#xff1a;资料主要来自网络&#xff0c;仅供学习使用。 …

Android:国际化弹出框

3.13 风格与主题、国际化 1、应用国际化 应用国际化,通过修改系统语言,应用显示语言跟着改变。 选择Locale,点击>>符号。 创建多个国家,地区strings.xml文件,有一个默认strings.xml文件,各个stirngs.xml中<string>标签中保持一致。 示例: 创建t_language.…

Linux 问题的故障定位

主要介绍各种问题定位的工具以及会结合案例分析问题 1. 分析问题 What-现象是什么样的 When-什么时候发生 Why-为什么会发生 Where-哪个地方发生的问题 How much-耗费了多少资源 How to do-怎么解决问题 2. cpu 针对应用程序&#xff0c;我们通常关注的是内核CPU调度…

【翻译】 Processing的安卓项目构建(译者用的是Android Studio)

原文链接&#xff1a;https://github.com/processing/processing-android/wiki/Building-Processing-for-Android&#xff0c;版本Apr 2, 2023 译者声明&#xff1a;这个文档是开源公开的&#xff0c;协议是GNU协议。译者自己得使用这个文档&#xff0c;所以才翻译的&#xff0…

java SpringBoot2.7整合Elasticsearch(ES)7 进行文档增删查改

首先 我们在 ES中加一个 books 索引 且带有IK分词器的索引 首先 pom.xml导入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency>applicatio…

立足智能存取解决方案|HEGERLS智能托盘四向车储存制动能量 实现能源回收

对于商业配送和工业生产的企业而言&#xff0c;如何能高效率、低成本进行低分拣、运输、码垛、入库&#xff0c;用以提升仓库空间的利用效率&#xff0c;是现在大多企业急需要解决的行业痛点。对此&#xff0c;为了解决上述痛点&#xff0c;近年来&#xff0c;物流仓储集成商、…

orin nx 安装paddlespeech记录

nx配置&#xff1a; 模块 版本说明 CPU 8核 内存 16G Cuda版本 11.4 Opencv版本 4.5.4 Tensorrt版本 5.1 Cudnn版本 8.6.0.166 Deepstream版本 6.2 Python版本 3.8 算力 100T 安装paddlepaddle&#xff1a; 去飞桨官网下载jetpack版本的&#xff1a;下…

Docker关于conda环境的导出和导入

Docker关于conda环境的导出和导入 1、常用命令&#xff1a;2、环境导出&#xff1a;3、两个服务器之间的文件传输命令&#xff1a;4、环境导入&#xff1a;5、快速进入容器6、其他问题解决记录&#xff1a; 1、常用命令&#xff1a; docker pull -- 从远程仓库将镜像下载至本地…

HDFS架构 之 服务视图

1 、简介 为实现以上特性,HDFS包含的各个服务模块都是经过精心设计的,HDFS的服务视图如图。 HDFS的服务视图包含三大部分:核心服务、公共服务和拓展服务。 2、 核心服务 1)Namenode。HDFS系统采用中心化设计,即Master/Slave架构。这里的Namenode即是Master,主要作用是管…

瑞_力扣LeetCode_二叉树相关题

文章目录 说明题目 144. 二叉树的前序遍历题解 题目 94. 二叉树的中序遍历题解 题目 145. 二叉树的后序遍历题解 题目 105. 从前序与中序遍历序列构造二叉树题解 题目 106. 从中序与后序遍历序列构造二叉树题解 &#x1f64a; 前言&#xff1a;本文章为瑞_系列专栏之《刷题》的…

基于微信小程序的学生公寓宿舍电费管理系统的研究与实现

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

c++多态(1) -- 子类型及什么是多态

目录 代码分析: 代码中我们使用了三种方式: 为什么子类对象可以赋值给父类对象? 子类型的传递性: 使用父类的指针指向子类的对象: 总结: 子类型和多态的联系及什么是多态 那父类指针指向子类对象的用处在哪? 子类型: 从名字看就知道和继承有关。 子类型…

Windows 版Oracle 数据库(安装)详细过程

首先到官网上去下载oracle64位的安装程序 第一步&#xff1a;将两个datebase文件夹解压到同一目录中。 当下载完成后,它里面是两个文件夹 win64_11gR2_database_1of2, win64_11gR2_database_2of2,我们需要把其中的一个database文件夹整合在一起(复制一个database文件夹到另一…

2024.02.07

总结C类中的继承&#xff0c;虚继承&#xff0c;多态等概念&#xff08;画思维导图&#xff09;

政安晨:机器学习快速入门(四){pandas与scikit-learn} {随机森林}

咱们将在这篇文章中使用更复杂的机器学习算法。 随机森林 基本定义 随机森林(Random Forest)是一种机器学习算法&#xff0c;属于集成学习(ensemble learning)的一种。它是通过构建多个决策树&#xff08;即森林&#xff09;来进行预测和分类的。 随机森林的主要特点是采用了…

如何配置Pycharm服务器并结合内网穿透工具实现远程开发

&#x1f525;博客主页&#xff1a; 小羊失眠啦. &#x1f3a5;系列专栏&#xff1a;《C语言》 《数据结构》 《Linux》《Cpolar》 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;…

Idea Git Review插件

idea git plugin 添加了一些常用的小插件 可以右键打开git bash窗口 可以右键选中文字点击baidu fanyi 可以通过搜索git用户名 指定开始时间查询某个版本自己提交的所有代码文件 可以通过点击蓝色行数&#xff0c;跳转到指定的改动代码块 资源地址&#xff1a; git-pl…

【C语言 - 力扣 - 反转链表】

反转链表题目描述 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 题解1-迭代 假设链表为 1→2→3→∅&#xff0c;我们想要把它改成 ∅←1←2←3。 在遍历链表时&#xff0c;将当前节点的 next 指针改为指向前一个节点。由于节点没…