【Spring】什么是Spring?

什么是Spring?

Spring是一个开源的轻量级框架,是为了简化企业级开发而设计的。我们通常讲的Spring一般指的是Spring Framework。Spring的核心是控制反转(IoC-Inversion of Control)和面向切面编程(AOP-Aspect-Oriented Programming)。这些功能使得开发者可以专注于业务逻辑的实现,不用去关注底层的实现。除此之外,Spring还可以与第三方库和框架集成,如Mybatis等,使得我们开发更加方便。

我们来看看官方的解释:

Spring | Why Spring

可以看到,spring包含了很多模块,简单来说:Spring是包含了很多工具方法的IoC容器

什么是容器?

Spring容器是Spring框架中的核心组成部分,负责管理Spring Bean的生命周期和依赖关系,Spring容器是一个BeanFactory(Bean工厂),负责实例化、配置和管理Bean。

在Spring程序中,我们所有的Bean都是存放在容器中,通过IoC(控制反转)技术进行管理。Spring容器通过自动装配(autowiring)的方式将各个Bean之间建立联系,从而减少手动配置的工作量。同时,Spring容器还提供了丰富的扩展机制,使得开发者可以根据自己的需求对bean进行定制化配置。

什么是IoC?

Spring IoC(控制反转),是一种设计思想,通过将对象的创建和管理权交给了Spring容器降低了程序之间的耦合性,

在Spring框架中,IoC主要通过XML配置文件、注解或Java配置等方式实现。通过使用IoC,应用程序的各个模块之间就可以以低耦合的形式进行协同工作,提高应用程序的可扩展性和可维护性。

传统程序开发流程

我们来举个例子,来更好的理解上面所述内容。

假设我们现在要生产一辆车,其基本思路如下:

按照传统的做法,我们生产一辆车,车的构成需要依赖车身(Framework),而车身需要依赖底盘(Bottom),底盘需要依赖轮胎(Tire)。

按照这种思路,我们用代码实现如下:

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

    /**
     * 汽车对象
     */
    static class Car {
        private Framework framework;

        public Car() {
            framework = new Framework();
        }

        public void init() {
            framework.init();
        }
    }

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

        private Bottom bottom;

        public Framework() {
            bottom = new Bottom();
        }

        public void init() {
            bottom.init();
        }
    }

    /**
     * 底盘Bottom
     */
    static class Bottom {

        private Tire tire;

        public Bottom() {
            tire = new Tire();
        }

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

    /**
     * 轮胎Tire
     */
    static class Tire {
        private int size = 20;//轮胎大小

        public void init() {
            System.out.println("轮胎大小:" + size);
        }
    }
}

我们可以看到,在上面的代码中,轮胎的尺寸是固定的,但是现在车的数量非常多,车轮胎的尺寸不可能都是一样的,所以我们就需要生产出各种尺寸大小的轮胎。我们需要对上面的代码进行修改:

public class CarProduct {
    public static void main(String[] args) {
        Car car = new Car();
        car.init(10);
    }

    /**
     * 汽车对象
     */
    static class Car {
        private Framework framework;

        public Car() {
            framework = new Framework();
        }

        public void init(int size) {
            framework.init(size);
        }
    }

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

        private Bottom bottom;

        public Framework() {
            bottom = new Bottom();
        }

        public void init(int size) {
            bottom.init(size);
        }
    }

    /**
     * 底盘Bottom
     */
    static class Bottom {

        private Tire tire;

        public Bottom() {
            tire = new Tire();
        }

        public void init(int size) {
            tire.init(size);
        }
    }

    /**
     * 轮胎Tire
     */
    static class Tire {

        public void init(int size) {
            System.out.println("轮胎大小:" + size);
        }
    }
}

我们可以看到,虽然满足我们的需求了,但是在上面的代码中,不难看到,当最底层的代码修改后,整个调用链上的代码都需要进行修改,这样耦合度就非常高了。

那么如果解决上面出现的这种问题呢?

在上面的代码中,我们都是在每个类中创建下一个要调用的类,这样的耦合度就非常高。

那么我们可以不在类中创建下级类,而是改为传递的方式(即注入),这样我们就能实现解耦,下级类的改变发生变化,对于当前类来说,也无需修改任何代码。

