1.简述Spring,SpringMVC,SpringBoot各自特点及联系
Spring、Spring MVC 和 Spring Boot 是 Java 开发中常用的三个框架,它们之间有以下关系:
Spring:是一个全功能的 JavaEE 应用程序框架。它提供了一系列的解决方案,用于开发企业级应用程序,包括依赖注入、面向切面编程、事务管理等等。Spring 框架是模块化的,你可以根据需求单独使用其中的部分功能。Spring 提供了一系列模块,如 Spring Core、Spring JDBC、Spring ORM、Spring AOP 等等,每个模块都提供了特定的功能。
Spring MVC:是 Spring 框架的一个模块,用于开发 Web 应用程序。它提供了一种基于 MVC(Model-View-Controller)架构的设计模式,用于构建 Web 应用程序。在 Spring MVC 中,控制器(Controller)负责处理用户请求,并调用适当的业务逻辑,然后渲染适当的视图(View)返回给用户。Spring MVC 提供了很多功能,如处理表单提交、验证用户输入、处理文件上传等等。
Spring Boot:是 Spring 团队提供的一个快速开发框架,旨在简化 Spring 应用程序的配置和部署。它通过约定优于配置的原则,让开发人员可以快速搭建基于 Spring 的应用程序。Spring Boot 提供了自动配置(auto-configuration)功能,可以根据 classpath 中的 jar 包、bean 的定义以及其他因素自动配置 Spring 应用程序。此外,Spring Boot 还提供了一组开箱即用的功能,如内嵌的 Web 服务器(如Tomcat、Jetty)、健康检查、度量指标、安全性等。
总的来说,Spring 提供了核心的功能和特性,Spring MVC 用于开发 Web 应用程序,而 Spring Boot 则是用于快速构建和部署基于 Spring 的应用程序的工具。Spring Boot 通常与 Spring MVC 配合使用,但也可以与其他 Spring 模块一起使用,例如 Spring Data、Spring Security 等等。
2.Spring模块介绍
Spring Core: Spring Core 模块提供了 Spring 框架的核心功能,包括依赖注入(Dependency Injection即DI)和控制反转(Inversion of Control即IOC)等。这些功能是 Spring 框架的基础,许多其他 Spring 模块都依赖于 Spring Core 模块。
具体可参考https://zhuanlan.zhihu.com/p/448716053
3.Spring框架中都应用到了哪些设计模式
(1)简单工厂模式
BeanFactory:Spring的BeanFactory充当工厂,负责根据配置信息创建Bean实例。它是一种工厂模式的应用,根据类名或ID创建Bean对象。
(2)工厂方法模式
(3)单例模式
(4)适配器模式
(5)装饰器模式
(6) 代理模式
(7)观察者模式
(8)策略模式
(9)模板方法模式
(10)责任链模式
4.介绍一下Spring IOC
Spring 的 IoC(Inversion of Control,控制反转)是 Spring 框架的核心特性之一,它的作用是实现了松耦合和依赖注入,使得应用程序的组件之间的关系更加灵活、可维护和可测试。
-
管理 Bean: IoC 容器负责管理应用程序中的组件(Bean),包括创建、销毁、依赖注入等。
-
松耦合: IoC 实现了组件之间的解耦,降低了组件之间的依赖关系,提高了代码的灵活性和可维护性。
-
依赖注入: IoC 容器将依赖关系注入到组件中,从而实现了组件之间的解耦,降低了组件的耦合度。
Spring IOC容器的加载过程
Spring IOC(Inversion of Control,控制反转)容器的加载过程是 Spring 应用程序启动的关键部分,它负责加载、初始化和管理应用程序中的所有 Bean 对象。以下是 Spring IOC 容器的加载过程:
-
加载配置文件:
Spring IOC 容器会根据配置文件(如 XML 配置文件、Java 配置类等)来加载应用程序的 Bean 定义。这些配置文件通常包含了 Bean 的定义信息,包括 Bean 的名称、类路径、属性值等。 -
创建 Bean 容器:
一旦配置文件加载完成,Spring IOC 容器会根据配置信息来创建一个容器对象,用于管理应用程序中的所有 Bean 对象。 -
解析 Bean 定义:
Spring IOC 容器会解析配置文件中的 Bean 定义,包括 Bean 的名称、类路径、属性值等信息。在解析过程中,Spring IOC 容器会根据配置信息来创建相应的 BeanDefinition 对象,并将其注册到容器中。 -
实例化 Bean:
一旦 Bean 定义解析完成,Spring IOC 容器会根据 Bean 定义中的信息来实例化 Bean 对象。这通常涉及到使用 Java 反射机制来调用 Bean 的构造方法或者工厂方法来创建 Bean 实例。 -
注入依赖:
一旦 Bean 实例化完成,Spring IOC 容器会根据配置信息来自动注入 Bean 的依赖关系。这通常涉及到使用 Java 反射机制来调用 Bean 的 setter 方法或者字段注入来设置 Bean 的属性值。 -
初始化 Bean:
一旦 Bean 的依赖注入完成,Spring IOC 容器会调用 Bean 的初始化方法(如果定义了的话)。初始化方法通常用于执行一些初始化操作,如连接数据库、加载配置文件等。 -
注册 Bean:
一旦 Bean 初始化完成,Spring IOC 容器会将 Bean 注册到容器中,并分配一个唯一的标识符(Bean 的名称或者 ID)。这样其他的 Bean 就可以通过这个标识符来获取对应的 Bean 实例。 -
容器就绪:
一旦所有的 Bean 都注册到容器中,Spring IOC 容器就进入了就绪状态,可以开始处理来自客户端的请求,并管理应用程序中的所有 Bean 对象。
综上所述,Spring IOC 容器的加载过程包括加载配置文件、创建 Bean 容器、解析 Bean 定义、实例化 Bean、注入依赖、初始化 Bean、注册 Bean 和容器就绪等步骤。这个过程是 Spring 应用程序启动的关键部分,它负责加载、初始化和管理应用程序中的所有 Bean 对象,实现了控制反转和依赖注入的功能。
补充:
- 实例化前置处理(InstantiationAwareBeanPostProcessor)
在Bean实例化之前,Spring IOC容器会调用InstantiationAwareBeanPostProcessor接口中的方法来处理Bean的实例化过程。这个阶段的处理包括:
postProcessBeforeInstantiation方法:在实例化Bean之前被调用,可以通过该方法返回一个代理对象或者null来控制Bean的实例化过程。
postProcessAfterInstantiation方法:在实例化Bean之后被调用,用于处理Bean实例化后的逻辑。
- 初始化前置处理(BeanPostProcessor)
在Bean实例化之后,Spring IOC容器会调用BeanPostProcessor接口中的方法来处理Bean的初始化过程。这个阶段的处理包括:
postProcessBeforeInitialization方法:在Bean的初始化方法调用之前被调用,可以在这个方法中进行一些自定义的初始化逻辑。
postProcessAfterInitialization方法:在Bean的初始化方法调用之后被调用,用于处理Bean初始化后的逻辑。
5.介绍一下Spring AOP
Spring AOP(Aspect-Oriented Programming,面向切面编程)是 Spring 框架的一个重要特性,它提供了一种方法来使得程序的横切关注点(如日志记录、性能统计、事务管理等)与核心业务逻辑相分离,从而提高了代码的模块化程度。
6.Spring MVC的工作原理是什么?
Spring MVC 是 Spring 框架中的一个模块,用于构建基于 Java 的 Web 应用程序。它采用了经典的 MVC(Model-View-Controller)设计模式,将应用程序分为模型、视图和控制器三层,以实现业务逻辑和用户界面的分离。下面是关于 Spring MVC 的工作原理:
(1)客户端请求处理流程:
客户端发送请求: 客户端发送 HTTP 请求到服务器端。
-
前端控制器(DispatcherServlet)接收请求: Spring MVC
应用程序的所有请求都会先经过前端控制器(DispatcherServlet),它是 Spring MVC 的核心组件。 -
HandlerMapping 寻找处理器: 前端控制器通过 HandlerMapping 将请求映射到相应的处理器(Controller)。
-
处理器处理请求: 处理器(Controller)处理请求,执行业务逻辑,并返回一个逻辑视图名称。
-
ModelAndView 封装模型和视图: 处理器将处理结果封装到 ModelAndView 对象中,其中包括数据模型和视图的名称。
-
ViewResolver 解析视图: 前端控制器通过 ViewResolver 解析视图的逻辑名称,找到对应的视图。
-
视图渲染: 视图将数据模型渲染为最终的 HTML 内容,并将其返回给客户端。
7.Spring MVC的核心组件
DispatcherServlet(前端控制器): 负责接收客户端的请求并委派给相应的处理器进行处理。
HandlerMapping(处理器映射器): 将请求映射到相应的处理器(Controller)上。
Controller(处理器): 执行业务逻辑,处理客户端的请求,并返回逻辑视图名称或者 ModelAndView 对象。
ViewResolver(视图解析器): 根据视图的逻辑名称解析出实际的视图对象,如 JSP、Thymeleaf 等。
8.SpringBoot的自动配置原理
自动装配的优势在于简化了应用程序的配置工作,开发者不需要手动编写大量的配置代码,只需引入相应的 Starter,Spring Boot 就会自动配置应用程序的各种组件。这样,开发者可以更专注于业务逻辑的实现,而无需过多地关注框架的配置和细节。
自动装配的大致过程
-
获取到组件(spring-boot-starter-data-redis)META-INF文件夹下的spring.factories文件
-
spring.factories文件中列出需要注入Ioc容器的类
-
将实体类注入到Ioc容器中使用
自动装配原理源码分析:
自动装配原理的大致流程是通过@SpringBootApplication进行实现,这个注解声明在SpringBoot的启动类上。
@SpringBootApplication是一个组合注解,主要由@SpringBootConfiguration,@EnableAutoConfiguration,@ComponentScan组成
(1)其中@SpringBootConfiguration的本质其实是@Configuration,标识该Java类是一个配置类。
(2)@ComoponentScan是用来指定扫描路径的,如果不指定特定的扫描路径的话,扫描的路径是当前修饰类所在的包及其子包。
(3)@EnableAutoConfiguration这个注解是SpringBoot自动装配的关键。它也有两个注解@AutoConfigurationPackage和@Import({AutoConfigurationImportSelector.class}).
@AutoConfigurationPackage:这个注解是 Spring Boot 中的一个特殊注解,用于指示 Spring Boot 自动配置过程中应该扫描的基本包。通常情况下,@AutoConfigurationPackage 会放在主应用程序类上(即包含 @SpringBootApplication 注解的类),它会扫描该类所在的包及其子包下的组件,并将它们纳入到自动配置的范围内。
@EnableAutoConfiguration注解最重要的是AutoConfigurationImportSelector.class,将需要装配的类装配到IoC容器中。AutoConfigurationImportSelector中的selectImports方法是自动装配的核心实现,它主要是读取META-INF/spring.factories文件,经过去重、过滤,返回需要装配的配置类集合
补充:
@AutoConfigurationPakage与@ComponentScan的区别:
@AutoConfigurationPackage会将自动配置需要的组件注入到IOC中。
@AutoConfigurationPakage与@ComponentScan都是将Spring Boot启动类所在的包及其子包里面的组件扫描到IOC容器中,但区别在于@AutoConfigurationPackage还会扫描@Enitity、@Mapper等第三方依赖的注解,@ComponentScan只扫描@Controller/@Service/@Component/@Repository等Spring容器相关的注解。
9.为什么SpringBoot的jar可以直接运行
-
嵌入式Servlet容器:SpringBoot默认使用嵌入式的Servlet容器(如Tomcat、Jetty、Undertow等)。这使得应用程序可以打包成一个可执行的JAR文件,包含了所有的依赖以及一个嵌入式的Servlet容器,而无需外部容器的支持。
-
Spring Boot Maven插件:SpringBoot提供了Maven和Gradle插件,可以将应用程序打包成可执行的JAR文件。这个JAR文件中包含了应用程序的所有依赖以及一个主类,使得它可以被直接运行。
-
自动化配置:SpringBoot采用自动化配置的方式,大大减少了开发者的配置工作。这使得应用程序可以更容易地打包成一个独立的可执行JAR文件,而不需要太多手动配置。
-
内嵌属性文件:SpringBoot支持使用application.properties或application.yml文件来配置应用程序。这些配置文件可以被打包进JAR文件,使得应用程序在不同环境中可以方便地切换配置。
总的来说,Spring Boot通过嵌入式Servlet容器、构建工具插件以及自动化配置等机制,使得应用程序可以方便地打包成一个JAR文件,并通过java -jar命令直接运行。这种方式简化了部署和运维的流程。
具体实现:
1.在Spring Boot项目的jar中会生成一个MANIFEST.MF文件(路径:META-INF\MANIFEST.MF),打开该文件你会看到有一个MainClass的映射,其对应的值是一个类,就是执行‘java -jar’命令后正式执行的类,它指定了启动应用程序的主类
2.Spring Boot的可执行JAR文件通常由JarLauncher类启动。JarLauncher负责创建一个类加载器,加载boot-lib目录下的jar文件。然后,它在一个新线程中启动应用程序的Main方法,实现应用程序的启动。
SpringBoot如何自定义Starter
为什么引入starter依赖可以实现自动配置?
每个 Starter 都会包含一个 META-INF/spring.factories 文件,其中定义了与该 Starter 相关的自动配置类。Spring Boot 在启动时会加载这些 spring.factories 文件,并根据文件中的配置来注册相应的自动配置类。
举个例子,假设你引入了 spring-boot-starter-web Starter,它包含了 Spring Boot Web 应用程序的必要依赖和配置。在该 Starter 的 META-INF/spring.factories 文件中,会定义一些自动配置类,用于配置嵌入式的 Tomcat 服务器、Spring MVC、Web 相关的特性等。
因此,当你引入了 spring-boot-starter-web 依赖后,Spring Boot 就会自动加载并应用与该 Starter 相关的自动配置类,从而自动配置你的应用程序,使得你可以快速启动一个基于 Web 的 Spring Boot 应用程序,而无需手动配置大量的依赖和配置项。
总的来说,引入 Starter 依赖后,Spring Boot 能够根据 Starter 中定义的自动配置类来自动配置应用程序的各种组件,使得开发者可以更专注于业务逻辑的实现,而无需过多关注框架的配置和细节。
实现一个自定义的 Spring Boot Starter 大致可以分为以下几个步骤:
(1)定义 Starter 模块:首先,你需要创建一个 Maven 或 Gradle 项目作为 Starter 模块,并定义它的基本结构。通常,一个 Starter 包括了一组依赖项、自动配置类、配置属性和其他需要的资源文件。
(2)添加依赖:在 Starter 模块的 Maven 或 Gradle 配置文件中,添加所需的依赖项,包括了你要使用的库、框架和其他依赖。
(3)编写自动配置类:编写自动配置类来配置你的 Starter 中的功能。自动配置类通常使用 @Configuration 和 @ConditionalOnClass、@ConditionalOnBean 等条件注解来控制条件化配置。
(4)定义配置属性:定义一些配置属性,允许用户在应用程序的配置文件(properties文件)中进行配置。这些配置属性可以通过 @ConfigurationProperties 注解来绑定到 POJO 类,并在自动配置类中使用。
(5)创建 Spring.factories 文件:在 Starter 模块的 resources/META-INF 目录下创建一个 spring.factories 文件,并在其中指定你的自动配置类。这个文件告诉 Spring Boot 在启动时加载哪些自动配置类。
(6)测试和文档:编写单元测试和集群测试,以确保自定义Starter的功能和配置正确。同时提供详细的文档和示例,以便用户能够正确配置和使用你的Starter
(7)发布到仓库:一旦你完成了 Starter 模块的开发,你可以将其发布到 Maven 中央仓库或者私有仓库中,以便其他项目可以引用。
SpringBoot的启动原理
1.服务构建
2.环境准备
3.容器创建
4.填充容器
refreshContext()这个过程也被称作自动装配,一共有12个步骤(包含bean的生命周期管理)(也就是面试题中常问的自动装配Bean的流程)