Spring基础及IoC容器的理解

news2024/11/12 20:30:17

Spring概念:

通常所说的Spring指的是Spring Framewprk(Spring框架),它是一个开源的框架。用一句话概括就是:Spring是包含了众多工具方法的IoC容器

什么是容器?

容器是用来容纳某种物品的装置,在之前的学习中,我们接触到的容器有List/Map(数据存储容器)Tomcat(Web容器)

什么是IoC容器?

Spring就是一个IoC容器,IoC(Inversion of Control)翻译成中文就是“控制反转”的意思,也就是说,Spring是一个“控制反转”的容器。

如何理解控制反转?

以前我们在一个类中使用另外一个类,需要New一个对象来使用,所以对象的生命周期是由当前代码或程序员来控制;控制反转其实是控制权反转,也就是说对象的生命周期,不由程序员或当前代码片段来控制,而是由Spring(Spring容器/IoC容器)来控制,这就叫做控制权反转。

为什么要使用IoC容器/Spring?

使用IoC容器最大的优点:可以实现解耦(松耦合)。
如何理解?我们可以想象成要造一辆车,要造这辆车得依赖于车身,车身又依赖于底盘,底盘依赖于轮胎。就像下面这张图所示:
在这里插入图片描述

下面我们用代码来演示这种关系:

传统的开发方式
  • 我们新建一个类,叫Car,这个类里面有一个init()方法,可以理解成造车的关键步骤,Car依赖于Framework类。
package old;

public class Car {
    private  Framework framework;
    public  Car(){
        this.framework=new Framework();
    }
    public  void init(){
        System.out.println("执行了 Car  init方法");
        //依赖车身
        framework.init();
    }
}

  • 接着new一个Framework类,Framework依赖于Bottom。
package old;

public class Framework {
    private  Bottom bottom;
    public  Framework(){
        this.bottom=new Bottom();
    }
    public  void  init(){
        System.out.println("执行了 Framework init 方法");
        //依赖底盘
       bottom.init();
    }
}

  • Framework又依赖于Bottom,于是我们再new一个Bottom类
package old;

public class Bottom {
    private  Tire tire;
    public  Bottom(){
        this.tire=new Tire();
    }
    public  void init(){
        System.out.println("执行了 Bottom init 方法");
        //依赖轮胎
        tire.init();
    }
}

  • 最后new一个Tire类,定义属性size
package old;

public class Tire {
    private  int size=20;
    public void init(){
        System.out.println("执行了Tire init 方法,Size:"+size);
    }
}

  • new一个Test类,测试一下代码是否正确:
package old;

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

在这里插入图片描述
执行没有问题,上面的代码就是传统开发的过程。
但是如果对车的要求增加了,比如对于轮胎的size,不同的人群,对轮胎size大小要求不一样,在代码上体现就是不能再使用原来默认的size,我们Tire类中重载构造方法。

package old;

public class Tire {
    private  int size=20;
    public  Tire(int size){
        this.size=size;
    }
    public void init(){
        System.out.println("执行了Tire init 方法,Size:"+size);
    }
}

但是这样会引发一系列的问题,Tire的构造方法是有参的,而Bottom又依赖于Tire,Bottom类也要随之改动,不然就会报错,就像下面这样:
在这里插入图片描述
我们先给Bottom补上需要的参数:

package old;

public class Bottom {
    private  Tire tire;
    public  Bottom(int size){
        this.tire=new Tire(size);
    }
    public  void init(){
        System.out.println("执行了 Bottom init 方法");
        tire.init();
    }
}

Bottom中本身是没有参数size的,这里要改这个报错,需要传入size,于是这个size由Framework传入。Framework本身也没有size参数,于是需要Car传给它。

package old;

public class Framework {
    private  Bottom bottom;
    public  Framework(int size){
        this.bottom=new Bottom(size);
    }
    public  void  init(){
        System.out.println("执行了 Framework init 方法");
        //依赖底盘
       bottom.init();
    }
}

当我们改完Framework类后,Car类也会出现问题,缺少size参数,我们重载Car的构造方法,进行有参构造传入size.

package old;

public class Car {
    private  Framework framework;
    public  Car(int size){
        this.framework=new Framework(size);
    }
    public  void init(){
        System.out.println("执行了 Car  init方法");
        //依赖车身
        framework.init();
    }
}

然后我们在测试类中新建Car对象的时候设置size大小进行测试,我们把size设置成10:

package old;

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

在这里插入图片描述
这样就可以随便设置轮胎size的大小,满足不同人群的需求。通过上面的代码可以可以看出,当我们最底层的代码发生改变时,整个调用链上的所有代码都需要改动,而且这只是改一个参数。那如果我们需要加别的参数并且做更改呢?这就非常麻烦,底层的代码改变,调用链上的所有代码都要跟着改变,这就是耦合———“牵一发而动全身”!
怎么解决这个问题呢?用IoC框架,使用IoC就可以实现解耦,就可以避免上面的问题。

