Spring核心 and 创建使用

news2024/9/23 5:25:38

Spring核心 and 创建使用

文章目录

  • Spring核心 and 创建使用
    • 一、Spring的定义
      • 1.1什么是IoC
        • 1.1.1 理解控制反转(IoC)
        • 1.1.2 控制反转式程序开发
      • 1.2 使用Spring IoC核心功能
      • 2.1 DI的概念说明
    • 二、Spring的创建和使用
      • 2.1 创建一个Maven项目
      • 2.2 添加Spring框架支持(依赖)
      • 2.3 创建一个启动类(普通的类)和 main
    • 三、将 Bean 存储到 Spring 容器中(重要)
      • 3.1、 先创建一个 Bean
      • 3.2.将 Bean 存储到 Spring 中(将 Bean 注册到容器)
    • 四、获取并使用 bean对象
      • ApplicationContext vs BeanFactory
      • getBean()方法说明
    • 五、Spring创建使用总结

本篇内容核心:

1、Spring 是什么,如何理解Spring

2、IoC和DI是什么,有什么区别?

3、Spring最核心的功能是什么?

一、Spring的定义

​ Spring Framework(Spring 框架)通常指的是 Spring,Spring是一个开源框架,有着活跃庞大的社区,Spring支持广泛的应用场景,他可以让java企业级的应用程序开发起来更简单。

1.1什么是IoC

​ Spring是一个容器,何为容器?(指用来容纳某种物品的装置)

  • List/Map -> 数据存储容器;
  • Tomcat -> Web容器

Spring是IoC的一个容器 ,IoC(Inversion of Control)“控制反转” ,也就是说Spring是一个 “控制反转” 的容器!!!

1.1.1 理解控制反转(IoC)

举一个栗子说明:

​ 以构建一辆 车 的程序,传统的实现思路是:

​ 构建一辆车首先 需要依赖车身,车身需要依赖底盘,底盘需要依赖轮胎;程序代码如下:

image-20230703141930709


 public class CarDemo {
    public static void main(String[] args) {
        Car car = new Car();
        car.run();
    }

    /**
     * 汽车对象
     */
    static class Car {
        public void run() {
            // 需要依赖车身
            Framework framework = new Framework();
            framework.run();
        }
    }

    /**
     * 车身类
     */
    static class Framework {

        public void run() {
            // 需要依赖轮胎
            Bottom bottom = new Bottom();
            bottom.run();
        }
    }

    /**
     * 底盘类
     */
    static class Bottom {
        public void run() {
            // 依赖轮胎
            Tire tire = new Tire();
            tire.run();
        }
    }

    /**
     * 轮胎类
     */
    static class Tire {
        // 尺寸
        private int size = 20;
        public void run() {
            System.out.println("轮胎尺寸:"+ size);
        }
    }
}

这上面的代码虽说可以实现这个车的构造,但是耦合性太强了,随时要依赖另一个对象,再者加上轮胎的需求尺寸是会越来越多,改变也会越来越频繁,然而上面的代码是固定尺寸,如果说需要修改尺寸,先看看修改尺寸的代码:

public class CarDemo {
    public static void main(String[] args) {
        Car car = new Car(30);
        car.run();
    }

    /**
     * 汽车对象
     */
    static class Car {
        private Framework framework;
        public Car (int size) {
            // 需要依赖车身
             framework = new Framework(size);
        }
        public void run() {
            framework.run();
        }
    }

    /**
     * 车身类
     */
    static class Framework {
        public Bottom bottom;
        public Framework (int size) {
            // 需要依赖轮胎
             bottom = new Bottom(size);
        }
        public void run() {
            bottom.run();
        }
    }

    /**
     * 底盘类
     */
    static class Bottom {
        private Tire tire;
        public Bottom (int size) {
            // 依赖轮胎
             tire = new Tire(size);
        }

        public void run() {
            tire.run();
        }
    }

    /**
     * 轮胎类
     */
    static class Tire {
        // 尺寸
        private int size;
        public Tire(int size) {
            this.size = size;
        }
        public void run() {
            System.out.println("轮胎尺寸:"+ size);
        }
    }
}

