【JavaEE进阶】Spring IoC

发布于:2025-02-11 ⋅ 阅读:(13) ⋅ 点赞:(0)

目录​​​​​​​

🌴序言

🎄Spring是什么?

🚩什么是容器?

🚩什么是IoC?

🌳IoC介绍

🚩传统程序开发

🚩问题分析

🚩解决方案

🚩IoC程序开发

🌲IoC优势

🍃Spring IoC用法

🚩@Component注解

🚩@Autowired注解


🌴序言

在前⾯的章节中,我们学习了SpringBoot和SpringMVC的开发,可以完成⼀些基本功能的开发了,但是 什么是Spring呢? Spring,SpringBoot和SpringMVC⼜有什么关系呢?咱们还是带着问题去学习. 我们先看什么是Spring

🎄Spring是什么?

通过前⾯的学习,我们知道了Spring是⼀个开源框架,他让我们的开发更加简单.他⽀持⼴泛的应⽤场 景,有着活跃⽽庞⼤的社区,这也是Spring能够⻓久不衰的原因

但是这个概念相对来说,还是⽐较抽象

我们⽤⼀句更具体的话来概括Spring,那就是:Spring是包含了众多工具方法的IoC容器

Spring两个核心思想:IoC,AOP

那问题来了,什么是容器?什么是IoC容器?接下来我们⼀起来看

🚩什么是容器?

容器是⽤来容纳某种物品的(基本)装置。

⽣活中的⽔杯,垃圾桶,冰箱等等这些都是容器.

我们想想,之前课程我们接触的容器有哪些?

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

那么Spring也作为一个容器,装的是对象(Bean)

这里的Bean跟在Java基础语法中是不一样的,在Javase中Bean指的是实体类,比如Student类

在JavaEE进阶中,Bean指的是Spring管理的对象

在之前的文章中,我们说一个类加上了@RestController注解,表示这个对象交给了Spring管理了,那么这个对象就是一个Bean

🚩什么是IoC?

IoC 是Spring的核⼼思想,也是常⻅的⾯试题,那什么是IoC呢?

其实IoC我们在前⾯已经使⽤了,我们在前⾯讲到,在类上⾯添加 @RestController 和 @Controller 注解,就是把这个对象交给Spring管理,Spring框架启动时就会加载该类.把对象交 给Spring管理,就是IoC思想.

IoC: Inversion of Control (控制反转),也就是说Spring是⼀个"控制反转"的容器.

什么是控制反转呢? 也就是控制权反转.什么的控制权发⽣了反转? 获得依赖对象的过程被反转了

也就是说,当需要某个对象时,传统开发模式中需要⾃⼰通过new创建对象,现在不需要再进⾏创建, 把创建对象的任务交给容器, 程序中只需要依赖注⼊(DependencyInjection,DI)就可以了. 这个容器称为:IoC容器. Spring是⼀个IoC容器,所以有时Spring也称为Spring容器.

当我们加了注解之后,为什么可以访问这个接口,getList是一个普通的方法,我们说除了静态方法都依赖于对象,那么这里就是被调用了,也就是Spring默认的帮我们创建好了一个BookController类型的对象,帮我们进行了管理,当我们去访问的时候,它帮我们调用了这个方法。

控制反转是⼀种思想,在⽣活中也是处处体现.

⽐如⾃动驾驶, 传统驾驶⽅式,⻋辆的横向和纵向驾驶控制权由驾驶员来控制,现在交给了驾驶⾃ 动化系统来控制,这也是控制反转思想在⽣活中的实现.

⽐如招聘,企业的员⼯招聘,⼊职,解雇等控制权,由⽼板转交给给HR(⼈⼒资源)来处理

🌳IoC介绍

接下来我们通过案例来了解⼀下什么是IoC

需求: 造一辆车

🚩传统程序开发

我们的实现思路是这样的:

先设计轮⼦(Tire),然后根据轮⼦的⼤⼩设计底盘(Bottom),接着根据底盘设计⻋⾝(Framework),最 后根据⻋⾝设计好整个汽⻋(Car)。这⾥就出现了⼀个"依赖"关系:汽⻋依赖⻋⾝,⻋⾝依赖底盘,底盘依赖轮⼦

最终程序的实现代码如下:

运行程序:

🚩问题分析

这样的设计看起来没问题,但是可维护性却很低.

接下来需求有了变更: 随着对的⻋的需求量越来越⼤,个性化需求也会越来越多,我们需要加⼯多种尺寸的轮胎.

那这个时候就要对上⾯的程序进⾏修改了,size就是一个可选参数了,修改后的代码如下所⽰:

修改之后,其他调⽤程序也会报错,我们需要继续修改

运行程序:

 那么通过上述修改,当前是想造多少寸的都可以

从以上代码可以看出,以上程序的问题是:当最底层代码改动之后,整个调⽤链上的所有代码都需要修改. 程序的耦合度⾮常⾼(修改⼀处代码,影响其他处的代码修改)

🚩解决方案