IoC开发方式
  • 编写Car类,Car类依然依赖于Framework类,但是不同的是,我们使用Framework对象时不需要new了,直接声明一下,框架会给我们。
package ioc;
public class Car {
   private  Framework framework;
   public Car(Framework framework){
       this.framework=framework;
   }
   public  void  init(){
       System.out.println("Car init");
       framework.init();
   }
}
  • 编写Framework类,Framework依赖于Bottom,但是这里同样也没有new Bottom对象,同样是框架给我们的Bottom对象,直接去使用。
package ioc;

public class Framework {
    private Bottom bottom;
    public Framework(Bottom bottom){
        this.bottom=bottom;
    }
    public  void  init(){
        System.out.println("Framework init");
        bottom.init();
    }
}

  • 编写Bottom类,Bottom依赖于Tire ,这里也没有new Tire对象,调用Tire时直接去框架中去取,然后给当前变量设置框架里面的bottom。
package ioc;

public class Bottom {
    private  Tire tire;
    public  Bottom(Tire tire){
        this.tire=tire;
    }
    public  void  init(){
        System.out.println("Bottom init");
        tire.init();
    }
}

  • 编写Tire类,设置属性和init方法
package ioc;

public class Tire {
    private   int size=15;
    public  Tire(){}
    public  void  init(){
        System.out.println("Tire init,size:"+size);
    }
}

  • 编写单元测试代码,这里是模拟Spring框架(不用关注这里的new对象),这是框架的事情。
package ioc;

public class Test {
    private  Tire tire;
    private  Bottom bottom;
    private  Framework framework;
    private  Car car;

    public  Test(){
        this.tire=new Tire();
       this.bottom=new Bottom(this.tire);
        this.framework=new Framework(this.bottom);
        this.car=new Car(this.framework);
    }
    public static void main(String[] args) {
        Test test=new Test();
        test.car.init();
    }
}

在这里插入图片描述
然后我们给Tire设置size,将无参构造改成有参构造。

package ioc;

public class Tire {
    private   int size=15;
    public  Tire(int size){
        this.size=size;
    }
    public  void  init(){
        System.out.println("Tire init,size:"+size);
    }
}

修改后整个调用链上的代码没有报错,调用链上的代码也不需要任何修改,Tire改动后哪里需要修改是Spring框架/IoC容器的事情,跟用户没有任何关系,Spring会自动去设置这些参数。
在这里插入图片描述
总结一下就是IoC帮我们实现了业务代码的解耦,实现了松耦合。不在是底层代码发生改变,整个调用链上的代码都要改变。这就是IoC的优点,实现解耦

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

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

相关文章

运动蓝牙耳机哪个品牌好、运动蓝牙耳机推荐

随着健康生活理念的广泛普及,对于很多人来说,运动已经成为他们日常生活不可或缺的重要组成部分。在激情四溢的健身运动中,我们既能够放松身心,减轻工作压力,又能够强健身体,增强免疫力,可谓一举…

代码随想录第31天 | 435. 无重叠区间 ● 763.划分字母区间 ● 56. 合并区间