解耦指的是:解决了代码之间的依赖程度,也可以叫做程序相关性,好的程序的代码的耦合性是很低的,也就是代码之间要解耦

这就好比我们生产一辆汽车,如果所有的配件都是自己制造的,那么当客户要改变需求时,如,客户想要一个比较大的轮胎,那么我们就需要自己生产,这样的效率是非常低的,但如果我们把轮胎的生产外包出去,那么就算轮胎的尺寸要发生改变,我们也能向代理公厂下单即可,无需自己生产,这样效率就提高了不少。

控制反转程序开发流程(IoC)

 根据上面所述,对代码进行修改:

**
 * CarProduct类是汽车生产模型的示例,展示了如何通过组合不同类来构建复杂的对象结构
 */
public class CarProduct {
    /**
     * 程序的入口点
     * 创建汽车对象及其组成部分,并初始化
     * @param args 命令行参数
     */
    public static void main(String[] args) {
        // 创建轮胎对象,指定轮胎大小
        Tire tire = new Tire(20);
        // 创建底盘对象,包含上面创建的轮胎
        Bottom bottom = new Bottom(tire);
        // 创建车身对象,包含上面创建的底盘
        Framework framework = new Framework(bottom);
        // 创建汽车对象,包含上面创建的车身
        Car car = new Car(framework);
        // 初始化汽车对象
        car.init();
    }

    /**
     * 汽车对象
     */
    static class Car {
        private Framework framework;

        /**
         * 构造方法,初始化汽车的车身
         * @param framework 汽车的车身
         */
        public Car(Framework framework) {
            this.framework = framework;
        }

        /**
         * 初始化汽车对象,包括其车身
         */
        public void init() {
            framework.init();
        }
    }

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

        private Bottom bottom;

        /**
         * 构造方法,初始化车身的底盘
         * @param bottom 车身的底盘
         */
        public Framework(Bottom bottom) {
            this.bottom = bottom;
        }

        /**
         * 初始化车身对象,包括其底盘
         */
        public void init() {
            bottom.init();
        }
    }

    /**
     * 底盘Bottom
     */
    static class Bottom {

        private Tire tire;

        /**
         * 构造方法,初始化底盘的轮胎
         * @param tire 底盘的轮胎
         */
        public Bottom(Tire tire) {
            this.tire = tire;
        }

        /**
         * 初始化底盘对象,包括其轮胎
         */
        public void init() {
            tire.init();
        }
    }

    /**
     * 轮胎Tire
     */
    static class Tire {

        private int size;//轮胎大小

        /**
         * 构造方法,初始化轮胎的大小
         * @param size 轮胎的大小
         */
        public Tire(int size) {
            this.size = size;
        }

        /**
         * 初始化轮胎对象,打印轮胎大小
         */
        public void init() {
            System.out.println("轮胎大小:" + size);
        }
    }
}

我们可以看到,通过上面的修改,就算底层类发生变化,整个调用链的代码也是不用做任何修改的,这样就实现代码之间的解耦,从而提高了代码的灵活性、复用性。

我们来对比一下传统程序开发流程和控制反转程序开发流程:

我们可以看到,传统的开发流程是:Car依赖Framework,Framework依赖Bottom,...。而在改进之后的代码中,控制权发生了反转,不再是由上级对象创建下级对象并控制下级对象,而是下级对象注入到上级对象中,下级对象不再受上级对象的控制,这样就算下级对象发生改变,也不会影响到上级对象,这就是典型的控制反转,也就是IoC的实现思想

 如何理解Spring IoC

在以往的程序设计中,对象之间的依赖关系通常是由程序内部通过new关键字来实现的,这样的方式,会导致程序内部与具体实现的对象紧密联系(即耦合度高),一旦对象的实现发生改变,那么对于程序中的一部分代码也需要进行修改,这不仅增加了开发成本,而且也增加了代码的维护难度。

Spring IoC则是将对象的创建和管理权交给了Spring容器。在Spring容器中,所有的对象称为Bean,并通过配置文件或注解等方式来进行获取对象。当程序某处需要用到Bean对象时,Spring容器就会负责查找、创建、注入Bean对象。而程序本身不需要关心Bean对象时如何实例化和管理的。这种方式的创建和管理权从原先的程序中转移到Spring容器中,从而实现了控制反转(IoC)。