​ 可见,一旦需要改需求那么整个程序都会受到影响,都要整体改一遍,增加工作量,增加错误率。

解决传统开发的缺陷:

​ 其中重要的思想就是 解藕 。由上面代码可知,我们在每个类里面都创建了下级类,当发生需求改变,就会整个代码改变;此时我们只需要将原来自己创建下级类,改为传递的方式(注入的方式),如果需求改变,就不需要在当前类中创建修改下级类,故下级类即使发生改变也不需要在当前类本身上面修改,这样就可以完成 “解耦”

1.1.2 控制反转式程序开发

​ 基于以上思想 “解耦” ,我们把创建子类的方式,改为注入传递的方式,具体代码如下:

public class CarDemo {
    public static void main(String[] args) {
        Tire tire = new Tire(40);
        Bottom bottom = new Bottom(tire);
        Framework framework = new Framework(bottom);
        Car car = new Car(framework);
        car.run();
    }

    /**
     * 汽车对象
     */
    static class Car {
        private Framework framework;
        public Car (Framework framework) {
            this.framework = framework;
        }
        public void run() {
            framework.run();
        }
    }

    /**
     * 车身类
     */
    static class Framework {
        public Bottom bottom;
        public Framework (Bottom bottom) {
            this.bottom = bottom;
        }
        public void run() {
            bottom.run();
        }
    }

    /**
     * 底盘类
     */
    static class Bottom {
        private Tire tire;
        public Bottom (Tire tire) {
            this.tire = tire;
        }

        public void run() {
            tire.run();
        }
    }

    /**
     * 轮胎类
     */
    static class Tire {
        // 尺寸
        private int size;
        public Tire(int size) {
            this.size = size;
        }
        public void run() {
            System.out.println("轮胎尺寸:"+ size);
        }
    }
}

​ 经过了代码的调整,无论底层如何变化,中间的程序都没有发生任何改变,这样就可以完成解耦,让需求,程序更加灵活了。

对比总结:

传统代码对象创建顺序是:car->Framework->Bottom->Tire

改进之后解耦代码对象创建顺序:Tire->Bottom->Framework->car

image-20230706161805197

现在就可以发现一个规律,类的创建是相反的,经过解耦的改变,控制权发生了改变,之前的控制权是以车car为主,现在是先以轮胎Tire为主;不再是上级对象创建控制下级对象,而是下级对象把需求注入将 当前对象中 ,这样下级的控制权不再是上级控制了,即使下级类发生了改变,当前类也不会受影响的,这就是典型的“控制反正(IoC)”,也就是IoC的实现思想。

1.2 使用Spring IoC核心功能

​ Spring最核心的总结:Spring是包含了多个工具方法的IoC容器

❓❓如何理解“Spring 是一个IoC(控制反转) 容器”

​ 重点还是在 容器 二字,这个容器具有两个最基础的功能。

  • 将对象存入容器中;{存}
  • 从容器中取出对象;{取}

那么学Spring最核心的功能,就是学如何将对象存入Spring中,再从Spring中获取对象的过程

好处:

  • 将对象存储在IoC容器相当于将以后可能用到的所有工具制作好放入仓库中。
  • 需要的时候再出来拿,用完后再放回去

new对象相当于纯手工制作,每次需要工具现做,用完扔掉也不会保存,下次用还要重新做,很麻烦。这就是IoC容器和普通重新开发的区别。

📖📖最后总结:

​ Spring是一个IoC容器,对象的创建和销毁的权利都交给Spring来管理,它本身又具备了存储对象和获取对象的能力

2.1 DI的概念说明

​ DI(Dependency Injection),翻译成中文是**“依赖注入” ** ;依赖注入,就是由IoC容器在运行期间,动态的将某种依赖关系注入到对象之中。指通过引入IoC容器,利用依赖关系注入的方式,实现对象之间的“解耦”。

乍一看 DI和IoC好像说的是同一件事情,实则从不同角度来描述的同一件事情。

就好比日常生活中的内存,大家都说手机内存256G或者说128G,实则说的是手机总的外存储容量,内存是指运行内存一般是8G或者16G。

  • 广义:IoC=DI 从不同角度来描述同一件事情
  • 微观:IoC描述的是目标,DI描述的是具体可实现的思路

