Java之Spring基础
Spring是框架?
其实这个问题困扰了我大几个月,有人说Spring是框架,也有人说Spring是一个生态系统,我更偏向于后者吧,广义上来说Spring不是一个简单的框架,而是构成一个完整的生态体系,但是往往我们口中的Spring都会被特指成Spring Framework,所以也就有极大部分人把Spring看成是一个框架。那我们后面就把他当作是一个框架(Spring Framework)吧
官方文档:https://spring.io/
总结来说:Spring框架是一个开源的轻量级的控制反转(IoC)和面向切面(AOP)的容器框架
Spring框架的特性
控制反转(IoC)和依赖注入(DI)
什么是控制反转呢?
在传统的Java开发中,对象需要自己创建并查找依赖对象建立依赖关系
例如
1 | // 用户服务类 |
这种传统方式下存在的问题:
- 高耦合度,UserService 和 UserRepository 紧密绑定,UserService 必须知道如何创建 UserRepository
- 测试困难,当我们需要测试UserService 时,必须实例化一个真实的UserRepository,这样会加大测试的工作量
- 紧密关联带来的低灵活性,如果我们想改变UserRepository的实现代码,就必须对UserService 代码也进行改变
但是在IoC中,Spring容器会负责创建对象并注入依赖关系,顾名思义就是“控制权发生了反转”
IoC的写法
1 |
|
这样就大大降低了组件之间的耦合度,提高了代码的可测试性和可维护性。
依赖注入(DI)其实就是IoC的具体实现方式,依赖注入的方式包括:
- 构造器注入(推荐)
- 字段注入
- Setter注入
- 接口注入
写个代码
1 | // 方式1: 构造器注入 (推荐) |
需要注意的是,DI不等于IoC,DI只是IoC里面对依赖和对象的具体处理方式
面向切面(AOP)
先了解AOP中的几个关键概念:
1.横切关注点:就是一些跟业务逻辑无关但是又必须存在的公共功能
常见的横切关注点包括:
- 日志记录: 方法执行前后记录日志
- 权限控制: 检查用户是否有权限
- 事务管理: 开启、提交、回滚事务
- 性能监控: 统计方法执行时间
- 异常处理: 统一处理异常
- 缓存: 缓存方法结果
- 数据验证: 验证参数
2.切面:横切关注点的模块化
3.连接点:可以插入切面的程序执行点,通常是方法的调用或执行点
4.切入点:定义在哪些连接点需要切面
5.通知:在切入点上要执行的具体操作,例如前置(Before)、后置(After)、返回后(After Returing)、异常后(After Throwing)、环绕(Around)
6.织入:将切面应用到目标对象的过程,Spring支持基于代理的运行时织入
7.代理:Spring AOP 通过 JDK 动态代理或 CGLIB 代理来实现织入
AOP其实就是一种编程思想,将这些公共功能从业务逻辑中抽离出来统一进行处理,即通过切面来封装这些横切关注点,并在运行时或编译时”织入”到目标代码中,从而实现模块化管理,也能提高代码的灵活性。
AOP的几个核心注解
@Aspect:声明一个横切关注点切面@Pointcut:定义一个切入点@Before:前置通知,即在方法执行前执行切面@After:后置通知,即在方法执行后执行切面,无论方法是否成功执行@AfterReturning:返回后通知,即方法成功返回后执行切面@AfterThrowing:异常通知,即方法抛出异常后执行切面@Around:环绕通知,是前面几种通知的组合
Spring框架的组成
Spring Framework作为最核心的框架,主要包含:
- Core Container 核心容器:主要负责IoC控制反转和DI依赖注入
核心容器包含模块:spring-core,spring-beans,spring-context,spring-expression (SpEL)
spring-core和spring-beans是框架最基础的部分,包括控制反转和依赖注入功能
spring-context提供了访问对象的方式,有点类似于JNDI注册
spring-expression提供了一种很强大的表达式,即SpEL表达式,可以在运行时查询和操作对象
- AOP模块:主要负责切面编程的实现
主要包含模块:spring-aop,spring-ascpects,spring-instrument,spring-instrument-tomcat
spring-aop主要是提供了基于代理的AOP实现
spring-ascpects集成了AspectJ,实现更强大的AOP
spring-instrument提供了类工具的支持和类加载器的实现,可以在特定的应用服务器中使用。
spring-instrument-tomcat模块提供针对tomcat的instrument实现。
- Data Access/Integration 数据访问/集成模块:主要负责JDBC数据库操作以及事务管理
主要包含模块:spring-jdbc,spring-tx,spring-orm,spring-oxm,spring-jms
spring-jdbc提供了对JDBC的封装,简化了数据库访问和操作
spring-tx提供了一套统一的事务抽象,让不同数据源的事务用同一种方式集中管理
spring-orm提供与流行的“对象-关系”映射框架无缝集成的 API,包括 JPA、JDO、Hibernate 和 MyBatis 等
spring-oxm提供了一个支持 Object /XML 映射的抽象层实现
spring-jms是对JMS标准的封装,提供发送消息和接收消息等消息服务功能
- Web模块:提供Web模块的功能包括基础Web执行,MVC架构
主要包含:spring-web,spring-webmvc,spring-websocket,spring-webflux
spring-web提供了最基础的web支持例如Servlet,文件上传等
spring-webmvc提供了一个 Spring MVC Web 框架实现。Spring MVC 框架提供了基于注解的请求资源注入、更简单的数据绑定、数据验证等及一套非常易用的 JSP 标签,并且能很好的和其他功能结合协同办公
spring-websocket提供了WebSocket 支持进行实时通讯
spring-webflux是响应式 Web 框架,特点是少量线程处理多个请求,可支持异步大并发请求
- Test测试模块,就是一个测试框架,主要包括spring-test
- Messaging消息模块,统一消息抽象,主要包括spring-messaging
官方的图

