Spring基础小结
# Spring 基础小结
# Spring 基础
# 什么是 Spring 框架?
Spring 是一款开源的轻量级 Java 开发框架,旨在提高开发人员的开发效率以及系统的可维护性。开箱即用。
一般说 Spring 框架指的都是 Spring Framework
核心功能主要是 IoC 和 AOP。
# Spring 包含哪些模块?
Spring4.x 版本:
Spring5.x 版本:
4.x -> 5.x
主要变化:
- Web 模块的 Portlet 组件被废弃了,
- 同时增加了用于异步响应式处理的 WebFlux 组件
# Core Container
Spring 框架的核心模块,也可以说是基础模块,主要提供 IoC 依赖注入功能的支持。
Spring 其他所有的功能基本都需要依赖于该模块。
主要包含:
- spring-core:Spring 框架基本的核心工具类。
- spring-beans:提供对 bean 的创建、配置和管理等功能的支持。
- spring-context:提供对国际化、事件传播、资源加载等功能的支持。
- spring-expression:提供对表达式语言(Spring Expression Language)SpEL 的支持,只依赖于 core 模块,不依赖于其他模块,可以单独使用。
# AOP
- spring-aspects:该模块为与 AspectJ 的集成提供支持。
- spring-aop:提供了面向切面的编程实现。
- spring-instrument:提供了为 JVM 添加代理(agent)的功能。 具体来讲,它为 Tomcat 提供了一个织入代理,能够为 Tomcat 传递【类文件】,就像这些文件是被类加载器加载的一样。
# Data Access/Integration
- spring-jdbc:提供了对数据库访问的抽象 JDBC。不同的数据库都有自己独立的 API 用于操作数据库,而 Java 程序只需要和 JDBC API 交互,这样就屏蔽了数据库的影响。
- spring-tx:提供对事务的支持。
- spring-orm:提供对 Hibernate、JPA、iBatis 等 ORM 框架的支持。
- spring-oxm:提供一个抽象层支撑 OXM(Object-to-XML-Mapping),例如:JAXB、Castor、XMLBeans、JiBX 和 XStream 等。
- spring-jms : 消息服务。自 Spring Framework 4.1 以后,它还提供了对 spring-messaging 模块的继承。
# Spring Web
- spring-web:对 Web 功能的实现提供一些最基础的支持。
- spring-webmvc:提供对 Spring MVC 的实现。
- spring-websocket:提供了对 WebSocket 的支持,WebSocket 可以让客户端和服务端进行双向通信。
- spring-webflux:提供对 WebFlux 的支持。WebFlux 是 Spring Framework 5.0 中引入的新的响应式框架。与 Spring MVC 不同,它不需要 Servlet API,是完全异步。
# Messaging
spring-messaging 是从 Spring4.0 开始新加入的一个模块,主要职责是为 Spring 框架集成一些基础的报文传送应用。
# Spring Test
提供了对测试的支持,包括了 JUnit 和 TestNG 等测试框架的集成,以及 Spring 应用程序的集成测试等。
# 核心模块总结
- Spring Core 模块:提供了 Spring 框架的核心功能,包括 IoC(控制反转)和 AOP(面向切面编程)等,是整个 Spring 框架的基础。
- Spring Context 模块:建立在 Spring Core 模块之上,提供了一个框架式的上下文环境,用于管理 Bean 的生命周期和配置元数据等。
- Spring JDBC 模块:提供了对 JDBC 的封装,简化了数据库访问的操作,包括了连接管理、事务管理、异常处理等。
- Spring ORM 模块:提供了对 ORM(对象关系映射)框架的支持,包括了 Hibernate、MyBatis 等,使得 Java 应用程序可以方便地访问数据库。
- Spring Web 模块:提供了对 Web 开发的支持,包括了 Web 应用程序的 MVC 框架、RESTful Web 服务、WebSocket 等。
- Spring Test 模块:提供了对测试的支持,包括了 JUnit 和 TestNG 等测试框架的集成,以及 Spring 应用程序的集成测试等。
- Spring Security 模块:提供了对安全性的支持,包括了认证、授权、加密等,使得 Java 应用程序可以更好地保护用户数据和隐私。
# Spring,Spring MVC,Spring Boot 之间是什么关系?
Spring、Spring MVC 和 Spring Boot 是 Spring 框架的三个核心模块。
它们有以下的关系:
Spring
是 Spring 框架的核心模块,主要提供了 IoC 容器、AOP、事务管理等功能,它是其他两个模块的基础。Spring MVC
是在 Spring 基础上开发的 Web 框架,提供了 MVC 架构的支持,可以用来开发 Web 应用程序。Spring MVC 可以通过 Spring IoC 容器来管理控制器、视图和其他组件。Spring Boot
是基于 Spring 框架的快速开发框架,提供了自动化配置、快速启动、自带服务器等功能,可以快速地开发独立的、生产级别的 Spring 应用程序。Spring Boot
不仅整合了 Spring 和 Spring MVC 所有的功能,还提供了许多便利的功能,如对嵌入式服务器的支持、对各种数据源的自动配置等。
因此,可以看出
- Spring MVC 和 Spring Boot 都是建立在 Spring 框架之上的,
- Spring MVC 是 Spring 框架在 Web 开发方面的扩展,
- 而 Spring Boot 则是在 Spring MVC 的基础上,通过自动化配置和快速启动等功能,进一步简化了 Spring 应用程序的开发。
# Spring MVC
# 说说自己对于 Spring MVC 了解?
MVC 是模型(Model)、视图(View)、控制器(Controller)的简写,其核心思想是通过将业务逻辑、数据、显示分离来组织代码。
Spring MVC 是 Spring 框架中的一个模块,用于构建基于 Servlet 的 Web 应用程序,它是一种基于 MVC(Model-View-Controller)设计模式的 Web 框架。
- 模型层(Model)负责业务逻辑
- 视图层(View)负责呈现数据
- 控制器层(Controller)负责接收请求并处理请求,将 Model 和 View 集成在一起。
更早的时期,是使用 Servlet
和 JSP
的时代。
# Spring MVC 的核心组件有哪些?
DispatcherServlet
:核心的中央处理器,负责接收请求、分发,并给予客户端响应。HandlerMapping
:处理器映射器,根据 uri 去匹配查找能处理的Handler
,并会将请求涉及到的拦截器和Handler
一起封装。HandlerAdapter
:处理器适配器,根据HandlerMapping
找到的Handler
,适配执行对应的Handler
。Handler
:请求处理器,处理实际请求的处理器。(Controller)ViewResolver
:视图解析器,根据Handler
返回的逻辑视图 / 视图,解析并渲染真正的视图,并传递给DispatcherServlet
响应客户端。
# 拦截器和过滤器了解么?
拦截器和过滤器都是 Java Web 开发中常用的组件,用于对请求进行拦截和处理,但它们有一些区别。
1、拦截器
拦截器(Interceptor)是 Spring MVC 框架中的一种组件,它可以对请求进行拦截、处理和转发,通常用于实现用户认证、日志记录、性能监控等功能。
拦截器的执行顺序是由配置顺序决定的,可以通过实现 HandlerInterceptor
接口来自定义拦截器。
Spring MVC 框架支持多个拦截器,可以通过配置文件或注解来添加拦截器。
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 在请求处理之前进行拦截,可以进行权限验证、日志记录等操作
return true; // 返回true表示继续执行后续的请求处理
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// 在请求处理之后但还未渲染视图时进行拦截,可以对数据进行处理或者添加公共数据到视图中
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// 在请求处理完成并视图渲染之后进行拦截,可以进行一些资源清理的工作
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
从上面的代码可以看出,拦截器包含三个方法:preHandle
请求的前置拦截、postHandle
请求处理后的拦截、afterCompletion
请求完成后的拦截。
2、过滤器
过滤器(Filter)是 Servlet 规范中的一种组件,它可以对请求进行过滤和处理,通常用于实现字符编码转换、请求参数解析、安全控制等功能。
过滤器的执行顺序是由配置顺序决定的,可以通过实现 Filter
接口来自定义过滤器。
Servlet 规范支持多个过滤器,可以通过配置文件或注解来添加过滤器。
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 过滤器初始化,在应用启动时执行
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// 过滤器主体逻辑,可以在此处进行请求、响应的处理和拦截
chain.doFilter(request, response); // 调用FilterChain的doFilter方法将请求传递给下一个过滤器或Servlet
}
@Override
public void destroy() {
// 过滤器销毁,在应用关闭时执行
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
从上面代码可以看出,过滤器也包含三个方法:init
过滤器初始化、doFilter
过滤器主体逻辑、destroy
过滤器销毁。
3、拦截器和过滤器的区别
拦截器和过滤器的区别在于它们的作用范围和使用场景不同。
拦截器的作用范围是在 Controller 层,用于拦截和处理请求,通常用于实现业务逻辑的控制和处理;
而过滤器的作用范围是在 Servlet 层,用于过滤和处理请求,通常用于实现请求的预处理和后处理。
拦截器和过滤器的使用场景也不同,一般来说,应该优先选择使用拦截器来实现业务逻辑控制和处理,只有在特定的情况下才需要使用过滤器来实现请求的预处理和后处理。
# Spring MVC 的请求处理流程
大致分为 7 个步骤:
- 首先,客户端发送请求到 DispatcherServlet
核心中央处理器
, - 然后 DispatcherServlet 接收请求并将请求交给 HandlerMapping
处理器映射器
进行处理, - HandlerMapping 根据请求的 URL 找到对应的 Controller
请求处理器
, - Controller 处理请求并返回一个
ModelAndView
对象,ModelAndView 包含数据模型和视图名称, - DispatcherServlet 将 ModelAndView 对象交给 ViewResolver
视图解析器
进行处理, - ViewResolver 将逻辑视图名称解析成真正的视图实现,
- 最后 DispatcherServlet 将请求转发到对应的视图实现,由视图实现将模型数据呈现给客户端。
# Spring 框架中用到了哪些设计模式?
- 工厂设计模式 : Spring 使用工厂模式通过
BeanFactory
、ApplicationContext
创建 bean 对象。 - 代理设计模式 : Spring AOP 功能的实现。
- 单例设计模式 : Spring 中的 Bean 默认都是单例的。
- 模板方法模式 : Spring 中
jdbcTemplate
、hibernateTemplate
等以 Template 结尾的对数据库操作的类,它们就使用到了模板模式。 - 包装器设计模式 : 我们的项目需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库。这种模式让我们可以根据客户的需求能够动态切换不同的数据源。
- 观察者模式: Spring 事件驱动模型就是观察者模式很经典的一个应用。
- 适配器模式 : Spring AOP 的增强或通知(Advice)使用到了适配器模式、spring MVC 中也是用到了适配器模式适配
Controller
。
# Spring 事务
# @Transactional(rollbackFor = Exception.class)注解了解吗?
- 在
@Transactional
注解中如果不配置rollbackFor
属性,那么事务只会在遇到RuntimeException
的时候才会回滚, - 加上
rollbackFor=Exception.class
, 可以让事务在遇到非运行时异常时也会回滚。
# 常见反序列化注解
反序列化请求体
@RequestBody
注解:
- 用途:将请求体中的数据反序列化为 Java 对象。
- 用法:通常用于处理发送 JSON 或 XML 数据的 POST 和 PUT 请求。
- 示例:
@RequestBody Person person
反序列化参数
@RequestParam
注解:- 用途:从 URL 查询参数中获取值。
- 示例:
@RequestParam String name, @RequestParam int age
- url:http://localhost:7529/getName?name=zhangsan
@PathVariable
注解:- 用途:从 URL 路径中获取值。(通常用于 Restful 风格接口的实现)
- 示例:
@PathVariable Long id
- url:http://localhost:7529/device/44050000081197526009
@RequestHeader
注解:- 用途:从请求头中获取值,例如获取
Content-Type
或自定义的请求头信息。 - 示例:
@RequestHeader("User-Agent") String userAgent
- 用途:从请求头中获取值,例如获取
- 自定义注解:
- 用途:创建自定义注解来反序列化特定类型的参数。
- 示例:
@DateParam Date birthDate
# Bean 的生命周期
包括以下几个阶段:
- 实例化:容器根据 Bean 定义创建 Bean 的实例。
- 属性填充:容器为 Bean 的属性设置值,包括通过构造函数注入和 setter 方法注入。
- 初始化:在 Bean 实例创建完成并设置好属性后,容器会调用 Bean 的初始化方法。可以通过配置初始化方法,或实现 InitializingBean 接口来自定义初始化逻辑。
- 使用:Bean 可以被应用程序使用,执行业务逻辑。
- 销毁:当 Bean 不再需要时,容器会调用 Bean 的销毁方法。可以通过配置销毁方法,或实现 DisposableBean 接口来自定义销毁逻辑。
# @Configuration 和 @Component 有何区别?
@Configuration
和 @Component
都是 Spring 框架中的注解,它们在将类作为 Spring 的 bean 的工作中发挥着类似的作用。然而,两者具有一些主要的区别:
- 用途
@Component
通常用于下列类上,这些类在应用程序中执行各种类型的业务逻辑。@Configuration
通常应用于配置类,这些类定义了 Spring 容器应如何初始化和配置应用程序上下文。
@Bean
注解@Configuration
类通常会有定义@Bean
的方法,这些方法将实例化,配置并返回需要在应用程序中其他位置注入的对象,这些对象将被 Spring 容器管理。@Component
通常不会有@Bean
注解。
- CGLIB 代理
@Configuration
在运行时会被 Spring 通过 CGLIB 进行子类代理,这是为了方便@Configuration
类中定义的bean
可以被 Spring 容器识别并管理。默认情况下,Spring 容器会考虑到同一个@Configuration
类中的交互,确保正确的单例语义。- 然而,
@Component
不会被 CGLIB 代理。
# 什么是 CGLIB
CGLIB(Code Generation Library)是一个 Java 库,提供了动态生成 Java 字节码的功能。CGLIB 是一个强大的高级类加载器,它使用 ASM(字节码操作工具库)极大提高了性能。
在 Spring 框架中,CGLIB 主要用于代理类(Proxy)
的生成。当 Spring 需要生成一个动态代理类的时候,如果目标类没有实现接口,JDK 动态代理就不能使用了,作为替代,Spring 会用 CGLIB 动态生成一个继承目标类型的子类。这个子类可以覆写父类的所有非 final 方法,并在覆写的方法中添加一些前置或后置等操作。
例如,由 @Configuration
注释的类在运行时会被 Spring 通过 CGLIB 进行子类化,这样才能知道由 @Bean
注释的方法何时被调用,并实现【正确的单例 / 原型】等 bean 作用域语义,同时支持 @Autowired
等注入。
结果是 Spring 使用 CGLIB 在运行时生成一个新的类,它是被代理类的子类,并且包含了增强的代码。这就是 Spring AOP 和事务管理等面向切面编程功能的工作原理。
# 深度考察
# 说说你用过和了解过的 spring 的扩展点,项目中哪里用到了
Spring Framework 提供了许多扩展点,其中一些常见的扩展点包括:
- BeanPostProcessor:允许你在 Spring 容器实例化 bean 之后和初始化 bean 之前自定义 bean 的行为。通常用于 AOP 代理、属性注入等。⭐️
- BeanFactoryPostProcessor:允许你在所有 bean 定义加载到容器之后,但在 bean 实例化之前修改 bean 工厂的内容。通常用于修改属性值或添加属性占位符。⭐️
- ApplicationContextInitializer:用于在应用程序上下文初始化之前执行自定义初始化逻辑。可以用来动态地修改或初始化 Spring 应用程序上下文。⭐️
- ApplicationListener:用于监听 Spring 应用程序中的事件,例如上下文刷新事件、应用程序启动事件等。可以自定义处理事件的逻辑。⭐️
- HandlerInterceptor:用于在 Spring MVC 应用程序中对请求进行拦截和预处理。可以用于实现身份验证、日志记录等功能。⭐️
- ViewResolver:用于解析视图名称并将其映射到实际的视图对象。可以自定义视图解析逻辑,例如将视图名称映射到 JSP、Thymeleaf 等视图技术。
- MessageSource:用于国际化和本地化支持,允许你在应用程序中轻松切换不同的语言和区域设置。
- HandlerMethodArgumentResolver:用于自定义方法参数的解析方式,可以扩展 Spring MVC 的功能,例如解析自定义注解、自定义参数类型等。
- AuthenticationProvider:用于自定义身份验证逻辑,通常与 Spring Security 一起使用,用于实现自定义的身份验证策略。
在项目中,具体使用哪些扩展点取决于项目的需求和架构。例如,
- 如果项目使用了 Spring MVC,那么可能会使用 HandlerInterceptor 来进行请求拦截和处理。
- 如果需要自定义 Bean 的初始化过程,可能会使用 BeanPostProcessor 或 BeanFactoryPostProcessor。(手写 bean 也会用到)
- 如果需要实现国际化支持,可能会配置 MessageSource。
# spring mvc 的拦截器,servlet 的过滤器,spring gateway 的过滤器。他们几个区别是什么,都在哪些场景下用?
Spring MVC 的拦截器、Servlet 的过滤器以及 Spring Cloud Gateway 的过滤器都用于对 HTTP 请求进行预处理、拦截和处理,但它们在不同的层级和场景下使用,并具有不同的功能和特点:
- Spring MVC 的拦截器:
- 层级:工作在 Spring MVC 框架内部,用于拦截 Spring MVC 中的 Controller 请求。
- 主要功能:对 Controller 层进行拦截,可以在请求到达 Controller 之前和之后执行自定义逻辑,如身份验证、日志记录、权限控制等。
- 场景:适用于单体应用程序,用于处理请求的前置和后置逻辑,以及与 Web 应用程序相关的业务逻辑。
- Servlet 的过滤器:
- 层级:工作在 Servlet 容器级别,位于 Web 应用程序的请求处理管道中,可以拦截所有 Servlet 请求。
- 主要功能:对所有 HTTP 请求进行拦截和处理,包括静态资源请求、Servlet 请求等。常用于日志记录、字符编码转换、跨域处理等通用性任务。
- 场景:适用于任何基于 Servlet 的 Web 应用程序,用于执行通用的请求处理逻辑,无论是单体应用还是分布式应用。
- Spring Cloud Gateway 的过滤器:
- 层级:工作在微服务网关层级,用于处理分布式系统中的请求路由、请求转发、身份验证、限流等任务。
- 主要功能:在微服务架构中,Gateway 充当请求的入口,通过配置一系列过滤器来执行请求处理逻辑。这些过滤器可以进行路由、权限校验、熔断、限流等功能。
- 场景:适用于微服务架构中,用于构建高度灵活、可伸缩的 API 网关。可以实现微服务之间的请求路由、请求合并、安全验证等功能。
总的来说,这三种过滤/拦截机制各自有不同的作用范围和功能:
- Spring MVC 的拦截器用于对 Controller 请求的拦截和处理。
- Servlet 的过滤器用于对所有 Servlet 请求的拦截和处理。
- Spring Cloud Gateway 的过滤器用于构建微服务架构下的 API 网关,实现请求路由和各种微服务相关的处理逻辑。
Controller 请求和 Servlet 请求之间的关系
Servlet 请求是 Web 应用程序中的原始 HTTP 请求,而 Controller 请求是 Spring MVC 中的处理器方法,用于处理特定 URL 映射的请求。
Spring MVC 使用 Servlet 容器来接收和处理 HTTP 请求,然后将请求分发给适当的 Controller 请求进行处理。
Servlet 请求包含了 Controller 请求。
- Servlet 请求是 Web 应用程序接收的原始 HTTP 请求,它包含了客户端浏览器发送的全部信息,包括请求头、请求方法、请求参数等。
- Controller 请求是在 Spring MVC 或类似的框架中定义的处理器方法,用于处理特定 URL 映射的请求。这些方法接收 Servlet 请求作为输入,可以从中提取数据、执行业务逻辑,并生成响应。
因此,Controller 请求是在 Servlet 请求的基础上定义的,用于更方便地处理和分发请求,实现了更高级别的请求处理逻辑。