目录
[🍃Spring IoC用法](#🍃Spring IoC用法)
🌴序言
在前⾯的章节中,我们学习了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)。这⾥就出现了⼀个"依赖"关系:汽⻋依赖⻋⾝,⻋⾝依赖底盘,底盘依赖轮⼦
![](https://i-blog.csdnimg.cn/direct/ab82e179fca84db4a9ff3e0ed127615a.png)
最终程序的实现代码如下:
运行程序:
🚩问题分析
这样的设计看起来没问题,但是可维护性却很低.
接下来需求有了变更: 随着对的⻋的需求量越来越⼤,个性化需求也会越来越多,我们需要加⼯多种尺寸的轮胎.
那这个时候就要对上⾯的程序进⾏修改了,size就是一个可选参数了,修改后的代码如下所⽰:
![](https://i-blog.csdnimg.cn/direct/8cd30304d0ff44bdaa5b78e1221d2d38.png)
修改之后,其他调⽤程序也会报错,我们需要继续修改
运行程序:
那么通过上述修改,当前是想造多少寸的都可以
从以上代码可以看出,以上程序的问题是:当最底层代码改动之后,整个调⽤链上的所有代码都需要修改. 程序的耦合度⾮常⾼(修改⼀处代码,影响其他处的代码修改)
🚩解决方案
在上⾯的程序中,我们是根据轮⼦的尺⼨设计的底盘,轮⼦的尺⼨⼀改,底盘的设计就得修改.同样因 为我们是根据底盘设计的⻋⾝,那么⻋⾝也得改,同理汽⻋设计也得改,也就是整个设计⼏乎都得改
上述呢我们可以看到,所需要的对象都是自己new出来的,需要什么就new什么,现在我们就通过IoC的思想进行设计,把创建对象的权力交给Spring,不在自己new了。
我们尝试换⼀种思路,我们先设计汽⻋的⼤概样⼦,然后根据汽⻋的样⼦来设计⻋⾝,根据⻋⾝来设计底盘,最后根据底盘来设计轮⼦.这时候,依赖关系就倒置过来了:轮⼦依赖底盘,底盘依赖⻋⾝, ⻋⾝依赖汽⻋
这就类似我们打造⼀辆完整的汽⻋,如果所有的配件都是⾃⼰造,那么当客⼾需求发⽣改变的时候, ⽐如轮胎的尺⼨不再是原来的尺⼨了,那我们要⾃⼰动⼿来改了,但如果我们是把轮胎外包出去,那 么即使是轮胎的尺⼨发⽣变变了,我们只需要向代理⼯⼚下订单就⾏了,我们⾃⾝是不需要出⼒的.
![](https://i-blog.csdnimg.cn/direct/627969500f0444ce8d8281a50b09806e.png)
如何来实现呢:
我们可以尝试不在每个类中⾃⼰创建下级类,如果⾃⼰创建下级类就会出现当下级类发⽣改变操作,⾃⼰也要跟着修改.
此时,我们只需要将原来由⾃⼰创建的下级类,改为传递的⽅式(也就是注⼊的⽅式),因为我们不需要在当前类中创建下级类了,所以下级类即使发⽣变化(创建或减少参数),当前类本⾝也⽆需修改任何代码,这样就完成了程序的解耦.
🚩IoC程序开发
基于以上思路,我们把调⽤汽⻋的程序⽰例改造⼀下,把创建⼦类的⽅式,改为注⼊传递的⽅式. 具体实现代码如下:
程序运行:
代码经过以上调整,⽆论底层类如何变化,整个调⽤链是不⽤做任何改变的,这样就完成了代码之间 的解耦,从⽽实现了更加灵活、通⽤的程序设计了。
感觉好像跟传统的开发没有什么区别,但是其中红色方框中的就是Spring帮我们做的事情
我们可以来观察一下区别:
当我们进行参数添加时
观察发现影响范围并不大,耦合低
🌲IoC优势
在传统的代码中对象创建顺序是:Car->Framework->Bottom->Tire
改进之后解耦的代码的对象创建顺序是:Tire->Bottom->Framework->Car
![](https://i-blog.csdnimg.cn/direct/13c54ac09b104faf9da9a890fb9f3868.png)
我们发现了⼀个规律,通⽤程序的实现代码,类的创建顺序是反的,传统代码是Car控制并创建了 Framework,Framework创建并创建了Bottom,依次往下,⽽改进之后的控制权发⽣的反转,不再是使⽤⽅对象创建并控制依赖对象了,⽽是把依赖对象注⼊将当前对象中,依赖对象的控制权不再由 当前类控制了
这样的话,即使依赖类发⽣任何改变,当前类都是不受影响的,这就是典型的控制反转,也就是IoC的 实现思想。
学到这⾥,我们⼤概就知道了什么是控制反转了,那什么是控制反转容器呢,也就是IoC容器
![](https://i-blog.csdnimg.cn/direct/91cb4dfec76540679690d5f9ffa375b2.png)
这部分代码,就是IoC容器做的⼯作.
从上⾯也可以看出来,IoC容器具备以下优点:
资源不由使⽤资源的双⽅管理,⽽由不使⽤资源的第三⽅管理,这可以带来很多好处。第⼀,资源集中管理,实现资源的可配置和易管理。第⼆,降低了使⽤资源双⽅的依赖程度,也就是我们说的耦合度。
-
- 资源集中管理: IoC容器会帮我们管理⼀些资源(对象等),我们需要使⽤时,只需要从IoC容器中去取 就可以了
-
- 我们在创建实例的时候不需要了解其中的细节,降低了使⽤资源双⽅的依赖程度,也就是耦合度.
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中取出该对象