栗子:

目标指:晚上出去是去吃好吃的。

可实现的思路指:海底捞,火锅,烧烤…


这篇文章重点(也是面试容易问的):

1、Spring是什么,如何理解Spring

​ 答:Spring是包含众多工具方法的IoC容器。

2、IoC和DI是啥,有什么区别

​ 答:IoC是“控制反转”,DI是“依赖注入”

3、Spring最核心的功能是什么?

​ 答:具备了存储对象和获取对象的能力(存,取)。


二、Spring的创建和使用

2.1 创建一个Maven项目

image-20230706220131030

image-20230706220602010

2.2 添加Spring框架支持(依赖)

在项目pom.xml 中添加Spring框架的支持

重要的依赖:

  • spring-context (上下文)
  • spring-beans (管理对象模块)

xml配置如下:

<dependencies>
   <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.2.3.RELEASE</version>
    </dependency>
  
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>5.2.3.RELEASE</version>
    </dependency>
</dependencies>

image-20230706221924908

2.3 创建一个启动类(普通的类)和 main

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C0uiPMw6-1688779813804)(D:\常用文件夹\资料信息图片\Typora-image\Image\image-20230706222736675.png)]


三、将 Bean 存储到 Spring 容器中(重要)

3.1、 先创建一个 Bean

Bean 也称为 “对象” ,提到Bean就是对象的意思。

就是创建一个对象:

image-20230706223610083

3.2.将 Bean 存储到 Spring 中(将 Bean 注册到容器)

​ a)、在 Maven项目中的resources 底下创建一个 xxx(名字可以随意取).xml

里面Spring的配置文件是可以保存的,是固定格式,保存到自己能找到的地方

<?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">

    
</beans>

image-20230706224311158

​ b)、在xml中添加一个 bean,就是将刚刚创建的User对象注册到Spring中,具体操作是在 中添加。

image-20230706225112768

这里面有两个重要的属性:

  • id:是在spring中的一个身份标识,之后就是用这个身份标识完成代码
  • class:指存储对象的路径,一般是完整包名+类名

到这里就是Spring Ioc容器里面核心重要的一个“存”操作

四、获取并使用 bean对象

ApplicationContext获取上下文

1、获取Spring 上下文对象。对象都交给了Spring管理,故获取对象要从Spring中获取,那么首先需要先创建Spring上下文,再得到Spring上下文。

//1 .创建上下文需要配置spring配置信息(得到 Spring上下文)
        ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("spring.xml");

2、使用上下文对象获得一个bean。

User user = (User) applicationContext.getBean("user");//根据 bean id来获取

这段代码没有 new 对象,是从Spring里面拿出的bean,这里就体现了Spring的价值了

3、使用 bean

user.对象的方法;

BeanFactory获取上下文

​ 这是获取 Spring 上下文的第二种方法

BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("spring.xml"));

里面的参数也是与 resources 里面的xml对应的,这是最古老的方式。

BeanFactory beanFactory1 = new ClassPathXmlApplicationContext("spring.xml");

ClassPathXmlApplicationContext 也是可以的

💀💀💀完整代码:

public class App {
    public static void main(String[] args) {
         //第二种获取Spring 上下文的方法是 BeanFactory
        BeanFactory beanFactory = new XmlBeanFactory(
                new ClassPathResource("spring.xml")
        ); //这是最古老的方式

        User user = (User) beanFactory.getBean("user");
        user.saihi();
    }
}

​ 尽然都是一样的获取上下文对象,那他们的区别又是哪里尼?

ApplicationContext vs BeanFactory

**1、**性能方面:ApplicationContext 是 一次性加载并初始化 xml 里面所有 bean 对象(在当前的 Spring 项目里面);BeanFactory 是按需求进行初始化(按照代码的调用,getBean(bean id))。故ApplicationContext 就会初始化慢,但是调用快(都初始化好了直接取出就行),BeanFactory 初始化快,但是调用慢。

ApplicationContext applicationContext =new ClassPathXmlApplicationContext("spring.xml"); // 创建并初始化所有 bean 对象

ApplicationContext 在这里就已经创建并初始化所有 bean 对象。

