SpringBoot面试题
SpringBoot基础
1、什么是SpringBoot?
1 通过自动配置方式简化Spring应用的开发,弱化配置,遵循约定大于配置的原则,使开发者专注于业务开发而无需过多考虑配置相关操作,通过启动类的main方法一键启动应用。
2、SpringBoot有哪些优点?
1 1、独立运行。 2 内嵌了servlet,tomat等,不需要打成war包部署到容器中,只需要将SpringBoot项目打成jar包就能独立运行。 3 4 2、简化配置 5 启动器自动依赖其他组件,简少了 maven 的配置。各种常用组件及配置已经默认配置完成,无需过多干预。 6 7 3、避免大量的Maven导入和各种版本冲突 8 9 4、应用监控 10 Spring Boot 提供一系列端点可以监控服务及应用。
3、SpringBoot的核心注解是什么?由那些注解组成?
1 核心注解为:@SpringBootApplication 2 3 该注解主要由三个注解组成: 4 @SpringBootConfiguration():代表当前是一个配置类 5 @EnableAutoConfiguration(): 启动自动配置 6 @ComponentScan():指定扫描哪些Spring注解
4、SpringBoot自动配置原理是什么?
1、SpringBoot启动的时候加载主配置类,开启了自动配置功能@EnableAutoConfiguration。 2、查看@EnableAutoConfiguration,其作用是利用AutoConfigurationImportSelector给容器中导入一些组件。 3、查看AutoConfigurationImportSelector,其中public String[] selectImports(AnnotationMetadata annotationMetadata)方法内 最终调用getCandidateConfigurations()方法 4、查看 getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes),获取候选的配置,这个是扫描所有jar包类路径下"META-INF/spring.factories" 5、然后把扫描到的这些文件包装成Properties对象。 6、从properties中获取到EnableAutoConfiguration.class类名对应的值,然后把他们添加在容器中。 简而言之,整个过程就是将类路径下"META-INF/spring.factories"里面配置的所有EnableAutoConfiguration的值加入到容器中。
5、你如何理解SpringBoot配置加载顺序?
6、运行 SpringBoot 有哪几种方式?
1 1、直接执行 main 方法运行 2 2、打包用Java命令行执行 3 3、用 Maven/ Gradle 插件运行
7、SpringBoot 需要独立的容器运行吗?
不需要,SpringBoot内置tomcat/jetty等容器
8、开启SpringBoot 特性有哪几种方式?
1 继承spring-boot-starter-parent项目 2 导入spring-boot-dependencies项目依赖
9、SpringBoot、Spring MVC和Spring有什么区别?
Spring:主要用来创建IOC容器,依赖注入,实现程序间的松耦合
SpringMVC: 主要是用来做WEB开发,通过各种组件的协调配合,简化Web应用的开发
SpringBoot: SpringBoot更像是一个管家,当使用到对应功能时,只需要导入指定应用启动器,SpringBoot就能够在底层默认其配置,大大简化了开发所需的繁杂配置
10、SpringBoot启动时都做了什么?
Springboot的启动,主要创建了配置环境 (environment)、事件监听 (listeners)、应用上下文 (applicationContext),并基于以上条件,在容器中开始实例化我们需要的Bean,至此,通过SpringBoot启动的程序
已经构造完成。
SpringBoot配置
什么是YAML?
1 YAML 是一种人类可读的数据序列化语言。它通常用于配置文件。与属性文件相比,如果我们想要在配置文件中添加复杂的属性,YAML 文件就更加结构化,而且更少混淆。可以看出 YAML 具有分层配置数据。
YAML 配置的优势在哪里 ?
1 配置有序,在一些特殊的场景下,配置有序很关键 2 支持数组,数组中的元素可以是基本数据类型也可以是对象 3 简洁
相比 properties 配置文件,YAML 还有一个缺点,就是不支持 @PropertySource 注解导入自定义的 YAML 配置。
SpringBoot 是否可以使用 XML 配置 ?
1 SpringBoot推荐使用 Java 配置而非 XML 配置,但是 SpringBoot 中也可以使用 XML 配置,通过 @ImportResource 注解可以引入一个 XML 配置。
SpringBoot核心配置文件是什么?
bootstrap.properties和application.properties
bootstrap.properties和application.properties 有何区别 ?
1 bootstrap(.yml 或者 .properties):boostrap 由父 ApplicationContext 加载的,比applicaton优先加载,配置在应用程序上下文的引导阶段生效。一般来说我们在 SpringCloud Config
或者Nacos中会用到它。且boostrap里面的属性不能被覆盖;
2 application (.yml或者.properties):由ApplicatonContext 加载,用于 SpringBoot项目的自动化配置。
什么是Spring Profiles?
为了适应多环境配置,可以在项目中配置多个application配置文件,根据应用场景不同,通过application-*中的*来决定启用某个配置文件。
SpringBoot安全性
如何实现SpringBoot应用程序的安全性?
比较一下Spring Security 和Shiro各自的优缺点 ?
SpringBoot中如何解决跨域问题 ?
1、基于WebMvcConfigurerAdapter配置加入Cors的跨域
跨域可以在前端通过 JSONP 来解决,但是 JSONP 只可以发送 GET 请求,无法发送其他类型的请求,在 RESTful 风格的应用中,就显得非常鸡肋,因此我们推荐在后端通过(CORS,Cross-origin resource sharing)
来解决跨域问题。这种解决方案并非 Spring Boot 特有的,在传统的 SSM 框架中,就可以通过 CORS 来解决跨域问题,只不过之前我们是在 XML 文件中配置 CORS ,现在可以通过实现WebMvcConfigurer接口然后重写
addCorsMappings方法解决跨域问题
1 @Configuration 2 public class CorsConfig implements WebMvcConfigurer { 3 4 @Override 5 public void addCorsMappings(CorsRegistry registry) { 6 registry.addMapping("/**") 7 .allowedOrigins("*") 8 .allowCredentials(true) 9 .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") 10 .maxAge(3600); 11 } 12 13 }
2、创建一个filter解决跨域
项目中前后端分离部署,所以需要解决跨域的问题。 我们使用cookie存放用户登录的信息,在spring拦截器进行权限控制,当权限不符合时,直接返回给用户固定的json结果。 当用户登录以后,正常使用;当用户退出登录
状态时或者token过期时,由于拦截器和跨域的顺序有问题,出现了跨域的现象。 我们知道一个http请求,先走filter,到达servlet后才进行拦截器的处理,如果我们把cors放在filter里,就可以优先于权限拦截器执行。
1 @Configuration 2 public class CorsConfig { 3 4 @Bean 5 public CorsFilter corsFilter() { 6 CorsConfiguration corsConfiguration = new CorsConfiguration(); 7 corsConfiguration.addAllowedOrigin("*"); 8 corsConfiguration.addAllowedHeader("*"); 9 corsConfiguration.addAllowedMethod("*"); 10 corsConfiguration.setAllowCredentials(true); 11 12 UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource(); 13 urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration); 14 return new CorsFilter(urlBasedCorsConfigurationSource); 15 } 16 17 }
3、controller配置CORS
controller方法的CORS配置,您可以向@RequestMapping注解处理程序方法添加一个@CrossOrigin注解,以便启用CORS(默认情况下,@CrossOrigin允许在@RequestMapping注解中指定的所有源和HTTP方法)
1 @RestController 2 @RequestMapping("/account") 3 public class AccountController { 4 5 @CrossOrigin 6 @GetMapping("/{id}") 7 public Account retrieve(@PathVariable Long id) { 8 // ... 9 } 10 11 @DeleteMapping("/{id}") 12 public void remove(@PathVariable Long id) { 13 // ... 14 } 15 }
@CrossOrigin 表示所有的URL均可访问此资源 @CrossOrigin(origins = “http://127.0.0.1:8080”)
//表示只允许这一个url可以跨域访问这个controller 代码说明:@CrossOrigin这个注解用起来很方便,这个可以用在方法上,也可以用在类上。如果你不设置他的value属性,或者是origins属性,
就默认是可以允许所有的URL/域访问。 -value属性可以设置多个URL。 -origins属性也可以设置多个URL。 -maxAge属性指定了准备响应前的缓存持续的最大时间。就是探测请求的有效期。 -allowCredentials属性表示用户是否可以发送、处理 cookie。默认为false -allowedHeaders 属性表示允许的请求头部有哪些。 -methods 属性表示允许请求的方法,默认get,post,head。
@CrossOrigin不起作用的原因
1 1、是springMVC的版本要在4.2或以上版本才支持@CrossOrigin 2 3 2、非@CrossOrigin没有解决跨域请求问题,而是不正确的请求导致无法得到预期的响应,导致浏览器端提示跨域问题。 4 5 3、在Controller注解上方添加@CrossOrigin注解后,仍然出现跨域问题,解决方案之一就是: 7 在@RequestMapping注解中没有指定Get、Post方式,具体指定后,问题解决。
什么是 CSRF 攻击?
1 CSRF 代表跨站请求伪造。这是一种攻击,迫使最终用户在当前通过身份验证的Web 应用程序上执行不需要的操作。CSRF 攻击专门针对状态改变请求,而不是数据窃取,因为攻击者无法查看对伪造请求的响应。 2 3 简单来说就是:攻击者盗取合法用户登录信息,通过盗取账户进行登录,然后以合法用户的身份发送恶意请求,但是请求对于服务器来说是合法的。
SpringBoot 中的监视器是什么?
1 SpringBoot Actuator是SpringBoot一项重要功能,其可以帮助我们查看应用的运行状态,对运行时指标进行检查和监控,监视器提供了一组可以直接作为httpurl访问的rest端点来访问查看指定功能状态。
如何在SpringBoot中禁用Actuator端点安全性?
management.security.enabled=false来禁用安全性
如何监视所有SpringBoot微服务?
1 创建SpringBoot Web项目,引入下列pom坐标 2 <dependency> 3 <groupId>de.codecentric</groupId> 4 <artifactId>spring-boot-admin-starter-server</artifactId> 5 <version>2.5.1</version> 6 </dependency> 7 <dependency> 8 9 在你的启动类上添加:@EnableAdminServer注解 10 =================================== 11 12 在你需要监控的服务中加入下列pom坐标 13 <dependency> 14 <groupId>de.codecentric</groupId> 15 <artifactId>spring-boot-admin-starter-client</artifactId> 16 <version>2.5.1</version> 17 </dependency> 18 19 在需监控服务中配置: 20 spring.boot.admin.client.url=http://localhost:8080 (监控服务url) 21 management.endpoints.web.exposure.include=*
SpringBoot进阶
什么是 WebSockets?
什么是 Spring Data?
1 Spring Data 是 Spring 的一个子项目。用于简化数据库访问,支持NoSQL 和 关系数据存储。其主要目标是使数据库的访问变得方便快捷。
什么是 Spring Batch?
Spring Boot Batch 提供可重用的函数,这些函数在处理大量记录时非常重要,包括日志/跟踪,事务管理,作业处理统计信息,作业重新启动,跳过和资源管理。它还提供了更先进的技术服务和功能,通过优化和分区技术,
可以实现极高批量和高性能批处理作业。简单以及复杂的大批量批处理作业可以高度可扩展的方式利用框架处理重要大量的信息。
什么是 FreeMarker 模板?
FreeMarker 是一个基于 Java 的模板引擎,最初专注于使用 MVC 软件架构进行动态网页生成。使用 Freemarker 的主要优点是表示层和业务层的完全分离。程序员可以处理应用程序代码,而设计人员可以处理 html页面
设计。最后使用freemarker 可以将这些结合起来,给出最终的输出页面。
如何集成 SpringBoot和ActiveMQ?
Swagger用过麽?他用来做什么?
前后端分离,如何维护接口文档 ?
前后端分离开发日益流行,大部分情况下,我们都是通过 Spring Boot 做前后端分离开发,前后端分离一定会有接口文档,不然会前后端会深深陷入到扯皮中。
一个比较笨的方法就是使用 word 或者 md 来维护接口文档,但是效率太低,接口一变,所有人手上的文档都得变。
在 Spring Boot 中,这个问题常见的解决方案是 Swagger ,使用 Swagger 我们可以快速生成一个接口文档网站,接口一旦发生变化,文档就会自动更新,
所有开发工程师访问这一个在线网站就可以获取到最新的接口文档,非常方便。
SpringBoot项目如何热部署?
1、使用 DEV 工具来实现。DevTools工具可以刷新SpringBoot的更改而无需重启Tomcat服务器。
2、Spring Loaded
SpringBoot 中的starter到底是什么 ?
首先,这个 Starter 并非什么新的技术点,基本上还是基于 Spring 已有功能来实现的。首先它提供了一个自动化配置类,一般命名为 XXXAutoConfiguration ,在这个配置类中通过条件注解来决定一个配置是否生效
(条件注解就是 Spring 中原本就有的),然后它还会提供一系列的默认配置,也允许开发者根据实际情况自定义相关配置,然后通过类型安全的属性注入将这些配置属性注入进来,新注入的属性会代替掉默认属性。
正因为如此,很多第三方框架,我们只需要引入依赖就可以直接使用了。当然,开发者也可以自定义 Starter
spring-boot-starter-parent 有什么用?
1 定义了 Java 编译版本为 1.8 。 2 使用 UTF-8 格式编码。 3 继承自 spring-boot-dependencies,这个里边定义了依赖的版本,也正是因为继承了这个依赖,所以我们在写依赖时才不需要写版本号。 4 执行打包操作的配置。 5 自动化的资源过滤。 6 自动化的插件配置。 7 针对 application.properties 和 application.yml 的资源过滤,包括通过 profile 定义的不同环境的配置文件,例如 application-dev.properties 和 application-dev.yml。
SpringBoot 打成的jar和普通的jar有什么区别 ?
SpringBoot打成jar包可以直接通过java -jar *.jar启动项目,但是不能够像普通jar包一样被其他项目引用。
普通jar解压后就是包名,可以直接引用内部的类,而SpringBoot解压后BOOT/classes目录下才是真正的代码,因此不能被直接引用。
如果需要被引用可以配置pom,将SpringBoot打包成两个jar包,一个可执行,一个可引用。
如何使用SpringBoot实现异常处理?
1、直接在error目录下防止错误页面 2、@ControllerAdvice+@ExceptionHandler处理全局异常;底层是 ExceptionHandlerExceptionResolver 支持 3、@ResponseStatus+自定义异常 ;底层是 ResponseStatusExceptionResolver ,把responsestatus注解的信息底层调用 response.sendError(statusCode, resolvedReason);tomcat发送的/error
如何使用SpringBoot实现分页和排序?
1 1、pom 2 <!--分页插件--> 3 <dependency> 4 <groupId>com.github.pagehelper</groupId> 5 <artifactId>pagehelper-spring-boot-starter</artifactId> 6 <version>${pagehelper-version}</version> 7 </dependency> 8 9 2、配置文件 10 pagehelper: 11 helper-dialect: mysql 12 reasonable: true 13 support-methods-arguments: true 14 params: count=countSql 15 16 3、service层 17 //用插件进行分页 18 PageHelper.startPage(pageNum, pageSize); 19 return articleMapper.findByPage(); 20 21 4、controller层 22 通过service调用方法后获取数据。 23 // 需要把Page包装成PageInfo对象才能序列化。该插件也默认实现了一个PageInfo 24 PageInfo<Article> pageInfo = new PageInfo<>(articles);
微服务中如何实现 session 共享?
在微服务中,一个完整的项目被拆分成多个不相同的独立的服务,各个服务独立部署在不同的服务器上,各自的 session 被从物理空间上隔离开了,但是经常,我们需要在不同微服务之间共享 session ,
常见的方案就是 Spring Session + Redis 来实现 session 共享。将所有微服务的 session 统一保存在 Redis 上,当各个微服务对 session 有相关的读写操作时,都去操作 Redis 上的 session 。
这样就实现了 session 共享,Spring Session 基于 Spring 中的代理过滤器实现,使得 session 的同步操作对开发人员而言是透明的,非常简便。
SpringBoot 中如何实现定时任务?
定时任务也是一个常见的需求,SpringBoot 中对于定时任务的支持主要还是来自 Spring 框架。
在 SpringBoot 中使用定时任务主要有两种不同的方式,一个就是使用 Spring 中的 @Scheduled 注解,另一个则是使用第三方框架 Quartz。
-使用Spring中的 @Scheduled的方式主要通过@Scheduled注解来实现。
-使用Quartz,则按照Quartz的方式,定义Job和Trigger即可。
提高篇
如何自定义starter?
1、创建项目,创建两个模块分别为spring-boot-starter-*,spring-boot-starter-*-autoconfiguration 2、spring-boot-starter-* pom引入spring-boot-starter-*-autoconfiguration 3、spring-boot-starter-*-autoconfiguration创建功能方法,创建*properties类,创建一个配置类将功能方法类添加到spring容器,在resouces下创建META-INF/spring.factories 配置 org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration 4、打包安装这两个模块到本地maven仓库,即可在其他项目引入spring-boot-starter-* 注入功能类进行方法调用
额外补充
如何在 Spring Boot 启动的时候运行一些特定的代码?
可以实现接口 ApplicationRunner 或者 CommandLineRunner,这两个接口实现方式一样,它们 都只提供了一个 run 方法
SpringBoot事务的使用
SpringBoot的事物很简单,首先使用注解EnableTransactionManagement开启事物之后,然后在 Service方法上添加注解Transactional便可。
Async异步调用方法
在SpringBoot中使用异步调用是很简单的,只需要在方法上使用@Async注解即可实现方法的异步 调用。 注意:需要在启动类加入@EnableAsync使异步调用@Async注解生效。
SpringBoot支持什么前端模板
thymeleaf,freemarker,jsp,官方不推荐JSP会有限制
Spring Boot 有哪几种读取配置的方式?
Spring Boot 可以通过 @PropertySource,@Value,@Environment, @ConfigurationPropertie注 解来绑定变量
SpringBoot的自动配置原理是什么
1、主要是Spring Boot的启动类上的核心注解SpringBootApplication注解主配置类,有了这个主配置 类启动时就会为SpringBoot开启一个@EnableAutoConfiguration注解自动配置功能。 2、有了这个EnableAutoConfiguration的话就会: 1. 从配置文件META_INF/Spring.factories加载可能用到的自动配置类 2. 去重,并将exclude和excludeName属性携带的类排除 3. 过滤,将满足条件(@Conditional)的自动配置类返回
SpringBoot多数据源拆分的思路
先在properties配置文件中配置两个数据源,创建分包mapper,使用@ConfigurationProperties
读取properties中的配置,使用@MapperScan注册到对应的mapper包中
SpringBoot多数据源事务如何管理
第一种方式是在service层的@TransactionManager中使用transactionManager指定 DataSourceConfig中配置的事务 第二种是使用jta-atomikos实现分布式事务管理
保护 Spring Boot 应用有哪些方法?
在生产中使用HTTPS 使用Snyk检查你的依赖关系 升级到最新版本 启用CSRF保护 使用内容安全策略防止XSS攻击
如何使用 Spring Boot 实现全局异常处理?
Spring 提供了一种使用 ControllerAdvice 处理异常的非常有用的方法。 我们通过实现一个 ControlerAdvice 类,来处理控制器类抛出的所有异常。
SpringBoot性能如何优化
- 如果项目比较大,类比较多,不使用@SpringBootApplication,采用@Compoment指定扫包范围
- 在项目启动时设置JVM初始内存和最大内存相同
- 将springboot内置服务器由tomcat设置为undertow
如何重新加载 Spring Boot 上的更改,而无需重新启动服务器?Spring Boot项目如何热部署?
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>