SpringBoot面试题

SpringBoot面试题
潘SpringBoot面试题
- 什么是SpringBoot?
- SpringBoot是Spring开源组织下的子项目,是Spring组件一站式解决方案,主要是简化了使用Spring的难度,简省了繁重的配置,
提供了各种启动器,开发者可以快速上手。
- 为什么要使用SpringBoot?
- 快速开发
- 快速整合第三方框架(Maven依赖关系,Maven继承)
- 简化XML的配置
- 内置嵌入HTTP服务器(Tomcat(默认)、Jetty),降低了对环境的要求
- SpringBoot的优点?
- 容易上手,提升开发效率,为Spring开发提供一个更快、更简单的开发框架
- 远离繁琐的配置
- 提供一系列大型项目通用的非业务性功能,例如:内嵌服务器、安全管理、运行数据监控、运行状况检查和外部化配置等
- SpringBoot总结就是使编码变简单、配置变简单、部署变简单、监控变简单等等
- SpringBoot的缺点
- SpringBoot仅适用于全新Spring项目。将一个传统SpringFramework项目转换为SpringBoot应用程序是一个非常困难和耗时的过程
- 集成度较高,使用过程中不太容易了解底层
- SpringBoot与SpringCloud区别
- SpringBoot是快速开发的Spring框架,而SpringCloud是完整的微服务框架,SpringCloud依赖于SpringBoot进行开发。
- Spring 和SpringBoot有何不同?
- SpringBoot本质上是Spring框架的延伸和扩展,它的诞生是为了简化Spring框架初始搭建以及开发过程,使用它可以不再依赖Spring应用程序中的XML配置,为更快、更高效的开发Spring提供更加有力的支持。
- 更快速的构建能力:SpringBoot提供了更多的Starters用于快速构建业务框架,Starters可以理解为启动器,它包含了一系列可以集成到应用里面的依赖包,你可以一站式集成Spring及其他技术,而不需要到处找依赖包
- 起步依赖:在创建SpringBoot时可以直接勾选依赖模块,这样在项目初始化时就会把相关依赖直接添加到项目中,大大缩短了查询并添加依赖的时间
- 内嵌容器支持:SpringBoot内嵌了Tomcat、Jetty、Undertow
- Actuator监控:可以监控应用程序的运行状况,或者内存、线程池、Http请求统计等
- SpringBootApplication引入了哪3个重要注解?
- 核心注解是@SpringBootApplication,它主要由@SpringBootConfiguration,@EnableAutoConfiguration和@ComponentScan这三个构成:
@SpringBootConfiguration 里面就只有一个 @Configuration 主要注解,也就是把该类变成一个配置类所以@SpringBootConfiguration 就相当于 @Configuration
@EnableAutoConfiguration 是由 @AutoConfigurationPackage 和@Import(EnableAutoConfigurationImportSelector.class) 这两个组成的 @AutoConfigurationPackage 是自动配置包,包括了一个 @Import 注解,给容器导入了自动配置包的注册器,AutoConfigurationPackages.Registrar.class:将主启动类的所在包及包下面所有子包里面的所有组件扫描到 Spring 容器
@ComponentScan:扫描包,该注解默认会扫描该类所在的包下所有的配置类
- SpringBoot的配置文件由哪几种格式?它们有什么区别?
主要有.properties 和 .yml,它们的区别主要是写的格式不同:.properties: user.name = jason .yml: user: name: javastack .yml 格式不支持 @PropertySource 注解导入配置
- SpringBoot需要独立的容器运行吗?
- 不需要,因为已经内置了 Tomcat/ Jetty 等容器
- 你如何理解 Spring Boot 中的 Starters
- 个人理解 Spring Boot 就是由各种 Starter 组合起来的,我们自己也可以开发Starter。
- 当一个项目变得相当复杂,管理依赖会成为一个噩梦,因为当中涉及太多 artifacts 了。
- 这时候 SpringBoot starter 就派上用处了。其他所需的依赖以一致的方式注入并且被管理。
- 所有的 starter 都归于 org.springframework.boot 组中,并且它们都以由 spring-boot-starter- 开头取名。这种命名方式使得我们更容易找到 starter 依赖,特别是当我们使用那些支持通过名字查找依赖的 IDE 当中。
- SpringBoot 提供了非常多的 starter ,其中最常用的是:
- spring-boot-starter:核心 starter,包括自动化配置支持,日志以及 YAML
- spring-boot-starter-aop:Spring AOP 和 AspectJ 相关的切面编程 starter
- spring-boot-starter-data-jpa:使用 Hibernate Spring Data JPA 的 starter
- spring-boot-starter-jdbc:使用 HikariCP 连接池 JDBC 的 starter
- spring-boot-starter-security:使用 Spring Security 的 starter
- spring-boot-starter-test:SpringBoot 测试相关的 starter
- spring-boot-starter-web:构建 restful、springMVC 的 web应用程序的 starter
- Spring Boot 可以兼容老 Spring 项目吗,如何做?
- 使用 @ImportResource 注解导入老 Spring 项目配置文件
- Spring Boot 中读取配置的方式有哪些?
- 注入Environment对象:通过Environment 的 getProperty() 方法读取指定配置 Key 的内容
- 使用@Value注解,实现单个配置的注入
- 使用@ConfigurationProperties注解,实现一组配置的注入
- SpringBoot 实现热部署有哪几种方式? 热部署就是可以不用重新运行SpringBoot项目可以实现操作后台代码自动更新到以运行的项目中 主要有两种方式:
- SpringLoaded
- Spring-boot-devtools
- Spring Boot 是否可以使用 XML 配置 ?
- Spring Boot 推荐使用 Java 配置而非 XML 配置,但是 Spring Boot 中也可以使用 XML 配置,通过@ImportResource 注解可以引入一个 XML 配置
- 如何实现 Spring Boot 应用程序的安全性?
- 为了实现Spring Boot的安全性,我们使用 spring-boot-starter-security依赖项,并且必须添加安全配置。它只需要很少的代码。配置类将必须扩展WebSecurityConfigurerAdapter并覆盖其方法
- 运行 Spring Boot 有哪几种方式?
- 打包用命令或者放到容器中运行
- 用 Maven/ Gradle 插件运行
- 直接执行 main 方法运行
- 开启 Spring Boot 特性有哪几种方式
- 继承spring-boot-starter-parent项目
org.springframework.boot spring-boot-starter-parent 2.6.2 - 导入spring-boot-dependencies项目依赖
org.springframework.boot spring-boot-dependencies 2.6.2
- Spring Boot 支持哪些日志框架?推荐和默认的日志框架是哪一个?
- Spring Boot 支持 Logging、Log4j2、Lockback 做为日志框架,若是你使用 Starters 启动器,Spring Boot 将使用 Logback 做为默认日志框架
- Spring Initializr 是创建 Spring Boot 的唯一方法?
- Spring Initiatlizr 让创建 Spring Boot 项目变的很容易,但是,也可以通过设置一个 maven 项目并添加正确的依赖项来开始一个项目
- 创建方式有两种:
- 第一种::start.spring.io 方式创建
- 第二种:在项目的标题为 “Basic Web Application” 处进行手动设置
- Spring Boot 内嵌了 Tomcat ,那什么是嵌入式服务器
- 我们在虚拟机上面部署应用程序需要几个步骤:
- 安装 Java
- 安装 Web 或者是应用程序的服务器(Tomat/Wbesphere/Weblogic 等等)
- 部署应用程序 jar 或者 war 包
- 如果把这些步骤简化了,应该怎么做呢?
- 让我们来思考如何使服务器成为应用程序的一部分?
- 我们只需要一个安装了 Java 的虚拟机,就可以直接在上面部署应用程序了
- 这就是嵌入式服务器的起源
- 前后端分离,如何维护接口文档
前后端分离开发日益流行,大部分情况下,我们都是通过 Spring Boot 做前后端分离开发,前后端分离一定会有接口文档,不然会前后端会深深陷入到扯皮中。一个比较笨的方法就是使用 word 或者 md 来维护接口文档,但是效率太低,接口一变,所有人手上的文档都得变。在 Spring Boot 中,这个问题常见的解决方案是 Swagger ,使用 Swagger 我们可以快速生成一个接口文档网站,接口一旦发生变化,文档就会自动更新,所有开发工程师访问这一个在线网站就可以获取到最新的接口文档,非常方便 - Spring Boot中如何解决跨域问题?
跨域可以在前端通过JSONP来解决,但是JSONP只可以发送GET请求,无法发送其他类型的请求,在RESTful风格的应用中,就显得非常鸡肋,因此推荐在后端通过(CORS,Cross-origin resource sharing)来解决跨域问题。这种解决方案并非Spring Boot特有的,在传统的SSM框架中,就可以通过CORS来解决跨域问题,只不过之前我们是在XML文件中配置CORS,现在可以通过实现WebMvcConfigurer接口然后重写addCorsMappings方法解决跨域问题
@Configuration
public class CorsConfig implements WebMvcConfigurer {@Override
public void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**") .allowedOrigins("*") .allowCredentials(true) .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") .maxAge(3600);
}
}
项目中前后端分离部署,所以需要解决跨域的问题。
我们使用cookie存放用户登录的信息,在spring拦截器进行权限控制,当权限不符合时,直接返回给用户固定的json结果。
当用户登录以后,正常使用;当用户退出登录状态时或者token过期时,由于拦截器和跨域的顺序有问题,出现了跨域的现象。
我们知道一个http请求,先走filter,到达servlet后才进行拦截器的处理,如果我们把cors放在filter里,就可以优先于权限拦截器执行
@Configuration
public class CorsConfig {@Bean public CorsFilter corsFilter() { CorsConfiguration corsConfiguration = new CorsConfiguration(); corsConfiguration.addAllowedOrigin("*"); corsConfiguration.addAllowedHeader("*"); corsConfiguration.addAllowedMethod("*"); corsConfiguration.setAllowCredentials(true); UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource(); urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration); return new CorsFilter(urlBasedCorsConfigurationSource); }
}
- Spring Boot 约定优于配置的体现是什么?
- Maven的目录结构:
- 默认有 resources 文件夹存放配置文件
- 默认打包方式为jar
- 默认的配置文件:application.properties 或 application.yml 文件
- 默认通过 spring.profiles.active 属性来决定运行环境时的配置文件
- EnableAutoConfiguration 默认对于依赖的 starter 进行自动装载
- spring-boot-start-web 中默认包含 spring-mvc 相关依赖以及内置的 tomcat 容器,使得构建一个 web 应用更加简单
- 内置容器的启动流程是什么
- 启动一个 Spring Boot项目,首先运行 Application 启动类的 main 方法,main 方法中调用了 SpringApplication.run 方法,run 方法中又调用了最核心的 refreshContext 方法,这里面又调用了我们最熟悉了 spring 容器启动模板方法refresh 方法,默认 Spring Boot 会启动 Tomcat,在 refresh 中的 onRefresh() 中执行;
onRefresh 调用了 createWebServer() 方法,通过 TomcatServletWebServerFactory 开始创建 Tomcat 实例;
最后在 refresh 方法中的 finishRefresh() 中调用 Tomcat 实例的 start 逻辑,并将应用上下文发布的 webServer 中,至此完成 Tomcat 的启动
- 你如何理解 Spring Boot 配置加载顺序?
- Spring Boot 配置加载顺序优先级是:propertiese文件、YAML文件、系统环境变量、命令行参数。
- application.properties 和 bootstrap.properties 有何区别 ?
- bootstrap 比 applicaton 优先加载,配置在应用程序上下文的引导阶段生效, 而且 boostrap 里面的属性不能被覆盖;
application 用于 Spring Boot 项目的自动化配置
- Spring Boot 中的监视器是什么?
- Spring boot actuator 是 spring 启动框架中的重要功能之一,Spring boot 监视器可以访问生产环境中正在运行的应用程序的当前状态。监视器模块公开了一组可直接作为 HTTP URL 访问的 REST 端点来检查状态
- 如何使用 Spring Boot 实现异常处理?
- Spring 通过使用 @ControllerAdvice 注解处理异常,实现一个ControllerAdvice 类来处理控制器类抛出的所有异常
- YAML在springboot中的作用
- 使得 Spring Boot 配置文件更加有层次感,结构也比较清晰,不容易混淆,目前也是人类可读的数据序列化语言
- 如何使用 SpringBoot 实现分页和排序?
1、pom<dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>${pagehelper-version}</version> </dependency>
- 配置文件
pagehelper:
helper-dialect: mysql
reasonable: true
support-methods-arguments: true
params: count=countSql - service层
//用插件进行分页 PageHelper.startPage(pageNum, pageSize); return articleMapper.findByPage();
- controller层
通过service调用方法后获取数据。
// 需要把Page包装成PageInfo对象才能序列化。该插件也默认实现了一个PageInfoPageInfo<Article> pageInfo = new PageInfo<>(articles);
- Spring Boot 中如何实现定时任务 ?
- 在 Spring Boot 中使用定时任务主要有两种不同的方式,一个就是使用 Spring 中的 @Scheduled 注解,另一个则是使用第三方框架 Quartz。
- 使用 Spring 中的 @Scheduled 的方式主要通过 @Scheduled 注解来实现。
- 使用 Quartz ,则按照 Quartz 的方式,定义 Job 和 Trigger 即可
- 你使用了哪些 starter maven 依赖项?
- spring-boot-starter-web 嵌入tomcat和web开发需要servlet与jsp支持
- spring-boot-starter-data-jpa 数据库支持
- spring-boot-starter-data-Redis Redis数据库支持
- spring-boot-starter-data-solr solr支持
- mybatis-spring-boot-starter 第三方的mybatis集成starter
自己开发过的都可以说出来
- Spring Boot 自动配置的原理
- SpringBoot启动的时候加载主配置类,开启了自动配置功能@EnableAutoConfiguration
- 查看@EnableAutoConfiguration,其作用是利用AutoConfigurationImportSelector给容器中导入一些组件
- 查看AutoConfigurationImportSelector,其中public String[] selectImports(AnnotationMetadata annotationMetadata)方法内 最终调用getCandidateConfigurations()方法
- 查看 getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes),获取候选的配置,这个是扫描所有jar包类路径下”META-INF/spring.factories”
- 然后把扫描到的这些文件包装成Properties对象
- 从properties中获取到EnableAutoConfiguration.class类名对应的值,然后把他们添加在容器中
- 整个过程就是将类路径下 “META-INF/spring.factories” 里面配置的所有 EnableAutoConfiguration 的值加入到容器中
- SpringBoot核心配置文件是什么?
- bootstrap.properties 和 application.properties
- 如何监视所有 SpringBoot 微服务?
创建SpringBoot Web项目,引入下列pom坐标de.codecentric spring-boot-admin-starter-server 2.5.1
在你的启动类上添加:@EnableAdminServer注解
在你需要监控的服务中加入下列pom坐标
在需监控服务中配置:
spring.boot.admin.client.url=http://localhost:8080 (监控服务url)
management.endpoints.web.exposure.include=*
- Spring Boot 打成的 jar 和普通的 jar 有什么区别
- Spring Boot 打成jar包可以直接通过 java -jar *.jar 启动项目,但是不能够像普通 jar 包一样被其他项目引用。
- 普通 jar 解压后就是包名,可以直接引用内部的类,而 Spring Boot 解压后 BOOT/classes 目录下才是真正的代码,因此不能被直接引用,如果需要被引用可以配置 pom,将 SpringBoot 打包成两个 jar 包,一个可执行,一个可引用