BeanFactory beanFactory1 = new ClassPathXmlApplicationContext("spring.xml");
User user = (User) beanFactory.getBean("user"); //真正创建 User 对象

BeanFactory 在下一步去 getBean 的时候采取创建对象。

**2、**二者的归属关系不同:ApplicationContext 输入 BeanFactory 的子类。

3、 二者的功能不同:BeanFactory 提供了基础操作 Bean 访问容器的功能: ApplicationContext 继承了BeanFactory,它除了有操作 Bean 的基础功能之外,还提供了更多的功能,如国际化的支持,事件的传播,资源访问等功能。

总结:“取”操作

image-20230706232707786

getBean()方法说明

​ getBean() 主要有三种使用的方法:

  • getBean(String s)----------- Object
  • getBean(class aClass)------------------T
  • getBean(String s, Class aclass)-----------------T

image-20230708083812368

  • 第一种是根据 bean id 获取的 Object 对象 (需要类型的强转)。对应代码:
User user = (User) beanFactory.getBean("user");
  • 第二种是根据类型获取 bean ,无需强装类型。对应代码:
User user = beanFactory.getBean(User.class);

特点:写法简单,但是如果 Spring 里面将一个对象注入多次,那么使用此方法就会导致程序异常。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XUsKGYAC-1688779813805)(D:\常用文件夹\资料信息图片\Typora-image\Image\image-20230708090518469.png)]

  • 第三种指的是 bean id ,还有bean类型 ☆☆☆☆
User user = beanFactory.getBean("user",User.class);

这种方法就解决了上面两种方法的缺点,不用强转类型,也不用担心一个对象在 Spring 里面注入多次而报错,大多数使用的就是第三种方法。


五、Spring创建使用总结

image-20230708092224687


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

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

相关文章

解决在jupyter notebook中找不到pip安装后的库

解决在jupyter notebook中找不到已安装的库

Todo-List案例版本二

(160条消息) Todo-List案例版本一_bubbleJessica的博客-CSDN博客 引入了localStorage&#xff0c;让案例更加完善 src/App.vue <template><div id"root"><div class"todo-container"><div class"todo-wrap"><MyHe…

pycharm 打开终端,安装第三方程序

鼠标移动到左下角 弹出列表&#xff0c;选择终端&#xff0c;当然也可以用快捷键唤出&#xff0c; 可以输入命令进行第三方库的安装

Redis实战案例14-分布式锁的基本原理、不同实现方法对比以及基于Redis进行实现思路

1. 分布式锁基本原理 基于数据库的分布式锁&#xff1a;这种方式使用数据库的特性来实现分布式锁。具体流程如下&#xff1a; 获取锁&#xff1a;当一个节点需要获得锁时&#xff0c;它尝试在数据库中插入一个特定的唯一键值&#xff08;如唯一约束的主键&#xff09;&#xff…

vue 进阶---动态组件 插槽 自定义指令

目录 动态组件 如何实现动态组件渲染 使用 keep-alive 保持状态 keep-alive 对应的生命周期函数 keep-alive 的 include 属性和exclude属性 插槽 插槽的基础用法 具名插槽 作用域插槽 自定义指令 自定义指令的分类 私有自定义指令 全局自定义指令 了解 eslint 插件…

mysql 单表查询练习

