🤞目录🤞
【大家好,我是爱干饭的猿,如果喜欢这篇文章,点个赞👍,关注一下吧,后续会持续分享每日一题和SSM其他重要知识点总结】
上一篇文章:《【Linux】部署web项目》
SSM(Spring+SpringMVC+MyBatis)框架集由Spring、MyBatis两个开源框架整合而成(SpringMVC是Spring中的部分内容),常作为数据源较简单的web项目的框架。
🀄1. 什么是Spring?
我们通常说的 Spring 指的是 Spring Framework (Spring 框架)。
一句话概括Spring:Spring 是包含了众多工具方法的loC容器。
🃏1.1 什么是容器?
容器是用来容纳某种物品的(基本)装置。
例如:
- List/Map -> 数据存储容器
- Tomcat -> Web 容器
🃏1.2 什么是IoC?
- Spring -> IoC 容器
IoC (Inversion of Control) 指 “控制反转”,也就是说 Spring 是一个“控制反转”容器。
1.2.1 传统程序开发 & 控制反转式程序开发
假如,我们现在构建一辆“车”的程序,我们的实现思路是这样的:
- 在传统的代码中对象创建顺序是:Car -> Framework -> Bottom -> Tire
- 改进之后解耦的代码的对象创建顺序是:Tire -> Bottom -> Framework -> Car
编辑
规律:
- 传统代码是Car 控制并创建了 Framework,Framework 创建并创建了 Bottom,依次往下;
- 而改进之后的控制权发生的反转,不再是上级对象创建并控制下级对象了,而是下级对象把注入将当前对象中,下级的控制权不再由上级类控制 了,这样即使下级类发生任何改变,当前类都是不受影响的,这就是典型的控制反转,也就是 IoC 的实 现思想。
🃏1.3 理解 Spring IoC
既然 Spring 是一个 IoC(控制反转)容器,重点还在“容器”二字上,那么它就具备两个最基础的功能:
- 将对象存入到容器
- 从容器中取出对象
也就是说学 Spring 最核心的功能,就是学如何将对象存入到 Spring 中,再从 Spring 中获取对象的过 程。
IoC 容器 和普通程序开发的区别:
将对象存储在 IoC 容器相当于将以后可能用的所有工具制作好都放 到仓库中,需要的时候直接取就行了,用完再把它放回到仓库。而 new 对象的方式相当于,每次 需要工具了,才现做,用完就扔掉了也不会保存,下次再用的时候还得重新做。
Spring 是一个 IoC 容器,说的是对象的创建和销毁的权利都交给 Spring 来管理了,它本身又具备了存 储对象和获取对象的能力。
🃏1.4 DI 概念
DI (Dependency Injection) 指的是“依赖注入”。
所谓依赖注入,就是 loC 容器在运行期间,动态地将某种依赖关系注入到对象之中。所以,依赖注入(DI)和控制反转(IoC)是从不同的角度的描述的同一件事情,就是指通过引入 IoC 容器,利用依赖关系注入的方式,实现对象之间的解耦。
IoC 是方法思想,DI 是具体实现。
🀄2. 存储 Bean 对象
🃏2.1 前置工作:配置扫描路径(重要)
注意:想要将对象成功的存储到 Spring 中,我们需要配置一下存储对象的扫描包路径,只有被配置的包下的所有类,添加了注解才能被正确的识别并保存到 Spring 中。
在 spring-config.xml 添加如下配置:
<?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"> <content:component-scan base-package="com.bit.service"></content:component- scan> </beans>
其中标红的一行为注册扫描的包,如下图所示:
编辑
🃏2.2 添加注解存储 Bean 对象
想要将对象存储在 Spring 中,有两种注解类型可以实现:
- 类注解:@Controller、@Service、@Repository、@Component、@Configuration。
- 方法注解:@Bean。
2.2.1 @Controller (控制器存储)
使用 @Controller 存储 bean 的代码如下所示:
@Controller // 将对象存储到 Spring 中 public class UserController { public void sayHi(String name) { System.out.println("Hi," + name); } }
此时我们先使用之前读取对象的方式来读取上面的 UserController 对象,如下代码所示:
public class Application { public static void main(String[] args) { // 1.得到 spring 上下文 ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml"); // 2.得到 bean UserController userController = (UserController) context.getBean("userController"); // 3.调用 bean 方法 userController.sayHi("Bit"); } }
其他注解方法类似
- @Service(服务存储)
- @Repository(仓库存储)
- @Component(组件存储)
- @Configuration(配置存储)
🃏2.3 为什么要这么多类注解?
就是让程序员看到类注解之后,就能直接了解当前类的用途
比如:
- @Controller:表示的是业务逻辑层;
- @Servie:服务层;
- @Repository:持久层;
- @Configuration:配置层。
程序的工程分层,调用流程如下:
编辑
2.3.1 类注解之间的关系
其实@Controller / @Service / @Repository / @Configuration 注解里面都有一个注解 @Component,说明它们本身就是属于 @Component 的“子类”。
🀄3. 获取 Bean 对象(对象装配)
获取 bean 对象也叫做对象装配,是把对象取出来放到某个类中,有时候也叫对象注入。
对象装配(对象注入)的实现方法以下 3 种:
- 属性注入
- 构造方法注入
- Setter 注入
🃏3.1 属性注入
属性注入是使用 @Autowired 实现的,将 Service 类注入到 Controller 类中。
Service 类的实现代码如下:
import org.springframework.stereotype.Service; @Service public class UserService { public User getUser(Integer id) { // 伪代码,不连接数据库 User user = new User(); user.setId(id); user.setName("Java-" + id); return user; } }
Controller 类的实现代码如下:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; @Controller public class UserController { // 注入方法1:属性注入 @Autowired private UserService userService; public User getUser(Integer id) { return userService.getUser(id); } }
获取 Controller 中的 getUser 方法:
public class UserControllerTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml"); UserController userController = context.getBean(UserController.class); System.out.println(userController.getUser(1).toString()); } }
🃏3.2 构造方法注入
构造方法注入是在类的构造方法中实现注入,如下代码所示:
@Controller public class UserController2 { // 注入方法2:构造方法注入 private UserService userService; @Autowired public UserController2(UserService userService) { this.userService = userService; } public User getUser(Integer id) { return userService.getUser(id); } }
🃏3.3 Setter 注入
Setter 注入和属性的 Setter 方法实现类似,只不过在设置 set 方法的时候需要加上 @Autowired 注解,如下代码所示:
@Controller public class UserController3 { // 注入方法3:Setter注入 private UserService userService; @Autowired public void setUserService(UserService userService) { this.userService = userService; } public User getUser(Integer id) { return userService.getUser(id); } }
本次分享就到这里,如果你喜欢这篇文章,请点赞加关注吧,或者如果你对文章有什么困惑,可以私信我。
🏓🏓🏓