总结来说:Spring 框架是一个分层的 Java 应用开发框架,由 6 大模块构成:核心容器(IoC/DI)、AOP 模块、数据访问模块、Web 模块、消息模块和测试模块。这些模块协作支持从底层容器管理,到面向切面编程、数据访问、MVC Web 开发及测试的完整开发体系。
Spring MVC架构
参考文章:https://blog.csdn.net/zzuhkp/article/details/120685952
Spring MVC架构主要是Web层的框架,MVC(Model View Controller)指的是模型-视图-控制器三个核心组件,MVC架构主要是将用户交互拆分到这三个组件中,接下来我们分开讲讲
- **模型(Model)**:模型封装了数据及对数据的操作,可以直接对数据库进行访问,不依赖视图和控制器,也就是说模型并不关注数据如何展示,只负责提供数据。GUI 程序模型中数据的变化一般会通过观察者模式通知视图,而在 web 中则不会这样。
- **视图(View)**:视图从模型中拉取数据,只负责展示,没有具体的程序逻辑。
- **控制器(Controller)**:控制器用于控制程序的流程,将模型中的数据展示到视图中。
为什么MVC好
我觉得这个原因是比较重要的,知道他好在哪里才会喜欢用他嘛
早期的JavaEE项目通常使用Servlet去处理请求,但是Servlet的缺点是会产生大量的冗余代码,不适合输出复杂的HTML,后来Sun公司根
据asp提出了JSP,JSP是基于 Java 的一种 动态网页技术。JSP 文件本质上就是一个 HTML + Java 代码的混合文件,后缀是 .jsp,虽然他很适合进行HTML+Java的开发,但是也不适合编写复杂的Java代码
哎,可以看到这两个其实在优缺点上是互补的,那么是否可以结合这两个从而发挥出其最大的作用呢?
有的兄弟,有的,Web MVC被提出,JavaBean充当模型,而JSP文件作为视图,Servlet作为控制器
借鉴一下师傅的流程图

客户端发送请求后先经过Servlet,Servlet会使用JavaBean查询并存储数据,然后将数据交给JSP进行渲染生成视图,那么这就是早期的Web MVC架构
直到后来出现了Spring MVC结构模式
Spring MVC架构模式的组成
Spring MVC架构遵循了Servlet规范 ,并对早期的Web MVC加以拓展,将控制器拆分成前端控制器DispatcherServlet,处理器映射器HandlerMapping和后端控制器Controller,将模型拆分成业务层Service和数据访问层Repository,同时也不止支持JSP,还支持入FreeMarker等
具体的请求流程还是借鉴师傅的图

MVC请求流程
- 客户端发送请求到前端控制器DispatcherServlet,前端控制器DispatcherServlet根据HandlerMapping找到对应的Controller方法进行分发请求给后端控制器Controller
- 后端控制器Controller根据请求选择合适的 Model 和 View 名称
ViewResolver根据后端控制器返回的View名称找到真正需要的 ViewView接收返回的 Model 进行渲染- DispatcherServlet前端控制器将渲染的结果返回给客户端用户
SpringBoot
SpringBoot主要是用来快速构建Spring应用的
在之前我们开发一个Spring Web项目通常需要配置很多东西例如web.xml,Spring MVC,事务管理等,而Spring Boot会根据我们加入我依赖自动配置需要的Bean,并且还内置了Tomcat/Jerry/Netty等服务器,这让我们的Java Web服务启动更加便捷
Starter依赖
Starter依赖的作用主要是继承了某一类功能所需要的所有依赖,例如spring-boot-starter-web,当我们导入这个依赖后Spring Web开发所需要的依赖都集成在里面可供使用,并且Starter依赖由Spring Boot 统一管理版本,非常的方便和美味
Spring Boot 官方的几种Starter依赖:
| Starter | 用途 |
|---|---|
| spring-boot-starter-web | 构建 Web/MVC/REST API |
| spring-boot-starter-test | 测试工具集 |
| spring-boot-starter-data-jpa | JPA + Hibernate |
| spring-boot-starter-thymeleaf | Thymeleaf 模板引擎 |
| spring-boot-starter-security | Spring Security 认证授权 |
| spring-boot-starter-actuator | 监控与健康检查 |