mysql 单表查询练习 创建数据表代码 CREATE TABLE emp (empno int(4) NOT NULL,ename varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,job varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,mgr int(4) NULL DEFAU…

附件上传报java.lang.RuntimeException: java.nio.file.NoSuchFileException的问题

1、报错信息 java.lang.RuntimeException: java.lang.RuntimeException: java.nio.file.NoSuchFileException: /tmp/undertow.5113172416389412561.31101/undertow1781128540461109448upload 2、原因 Java项目以java -jar命令启动后&#xff0c;进行文件上传的操作&#xff0c…

android 测试google pay

1、到GooglePlay后台创建商品&#xff0c;需要注意的是要创建商品必须先发布一个带有Billing库的aab到GooglePlay&#xff08;测试渠道即可&#xff09; 2、获取并配置好商品id之后&#xff0c;将测试用的aab发布到内部测试&#xff0c;并添加测试人员的邮箱。 3、通过连接分享…

获取系统时间日期相关接口梳理

时间&日期 ##MyTime.hpp #pragma once #include <iostream> #include <ctime> #include <string>using namespace std;class MyTime { public:MyTime() {};~MyTime() {};time_t timeSec(void);uint64_t timeMs(void);string timeDate(void); };##MyTim…

端口监控:HHD Device Monitoring Studio Crack

设备监控工作室 监控、记录和分析流经 PC 端口和连接的数据 设备监控工作室 Device Monitoring Studio 是一款高性能非侵入式软件解决方案&#xff0c;用于监控、记录和分析通过 PC 端口和连接传入的数据。 在其开发过程中&#xff0c;我们特别注重所有数据拦截和处理算法的优化…

qt实现信息管理系统(学生信息管理系统)功能更完善

一、代码地址 信息系统代码地址&#xff1a;https://gitee.com/dxl96/StdMsgSystem 二、基本说明 本学生信息管理系统同升级改造的幅度较大&#xff0c;涉及到的东西对于初学者来说&#xff0c;可能稍显复杂&#xff0c;可以先移步到 https://blog.csdn.net/IT_CREATE/artic…

SWAT模型十八个案例教程

详情点击链接&#xff1a;SWAT模型十八个案例教程案例一&#xff1a;基于网络资源的SWAT模型快速建模 案例二&#xff1a;基于遥感产品的SWAT模型率定与验证 案例三&#xff1a;基于水文响应单元&#xff08;HRU&#xff09;的水资源时空分布特征 案例四&#xff1a;基于自定义…

【代码随想录day4】链表相交

题目 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点&#xff0c;返回 null 。 图示两个链表在节点 c1 开始相交&#xff1a; 题目数据 保证 整个链式结构中不存在环。 注意&#xff0c;函数返回结果后&a…

基于Java网络安全宣传网站设计实现(源码+lw+部署文档+讲解等)

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

硬件性能 - CPU瓶颈分析

简介 本文章通过CPU各个指标项来简单分析是否出现CPU硬件性能瓶颈。其他硬件分析如下&#xff1a; 1. 硬件性能 - 掌握内存知识 2. 硬件性能 - 磁盘瓶颈分析 3. 硬件性能 - 网络瓶颈分析 目录 1. 系统负载 2. CPU利用率 3. 中断占用 4. 上下文切换 1. 系统负载 系统负载是…

【Windows】Redis单机部署

下载redis 下载地址&#xff1a;Releases microsoftarchive/redis GitHub 1、下载后解压&#xff0c;在文件根目录下创建两个文件夹dbcache、logs 修改配置文件redis.windows.conf &#xff08;1&#xff09;配置redis地址&#xff1a; bind 127.0.0.1 &#xff08;2&am…

M62429L音量控制IC驱动

前言 最近项目开发中&#xff0c;要控制AV端的音量&#xff0c;由于主控端的AV音量控制gpio被复用为其它功能口了&#xff0c;不得已增加一个ic去控制音量的输出&#xff0c;这里使用的是M62429L音量控制IC。 1.M62429音量ic概述 M62429L是一款串行数据控制的双声道电子音量控…

用图来理解group by、where、having、聚合函数使用

基本概念&#xff1a; 常用聚合函数&#xff1a;count、max、min、avg、sum&#xff0c;对一整体数据进行计算group by&#xff1a;用来分组where&#xff1a;条件查询having&#xff1a;分组后条件查询 疑问&#xff1a; group by配合聚合函数和where配合聚合函数有什么不同…

【数据结构】24王道考研笔记——串

四、串 串的定义 串&#xff08;字符串&#xff09;是由零个或多个字符组成的有限序列。 子串&#xff1a;串中任意个连续的字符组成的子序列主串&#xff1a;包含子串的串字符在主串中的位置&#xff1a;字符在串中的序号子串在主串中的位置&#xff1a;子串的第一个字符在…

Mysql8安装教程与配置

添加密码 出现报错 MySQL error 1042: Unable to connect to any of the specified MySQL hosts. Failed to connect to MySQL Server 8.0.23 after 10 attempts. Ended configuration step: Starting the server 使用WinR --> 运行 “services.msc” --> 打开service服…