Spring IoC的优点

  • 降低耦合度:通过把对象的实例和管理权交给Spring容器,从而让程序与对象之间的耦合性降低,使得代码更加灵活、可维护、可复用。
  • 提高可扩展性:由于对象的创建和管理权交给了Spring容器,当我们需要添加新的功能或模块时,我们只需要在Spring中注册相应的bean即可。
  • 简化开发:使用Spring IoC可以简化开发。开发者只需要关注业务逻辑的实现,而不需要花费过多的精力在对象的创建和管理上。
  • 提高性能:虽然使用Spring IoC会增加一些额外的开销,但在大多数情况下,这种开销是微不足道的。而且,通过使用Spring IoC,可以减少不必要的对象创建和销毁,从而提高应用程序的性能。

DI(依赖注入)

DI(Dependcy Injection,即依赖注入)是一种软件设计模式,用于实现松耦合和可测试性的代码结构。在寻常的编程中,对象通常自己负责创建和管理它锁依赖的其他对象,这样导致了对象之间的耦合度高,使得对象难以复用和测试。

DI是一种实现控制反转(Inversion of Control,简称 IoC)的机制。它允许对象之间的依赖关系由外部容器(Spring 容器)来管理,而不是由对象自身来创建或查找依赖对象。这种方式可以减少对象之间的耦合性,提高代码的可重用性和可维护性

DI的实现方式

DI的主要实现方式包括构造函数注入、属性注入和方法注入

  • 构造函数注入是最常见的DI方式,它通过在对象的构造函数中传递依赖对象来实现。
  • 属性注入是通过设置对象的属性来注入依赖对象。
  • 方法注入是一种更灵活的DI方式,它通过在对象的方法中传递依赖对象来实现。

DI的优点

  • 降低耦合度DI使得对象之间的耦合度降低,因为对象不直接创建依赖,而是通过外部注入的方式获得。这使得每个对象更加独立,更易于管理和维护。
  • 提高代码的可维护性:由于对象之间的耦合度降低,修改一个对象时对其他对象的影响也会减少,这使得代码更易于维护和升级。
  • 提高灵活性:DI使得对象的依赖关系可以动态地管理和修改,这使得代码更加灵活,可以根据实际需求进行修改和扩展。
  • 增强代码的可测试性:依赖注入使得单元测试变得更加容易。开发者可以通过注入模拟(mock)对象或存根(stub)来测试组件的行为,而不需要依赖于实际的依赖对象。
  • 提高代码的可重用性:由于对象不依赖于具体的实现,而是依赖于抽象(接口或抽象类),因此可以更容易地替换对象的实现,从而提高代码的可重用性。

Spring相关网站

Spring官方网站:Spring | Homehttps://spring.io/https://spring.io/https://spring.io/
Spring Framework官方文档:Spring Framework 文档 :: Spring Frameworkhttps://docs.spring.io/spring-framework/reference/https://docs.spring.io/spring-framework/reference/https://docs.spring.io/spring-framework/reference/
Spring Boot官方文档:Spring Boot :: Spring Boothttps://docs.spring.io/spring-boot/index.htmlhttps://docs.spring.io/spring-boot/index.htmlhttps://docs.spring.io/spring-boot/index.html
Spring Cloud官方文档:Spring Cloudhttps://spring.io/projects/spring-cloud#learnhttps://spring.io/projects/spring-cloud#learnhttps://spring.io/projects/spring-cloud#learn
Spring源代码仓库:Spring · GitHubhttps://github.com/spring-projectshttps://github.com/spring-projectshttps://github.com/spring-projects
Spring源代码仓库中文文档:Spring Framework 中文文档https://www.docs4dev.com/docs/zh/spring-framework/5.1.3.RELEASE/reference/https://www.docs4dev.com/docs/zh/spring-framework/5.1.3.RELEASE/reference/https://www.docs4dev.com/docs/zh/spring-framework/5.1.3.RELEASE/reference/
Spring Boot中文文档:Spring Boot 参考https://www.docs4dev.com/docs/spring-boot/2.4.6/reference/getting-started.html#getting-startedhttps://www.docs4dev.com/docs/spring-boot/2.4.6/reference/getting-started.html#getting-startedhttps://www.docs4dev.com/docs/spring-boot/2.4.6/reference/getting-started.html#getting-started
Spring Cloud中文文档:Spring Cloud 中文文档https://www.docs4dev.com/docs/zh/spring-cloud/Finchley.SR2/reference/https://www.docs4dev.com/docs/zh/spring-cloud/Finchley.SR2/reference/https://www.docs4dev.com/docs/zh/spring-cloud/Finchley.SR2/reference/