435. 无重叠区间 /*** param {number[][]} intervals* return {number}*/ var eraseOverlapIntervals function(intervals) {intervals.sort((x,y)>(x[1]-y[1]))let r1for(let i0;i<intervals.length-1;i){//重叠if(intervals[i][1]>intervals[i1][0]){intervals[i…

向量数据库Milvus Cloud 2.3 工具升级: 解锁全新的运维功能

Milvus Cloud 2.3 已经发布,并且带来了一系列令人激动的新功能和升级。在这次升级中,Birdwatcher工具也得到了全面升级,为用户提供了更多强大的功能和更便捷的操作方式。在这篇文章中,我们将深入探讨Birdwatcher工具的升级内容,并带您一览Milvus Cloud 2.3的运维新特性。 …

2023数学建模国赛E题黄河水沙监测数据分析完整代码分析+处理结果+思路文档

已经写出国赛E题黄河水沙监测数据分析完整代码分析处理结果思路分析&#xff08;30页&#xff09;&#xff0c;包括数据预处理、数据可视化&#xff08;分组数据分布图可视化、相关系数热力图可视化、散点图可视化&#xff09;、回归模型&#xff08;决策树回归模型、随机森林回…

JAVA培训-核心概念学习

JAVA培训-核心概念 1. SpringBoot 1.1 理清概念(Spring、SpringMvc、SpringBoot、SpringCloud) 1、Spring Spring是一个开源容器框架&#xff0c;可以接管web层&#xff0c;业务层&#xff0c;dao层&#xff0c;持久层的组件&#xff0c;并且可以配置各种bean,和维护bean与…

【用unity实现100个游戏之10】复刻经典俄罗斯方块游戏

文章目录 前言网格生成Block方块脚本俄罗斯方块基类&#xff0c;绘制方块形状移动逻辑限制移动自由下落下落后设置对应风格为不可移动类型检查当前方块是否可以向指定方向移动旋转逻辑消除逻辑游戏结束逻辑怪物生成源码参考完结 前言 当今游戏产业中&#xff0c;经典游戏的复刻…

基于SSM的校园美食交流系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用Vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

开开心心带你学习MySQL数据库之第六篇下

插入查询结果 把查询和新增联合起来. 把查询结果作为新增的数据 例子:把student1表的查询结果作为新增数据插入到student2表中. create table student1(id int, name varchar(20));create table student2(id int, name varchar(20));insert into student1 values(1, 张三), (2…

NFT 合约部署教程

本篇文章主要介绍如何将您的 NFT(ERC-721 Token) 通过智能合约部署到去中心化网络中 Init Project //创建一款ocean的NFT mkdir nft-ocean//进入目录 cd nft-ocean//初始化项目&#xff0c;根据提示填写即可&#xff0c;packname和description填写即可 npm init//添加hardhat…

【JAVA】Object类与抽象类

作者主页&#xff1a;paper jie_的博客 本文作者&#xff1a;大家好&#xff0c;我是paper jie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 本文录入于《JAVASE语法系列》专栏&#xff0c;本专栏是针对于大学生&#xff0c;编程小白精心打造的。笔者用重金(时间和…

批量剪辑神器:AI智剪技巧全攻略

在视频剪辑的工作流程中&#xff0c;效率和质量都是至关重要的。有时候&#xff0c;我们需要对大量的视频进行剪辑&#xff0c;这可能会耗费大量的时间和人力。然而&#xff0c;随着技术的发展&#xff0c;AI智能剪辑工具如固乔智剪软件的出现&#xff0c;大大提高了剪辑的效率…

架构师之如何定位问题

1. 什么是问题 很多人对问题的理解不一样&#xff0c;有人认为问题就是解决方案中的难点&#xff0c;有人认为问题是现实和目标的差距&#xff0c;这些解读我觉得都还不够精确&#xff0c;尝试从毛主席的矛盾论中得到比较合理的解释&#xff1a; 问题就是事物的矛盾。哪里有没…

Ubuntu22.04 安装 MongoDB 7.0

稍微查了一些文章发现普遍比较过时。有的是使用旧版本的Ubuntu&#xff0c;或者安装的旧版本的MongoDB。英语可以的朋友可以移步Install MongoDB Community Edition on Ubuntu — MongoDB Manual&#xff0c;按照官方安装文档操作。伸手党或者英语略差的朋友可以按照本文一步步…

计算机重点学科评级B-,山东省属重点高校考情分析

山东科技大学(B-) 考研难度&#xff08;☆☆&#xff09; 内容&#xff1a;23考情概况&#xff08;拟录取和复试分析&#xff09;、院校概况、23专业目录、23复试详情、各专业考情分析、各科目考情分析。 正文1175字预计阅读&#xff1a;3分钟 2023考情概况 山东科技大学计…

stable diffusion webui升级bug问题解决思路(纯干货)

个人网站&#xff1a;https://tianfeng.space/ 文章目录 一、前言二、个人方案1.扼杀在萌芽中A.解压后点击启动器运行依赖&#xff0c;然后点击A启动器B.更新本体和扩展&#xff08;全部到最新版本&#xff09;C.把controlnet1.1放入stable diffusion 中D.插件转移E.模型转移F…

怎么选动捕设备?惯性动作捕捉还是光学动捕?

动捕设备在3D角色动画、影视制作中使用&#xff0c;通过动捕设备记录真人演员的动作&#xff0c;然后将其转换为数字模型的动作生成三维的计算机动画&#xff0c;使用动捕设备可以让动画角色更逼真地移动。 目前市面上主要分为光学动捕设备与惯性动作捕捉设备&#xff0c;这二…

基于SSM的学生课外知识学习网站

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用Vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

电水壶上要求亚马逊美国站SOR/2016-181和CSA22.1标准?

电水壶作为一种常见的小家电&#xff0c;受到了广大消费者的喜爱。然而&#xff0c;由于安全问题的日益重视&#xff0c;亚马逊加拿大站决定加强对电水壶产品的审核&#xff0c;以确保消费者的安全和权益。 近日&#xff0c;亚马逊平台发布公告&#xff0c;要求在加拿大站销售…

跨越时空,亲临其境:3D展示技术让你在家就能游览全球旅游景区

随着科技的不断发展&#xff0c;3D虚拟现实技术在文旅景区中的应用越来越广泛。相比传统的游览方式&#xff0c;3D展示技术具有以下优点&#xff1a; 一、真实感强 3D全景展示可以将文旅景区的真实场景以三维的方式呈现出来&#xff0c;让游客可以在虚拟的环境中感受到真实的场…

电子产品出口欧盟做什么认证?电子产品CE认证标准有哪些?

CE认证是产品出口到欧盟的通行证&#xff0c;没有CE认证标志的产品是不允许在欧盟市场上销售的&#xff0c;今天就给大家介绍常见的电子产品的CE认证标准有哪些&#xff1f; 电子产品CE认证标准有哪些&#xff1f; 常见的电子产品办理CE认证&#xff0c;做的认证指令是EMC指令…