目录
Spring 是什么?
什么是容器?
什么是 IoC?
什么是 IoC?
IoC的优点是啥呢?
理解 IoC
DI 概念说明
Spring 的创建
创建 Spring 项目
1. 创建⼀个普通 Maven 项⽬。
2. 添加 Spring 框架⽀持(spring-context、spring-beans)。
3. 添加启动类
将 bean 对象存储到 Spring(IoC)中
将 bean 对象从 Spring(IoC)中 取出
在开始Spring的创建和使用之前先来看看Spring的基本概念
Spring 是什么?
我们通常所说的 Spring 指的是 Spring Framework(Spring 框架),它是⼀个开源框架,有着活跃⽽庞⼤的社区,这就是它之所以能⻓久不衰的原因。Spring ⽀持⼴泛的应⽤场景,它可以让 Java 企业级的应⽤程序开发起来更简单。
⽤⼀句话概括 Spring:Spring 是包含了众多⼯具⽅法的 IoC 容器。 这里的众多工具体现在哪呢?这个慢慢学Spring都会介绍到。
那问题来了,什么是容器?什么是 IoC 容器?
什么是容器?
容器就是用来装某个物体的,我们之前就有学过容器:
- List/Map -> 数据存储容器
- Tomcat -> Web 容器
什么是 IoC?
Spring 也是⼀个容器,Spring 是什么容器呢?Spring 是⼀个 IoC 容器
什么是 IoC?
IoC = Inversion of Control 翻译成中⽂是“控制反转”的意思,也就是说 Spring 是⼀个“控制反转”的容器,怎么理解这句话呢?
控制(权)反转,指的是:对象的生命周期的控制权(原本属于 程序员/代码片段 控制),现在交给了Spring容器控制或者是IoC 容器控制
IoC的优点是啥呢?
答:可以实现解耦合(松耦合)
我们具体来举个栗子,具体的看看IoC的实现。
我们就创建一个普通的类:
我们的需求是这样的:
- 我们创建一辆车依赖了车的车身;
- 这个框架又依赖着车的底盘
- 这个底盘又依赖着车的轮胎
代码如下:
车身依赖底盘
底盘依赖轮胎
轮胎本身自带一个size 属性:
ok,旧的需求写到这里,我们客户现在需要自己规定轮胎大小,而不是每次都默认大小,那么从最底层 Tire 开始要进行传参 int size
此时就开始体现了耦合性太高,假设我们又有一个需求,需要换车身颜色呢?又需要从最底层开始向上修改到最高层所有的参数。
那么如果是用IoC 容器就很好的解决了这个问题。
这就很好的进行了 解耦合。
对比总结:
在传统的代码中对象创建顺序是:Car -> Framework -> Bottom -> Tire
改进之后解耦的代码的对象创建顺序是:Tire -> Bottom -> Framework -> Car
理解 IoC
回到我们的主题 Spring,本⽂刚开始咱们就讲:Spring 是包含了多个⼯具⽅法的 IoC 容器,这就是对 Spring 最核⼼的总结。“集成多个⼯具⽅法”这事咱们以后慢慢再讲,那如何理解“Spring 是⼀个 IoC 容器”这句话呢?
既然 Spring 是⼀个 IoC(控制反转)容器,重点还在“容器”⼆字上,那么它就具备两个最基础的功
能:
- 将对象存⼊到容器;
- 从容器中取出对象。
也就是说学 Spring 最核⼼的功能,就是学如何将对象存⼊到 Spring 中,再从 Spring 中获取对象的过程。
将对象存放到容器中的好处:将对象存储在 IoC 容器相当于将以后可能⽤的所有⼯具制作好都放到仓库中,需要的时候直接取就⾏了,⽤完再把它放回到仓库。⽽ new 对象的⽅式相当于,每次需要⼯具了,才现做,⽤完就扔掉了也不会保存,下次再⽤的时候还得重新做,这就是 IoC 容器和普通程序开发的区别。
Spring 是⼀个 IoC 容器,说的是对象的创建和销毁的权利都交给 Spring 来管理了,它本身⼜具备了存储对象和获取对象的能⼒
DI 概念说明
说到 IoC 不得不提的⼀个词就是“DI”,DI 是 Dependency Injection 的缩写,翻译成中⽂是“依赖注
⼊”的意思。
所谓依赖注⼊,就是由 IoC 容器在运⾏期间,动态地将某种依赖关系注⼊到对象之中。所以,依
赖注⼊(DI)和控制反转(IoC)是从不同的⻆度的描述的同⼀件事情,就是指通过引⼊ IoC 容
器,利⽤依赖关系注⼊的⽅式,实现对象之间的解耦。
二者的区别:
IoC 是“⽬标”也是⼀种思想,⽽⽬标和思想只是⼀种指导原则,最终还是要有可⾏的落地⽅案,⽽ DI就属于具体的实现
Spring 的创建
Spring 就是⼀个包含了众多⼯具⽅法的 IoC 容器。既然是容器那么
它就具备两个最基本的功能:
- 将对象存储到容器(Spring)中;
- 从容器中将对象取出来
那么本章的重点就是 怎么存和 怎么取
创建 Spring 项目
接下来使⽤ Maven ⽅式来创建⼀个 Spring 项⽬,创建 Spring 项⽬和 Servlet 类似,总共分为以下 3步:
- 创建⼀个普通 Maven 项⽬。
- 添加 Spring 框架⽀持(spring-context、spring-beans)。
- 添加启动类
步骤:
1. 创建⼀个普通 Maven 项⽬。
2.
3. 打开后就是这样的maven 项目:
这里还不算完,这里还需要正确配置 maven 国内源(学习Java 最容易出错的地方就是 Spring):
正确配置 maven 国内源
我们还需要去这个目录底下看一看:
情况 1 :
有些电脑会没有 settings.xml ,那么直接下载
链接:https://pan.baidu.com/s/1ctb6n0TLAy3QjmjvWNXZYw
提取码:1234
我已经上传至我的百度网盘,这个文件很小,只有 10k 。
切记,千万不要手动创建 settings.xml 文件。
如果是上述情况,那么到这里就ok 了。
情况 2 :
如果有这个文件,那么需要用记事本或者 vscode 打开:
找到 mirrors 这个标签,在这个标签下手动添加:
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>central</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
到这里,配置第一步就完成了。
然后,我们需要将repository 这个目录地下的所有文件删除:
ctrl + A 全选中,然后 delete 。
这个是可以删的,我们idea 在后台会自动去搜索 本地仓库是否存在它依赖的文件(资源),如果不存在,idea 会去Maven 中央仓库下载,我们上述正确配置 了 Maven 国内源,它会下载的很快。
我们手动的强制刷新以下,idea 就会开始下载 。
稍等一会就欧克了。
2. 添加 Spring 框架⽀持(spring-context、spring-beans)。
在项⽬的 pom.xml 中添加 Spring 框架的⽀持,xml 配置如下:
<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>
从上述配置中可以看出,添加的框架有 spring-context:spring 上下⽂,还有 spring-beans:管理对象的模块。
3. 添加启动类
最后在创建好的项⽬ java ⽂件夹下创建⼀个启动类,包含 main ⽅法即可
将 bean 对象存储到 Spring(IoC)中
创建一个 bean 对象:
将 bean 存入到 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" xmlns:content="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd (空格)http://www.springframework.org/schema/context (空格)https://www.springframework.org/schema/context/spring-context.xsd"> </beans>
将 bean 对象从 Spring(IoC)中 取出
获取到Spring 上下文对象:
得到 Spring 上下⽂对象,因为对象都交给 Spring 管理了,所以获取对象要从 Spring 中获取,那
么就得先得到 Spring 的上下⽂。
获取 bean 对象
通过 Spring 上下⽂,获取某⼀个指定的 Bean 对象。
这里getBean()获取到的是一个 Object 对象,所以需要强转
我们来看看结果如何:
当然,我们不止有以上的方法 获取到Spring 上下文对象,我们还可以用:
这样其实也可以获取 Spring 对象,我们来看看效果:
既然都可以获取到 Bean 对象我们来看看二者的区别(这也是面试会问的考点):
- 相同点:都是容器管理对象,都可以获取到 Bean对象
- 区别:
ApplicationContext 属于 BeqnFactory 的子类,ApplicationContext 可以实现更多功能,具体有(对国际化⽀持、资源访问⽀持、以及事件传播等⽅⾯的⽀持)- 加载Bean 的机制不同:BeqnFactory 属于懒加载,按需加载(使用一个 Bean则加载一个 Bean),ApplicationContext 一次性全部加载
第二点的出现原因在于:BeqnFactory 出现时间比 ApplicationContext 早,在早期空间十分有限,过去的硬件资源太昂贵了,现在硬件的资源大幅度下降。
案例演示:
我们再添加 一个 Teacher 类,并加上一个构造方法,同理原来的 User 也加上一个构造方法:
将这两个 Bean 对象都存入 容器中:
再来对比二者结果:
ApplicationContext :
我们再来看看 BeqnFactory:
getBean的更多用法
这里的坑还是很多的,我们来简单介绍结果
用法一:根据名称获取 Bean 对象
用法二:根据类型获取 Bean 对象
可能出现的问题:当同一个类型多个注入到 Spring 的情况下,那么使用就会报错:
用法三:根据名称 + 类型获取
总结:
1. 操作容器之前,先要有容器,所以先要得到容器。
2. 存对象
a. 创建 Bean(普通类)。
b. 将 Bean 注册(配置)到 spring-confing.xml 中。
3. 取对象
a. 得到 Spring 上下⽂,并读取到 Spring 的配置⽂件。
b. 获取某⼀个 Bean 对象。
c. 使⽤ Bean 对象
操作流程如下:
Spring 就是个框架,我们要使用框架就应该很简单,这样获取和存储,还是很麻烦,我们下一章会介绍更简单的 存储方式 和 获取方式。