以上就是本篇所有内容啦~

若有不足,欢迎指正~

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

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

相关文章

【专题】2024-2025人工智能代理深度剖析:GenAI 前沿、LangChain 现状及演进影响与发展趋势报告汇总PDF洞察(附原数据表)

原文链接:https://tecdat.cn/?p39630 在科技飞速发展的当下,人工智能代理正经历着深刻的变革,其能力演变已然成为重塑各行业格局的关键力量。从早期简单的规则执行,到如今复杂的自主决策与多智能体协作,人工智能代理…

oCam:免费且强大的录屏软件

今天给大家推荐一个非常好的录屏软件。几乎可以满足你日常工作的需求。而且软件完全免费,没有任何的广告。 oCam:免费且强大的录屏软件 oCam是一款功能强大的免费录屏软件,支持屏幕录制、游戏录制和音频录制等多种模式,能够满足不…

spring学习(spring 配置文件详解)

一 了解如何创建基本的spring 配置文件 步骤 1 导入 spring-context 依赖 <!-- https://mvnrepository.com/artifact/org.springframework/spring-context --><dependency><groupId>org.springframework</groupId><artifactId>spring-context&l…

C++Primer学习(2.2)

2.2 变量 变量提供一个具名的、可供程序操作的存储空间。C中的每个变量都有其数据类型,数据类型决定着变量所占内存空间的大小和布局方式、该空间能存储的值的范围&#xff0c;以及变量能参与的运算。对C程序员来说,“变量(variable)”和“对象(object)”一般可以互换使用。 术…

无须付费,安装即是完全版!

不知道大家有没有遇到过不小心删掉了电脑上超重要的文件&#xff0c;然后急得像热锅上的蚂蚁&#xff1f; 别担心&#xff0c;今天给大家带来一款超给力的数据恢复软件&#xff0c;简直就是拯救文件的“救星”&#xff01; 数据恢复 专业的恢复数据软件 这款软件的界面设计得特…

【Ubuntu】本地部署Deep Seek(深度求索)大模型的保姆级教程 | 详细教程

杭州深度求索人工智能基础技术研究有限公司(简称“深度求索”或“DeepSeek”)&#xff0c;成立于2023年&#xff0c;DeepSeek是一家专注通用人工智能&#xff08;AGI&#xff09;的中国科技公司&#xff0c;主攻大模型研发与应用&#xff0c;经营范围包括技术服务、技术开发、软…

Ollama + AnythingLLM + Deepseek r1 实现本地知识库

1、Ollama&#xff1a;‌是一个开源的大型语言模型 (LLM)服务工具&#xff0c;旨在简化在本地运行大语言模型的过程&#xff0c;降低使用大语言模型的门槛‌。 2、AnythingLLM&#xff1a;是由Mintplex Labs Inc. 开发的一款全栈应用程序&#xff0c;旨在构建一个高效、可定制、…

网络安全治理架构图 网络安全管理架构

网站安全攻防战 XSS攻击 防御手段&#xff1a; - 消毒。 因为恶意脚本中有一些特殊字符&#xff0c;可以通过转义的方式来进行防范 - HttpOnly 对cookie添加httpOnly属性则脚本不能修改cookie。就能防止恶意脚本篡改cookie 注入攻击 SQL注入攻击需要攻击者对数据库结构有所…

如何利用maven更优雅的打包

最近在客户现场部署项目&#xff0c;有两套环境&#xff0c;无法连接互联网&#xff0c;两套环境之间也是完全隔离&#xff0c;于是问题就来了&#xff0c;每次都要远程到公司电脑改完代码&#xff0c;打包&#xff0c;通过网盘&#xff08;如果没有会员&#xff0c;上传下载慢…