在上⾯的程序中,我们是根据轮⼦的尺⼨设计的底盘,轮⼦的尺⼨⼀改,底盘的设计就得修改.同样因 为我们是根据底盘设计的⻋⾝,那么⻋⾝也得改,同理汽⻋设计也得改,也就是整个设计⼏乎都得改

上述呢我们可以看到,所需要的对象都是自己new出来的,需要什么就new什么,现在我们就通过IoC的思想进行设计,把创建对象的权力交给Spring,不在自己new了。

我们尝试换⼀种思路,我们先设计汽⻋的⼤概样⼦,然后根据汽⻋的样⼦来设计⻋⾝,根据⻋⾝来设计底盘,最后根据底盘来设计轮⼦.这时候,依赖关系就倒置过来了:轮⼦依赖底盘,底盘依赖⻋⾝, ⻋⾝依赖汽⻋

这就类似我们打造⼀辆完整的汽⻋,如果所有的配件都是⾃⼰造,那么当客⼾需求发⽣改变的时候, ⽐如轮胎的尺⼨不再是原来的尺⼨了,那我们要⾃⼰动⼿来改了,但如果我们是把轮胎外包出去,那 么即使是轮胎的尺⼨发⽣变变了,我们只需要向代理⼯⼚下订单就⾏了,我们⾃⾝是不需要出⼒的.

如何来实现呢:

我们可以尝试不在每个类中⾃⼰创建下级类,如果⾃⼰创建下级类就会出现当下级类发⽣改变操作,⾃⼰也要跟着修改.

此时,我们只需要将原来由⾃⼰创建的下级类,改为传递的⽅式(也就是注⼊的⽅式),因为我们不需要在当前类中创建下级类了,所以下级类即使发⽣变化(创建或减少参数),当前类本⾝也⽆需修改任何代码,这样就完成了程序的解耦. 

🚩IoC程序开发

基于以上思路,我们把调⽤汽⻋的程序⽰例改造⼀下,把创建⼦类的⽅式,改为注⼊传递的⽅式. 具体实现代码如下:

程序运行:

代码经过以上调整,⽆论底层类如何变化,整个调⽤链是不⽤做任何改变的,这样就完成了代码之间 的解耦,从⽽实现了更加灵活、通⽤的程序设计了。

感觉好像跟传统的开发没有什么区别,但是其中红色方框中的就是Spring帮我们做的事情

我们可以来观察一下区别:

当我们进行参数添加时

观察发现影响范围并不大,耦合低

🌲IoC优势

在传统的代码中对象创建顺序是:Car->Framework->Bottom->Tire

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

我们发现了⼀个规律,通⽤程序的实现代码,类的创建顺序是反的,传统代码是Car控制并创建了 Framework,Framework创建并创建了Bottom,依次往下,⽽改进之后的控制权发⽣的反转,不再是使⽤⽅对象创建并控制依赖对象了,⽽是把依赖对象注⼊将当前对象中,依赖对象的控制权不再由 当前类控制了

这样的话,即使依赖类发⽣任何改变,当前类都是不受影响的,这就是典型的控制反转,也就是IoC的 实现思想。

学到这⾥,我们⼤概就知道了什么是控制反转了,那什么是控制反转容器呢,也就是IoC容器

这部分代码,就是IoC容器做的⼯作.

从上⾯也可以看出来,IoC容器具备以下优点:

资源不由使⽤资源的双⽅管理,⽽由不使⽤资源的第三⽅管理,这可以带来很多好处。第⼀,资源集中管理,实现资源的可配置和易管理。第⼆,降低了使⽤资源双⽅的依赖程度,也就是我们说的耦合度。

  •  1. 资源集中管理: IoC容器会帮我们管理⼀些资源(对象等),我们需要使⽤时,只需要从IoC容器中去取 就可以了
  • 2. 我们在创建实例的时候不需要了解其中的细节,降低了使⽤资源双⽅的依赖程度,也就是耦合度.

Spring 就是⼀种IoC容器,帮助我们来做了这些资源管理.

🍃Spring IoC用法

接下来我们来观察Spring是如何帮助我们做IoC的

比如有以下代码:

上述代码中,@RestController注解就是IoC的一种体现,加上这个注解之后,其中BookController这个对象,Spring就帮我们管理起来了。

我们也可发现在getList方法中也new了一个对象,那么我也希望BookService这个对象可以从Spring中去拿到,不在自己new了。

🚩@Component注解

在BookService这个类上加上@Component注解,Spring就会帮我们去创建一个BookService对象;在当前这个类中的getList方法里面,也有一个BookDao对象是自己new的,也可在BookDao类上加上@Component注解

🚩@Autowired注解

上述将对象放到Spring中称为IoC,也就是把对象的控制权交给了Spring;当前需要使用这个对象时,就可以从容器中去拿,这个称为DI(依赖注入,后续会详细讲述)。

直接在当前类中声明一个所需要的对象,加上@Autowired注解即可,表示从Spring中取出该对象