mysql 不是内部或外部命令,也不是可运行的程序或批处理文件

mysql 不是内部或外部命令&#xff0c;也不是可运行的程序或批处理文件 前言描述1、&#x1f331;环境变量配置&#xff08;高级系统设置&#xff09;&#xff1a;2、&#x1f331;环境变量配置&#xff08;系统属性&#xff09;&#xff1a;3、&#x1f331;环境变量配置&…

常用数据结构之String字符串

字符串 在Java编程语言中&#xff0c;字符可以使用基本数据类型char来保存&#xff0c;在 Java 中字符串属于对象&#xff0c;Java 提供了 String 类来创建和操作字符串。 操作字符串常用的有三种类&#xff1a;String、StringBuilder、StringBuffer 接下来看看这三类常见用…

RabbitMQ 消息顺序性保证

方式一&#xff1a;Consumer设置exclusive 注意条件 作用于basic.consume不支持quorum queue 当同时有A、B两个消费者调用basic.consume方法消费&#xff0c;并将exclusive设置为true时&#xff0c;第二个消费者会抛出异常&#xff1a; com.rabbitmq.client.AlreadyClosedEx…

使用LLaMA Factory踩坑记录

前置条件&#xff1a;电脑显卡RTX 4080 问题&#xff1a;LLaMA-Factory在运行的时候&#xff0c;弹出未检测到CUDA的报错信息 结论&#xff1a;出现了以上的报错&#xff0c;主要可以归结于以下两个方面&#xff1a; 1、没有安装GPU版本的pytorch&#xff0c;下载的是CPU版本…

大模型推理——MLA实现方案

1.整体流程 先上一张图来整体理解下MLA的计算过程 2.实现代码 import math import torch import torch.nn as nn# rms归一化 class RMSNorm(nn.Module):""""""def __init__(self, hidden_size, eps1e-6):super().__init__()self.weight nn.Pa…

Vue3+codemirror6实现公式(规则)编辑器

实现截图 实现/带实现功能 插入标签 插入公式 提示补全 公式验证 公式计算 需要的依赖 "codemirror/autocomplete": "^6.18.4","codemirror/lang-javascript": "^6.2.2","codemirror/state": "^6.5.2","cod…

MIT 6.5940(一)

记录了Lecture 1~8 Lecture 1 Introduction TinyML and Efficient Deep Learning Computing 摘要 AI systems need to continually adapt to new data collected locally 在设备学习&#xff1a;better privacy, lower cost, customization, life-long learningTraining is…

Linux TCP 编程详解与实例

一、引言 在网络编程的领域中&#xff0c;TCP&#xff08;Transmission Control Protocol&#xff09;协议因其可靠的数据传输特性而被广泛应用。在 Linux 环境下&#xff0c;使用 C 或 C 进行 TCP 编程可以实现各种强大的网络应用。本文将深入探讨 Linux TCP 编程的各个方面&…

一款由 .NET 官方团队开源的电子商务系统 - eShop

项目介绍 eShop是一款由.NET官方开源的&#xff0c;基于.NET Aspire构建的用于参考学习的服务架构电子商务系统&#xff0c;旨在展示如何利用.NET框架及其相关技术栈构建一个现代化的电子商务网站。该项目采用服务架构&#xff0c;将应用程序分解为多个独立的服务&#xff0c;…

crewai框架第三方API使用官方RAG工具(pdf,csv,json)

最近在研究调用官方的工具&#xff0c;但官方文档的说明是在是太少了&#xff0c;后来在一个视频里看到了如何配置&#xff0c;记录一下 以PDF RAG Search工具举例&#xff0c;官方文档对于自定义模型的说明如下&#xff1a; 默认情况下&#xff0c;该工具使用 OpenAI 进行嵌…

2011-2020年各省电话普及率数据

2011-2020年各省电话普及率数据 1、时间&#xff1a;2011-2020年 2、来源&#xff1a;国家统计局、统计年鉴 3、指标&#xff1a;行政区划代码、地区名称、年份、电话普及率(包括移动电话)(部/百人) 4、范围&#xff1a;31省 5、指标说明&#xff1a;电话普及率是衡量一个…