栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringBoot面试重点

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringBoot面试重点

一、SpringBoot概述 Spring Boot 的核心注解是哪个?它主要由哪几个注解组成的?

启动类上面的注解是@SpringBootApplication,它也是 Spring Boot 的核心注解,主要组合包含了以下 3 个注解:

(1)@SpringBootConfiguration:组合了 @Configuration 注解,实现配置文件的功能。

(2)@EnableAutoConfiguration:打开自动配置的功能,也可以关闭某个自动配置的选项,如关闭数据源自动配置功能。

(3)@ComponentScan:Spring组件扫描。

Spring Boot 核心配置文件bootstrap.properties 和 application.properties 有何区别 ?

bootstrap (. yml 或者 . properties):boostrap 由父 ApplicationContext 加载的,比 applicaton 优先加载,配置在应用程序上下文的引导阶段生效。一般来说我们在 Spring Cloud Config 或者 Nacos 中会用到它。且 boostrap 里面的属性不能被覆盖;
application (. yml 或者 . properties): 由ApplicatonContext 加载,用于 spring boot 项目的自动化配置。

Spring Boot 配置加载顺序?

在 Spring Boot 里面,可以主要使用以下几种方式来加载配置。

(1)properties文件;

(2)YAML文件;

(3)系统环境变量;

(4)命令行参数;

Spring Boot 是否可以使用 XML 配置 ?

Spring Boot 推荐使用 Java 配置而非 XML 配置,但是 Spring Boot 中也可以使用 XML 配置,通过 @importResource 注解可以引入一个 XML 配置。

SpringBoot自动装配原理

(1)通过@import(AutoConfigurationimportSelector)实现配置类的导入;

(2)AutoConfigurationimportSelector类实现了importSelector接口,重写了方法selectimport,用于实现选择性批量配置类的装配;

(3)通过Spring提供的SpringFactoriesLoader机制,扫描classpath路径下的meta-INF/spring.factories,读取需要实现自动装配的配置类;

(4)通过条件筛选的方式,把不符合条件的配置类移除,最终完成自动装配。

Spring Boot 中的 starter 到底是什么 ?

首先,这个 Starter 并非什么新的技术点,基本上还是基于 Spring 已有功能来实现的。首先它提供了一个自动化配置类,一般命名为 XXXAutoConfiguration ,在这个配置类中通过条件注解来决定一个配置是否生效(条件注解就是 Spring 中原本就有的),然后它还会提供一系列的默认配置,也允许开发者根据实际情况自定义相关配置,然后通过类型安全的属性注入将这些配置属性注入进来,新注入的属性会代替掉默认属性。正因为如此,很多第三方框架,我们只需要引入依赖就可以直接使用了。当然,开发者也可以自定义 Starter

spring-boot-starter-parent 有什么用 ?

我们都知道,新创建一个 Spring Boot 项目,默认都是有 parent 的,这个 parent 就是 spring-boot-starter-parent ,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。
Spring Boot 打成的 jar 和普通的 jar 有什么区别 ?

Spring Boot 项目最终打包成的 jar 是可执行 jar ,这种 jar 可以直接通过 java -jar xxx.jar 命令来运行,这种 jar 不可以作为普通的 jar 被其他项目依赖,即使依赖了也无法使用其中的类。

Spring Boot 的 jar 无法被其他项目依赖,主要还是他和普通 jar 的结构不同。普通的 jar 包,解压后直接就是包名,包里就是我们的代码,而 Spring Boot 打包成的可执行 jar 解压后,在 BOOT-INFclasses 目录下才是我们的代码,因此无法被直接引用。如果非要引用,可以在 pom.xml 文件中增加配置,将 Spring Boot 项目打包成两个 jar ,一个可执行,一个可引用。

运行 Spring Boot 有哪几种方式?

打包用命令或者放到容器中运行
用 Maven/ Gradle 插件运行
直接执行 main 方法运行

Spring Boot 需要独立的容器运行吗?

可以不需要,内置了 Tomcat/ Jetty 等容器。

开启 Spring Boot 特性有哪几种方式?

继承spring-boot-starter-parent项目
导入spring-boot-dependencies项目依赖

如何在自定义端口上运行 Spring Boot 应用程序?

为了在自定义端口上运行 Spring Boot 应用程序,您可以在application.properties 中指定端口。server.port = 8090

SpringBoot中各层的作用

DAO层(Mapper层): 持久层,主要与数据库进行交互,同时提供增删改查操作。

Entity层(domain层):实体层,数据库在项目中的类。

Service层(biz(应用)业务层):(基础)业务层,接收Controller传来的数据,进行业务逻辑的处理。

Controller层:(action层) 控制层,负责处理用户请求,接收和校验数据。

Model(模型):模型包含业务模型和数据模型,数据模型⽤于封装数据,业务模型⽤于处理业务。

View(视图): 通常指的就是我们的 jsp 或者 html。作⽤⼀般就是展示数据的。通常视图是依据模型数据创建的。

总结:在具体的项目中,其流程为:Controller层调用Service层接口的方法,Service层的实现调用Dao层中的方法,其中调用的参数是使用Entity层进行传递的。

二、Spring IoC IoC和DI

IoC(控制反转):把对象的生命周期托管到Spring容器中,反转是指对象的获取方式被反转了。

DI(依赖注入):IoC容器在运行期间,动态地把某种依赖关系注入到组件中。

三、Spring AOP 四、Spring-MyBatis 五、数据库事务 Spring声明式数据库事务

Spring利用其AOP为我们提供了一个数据库事务的约定流程。对于声明式事务,是使用@Transactional进行标注,代表被标注类所有公共非静态的方法都将启用事务功能,@Transactional允许配置的属性有用于配置Spring事务管理器的value和transactionManager,定义事务为只读事务的readOnly,指定异常回滚行为的rollbackFor、rollbackForClassName、noRollbackFor、noRollbackForClassName,传播行为propagation,隔离级别isolation。

事务的隔离级别

未提交读:是最低的隔离级别,允许一个事务读取另外一个事务没有提交的数据。

读写提交:一个事务只能读取另外一个事务已经提交的数据,不能读取未提交的数据。

可重复读:克服了读写提交中出现的不可重复读现象。

串行化:数据库最高隔离级别,要求所有的SQL都会按照顺序执行,能够完全保证数据的一致性。

项目类型脏读不可重复读幻读
未提交读
读写提交×
可重复读××
串行化×××

脏读:事务A、B交替执行,事务A被事务B干扰到了,因为事务A读取到事务B未提交的数据。

不可重复读:在一个事务范围内,两个相同的查询,读取同一条记录,却返回了不同的数据。

幻读:事务A查询一个范围的结果集,另一个并发事务B往这个范围中插入/删除了数据,并静悄悄地提交,然后事务A再次查询相同的范围,两次读取得到的结果集却不一样。

Oracle只能支持读写提交和串行化,默认级别是读写提交。

MySQL能够支持四种,默认级别是可重复读。

事务的传播行为

传播行为是指事务方法之间的调用行为。

Spring事务机制通过Propagation枚举类中定义了7中传播行为:

  1. REQUIRED:需要事务(默认传播行为)。当前存在事务,就沿用当前事务,否则新建一个事务运行子方法。
  2. SUPPORTS:支持事务。如果当前存在事务,就沿用当前事务,否则继续采用无事务的方式运行子方法。
  3. MANDATORY:必须使用事务。如果当前存在事务,就沿用当前事务,否则会抛出异常。
  4. REQUIRES_NEW:无论当前事务是否存在,都会创建新事务运行方法,新事务拥有新的锁和隔离级别等特性。
  5. NOT_SUPPORTED:不支持事务。当前存在事务时,将挂起事务,运行方法。
  6. NEVER:不支持事务。如果当前方法存在事务,则抛出异常,否则继续使用无事务机制运行。
  7. NESTED:当前方法调用子方法时,如果子方法发生异常,回滚子方法执行过的SQL,而不回滚当前方法的事务。
@Transactional自调失效用

Spring数据库事务的实现原理是AOP,而AOP的原理是动态代理,在自调用的过程中,是类自身的调用,而不是代理对象去调用,那么就不会产生AOP,这样Spring就不能把代码植入到约定流程中,继而@Transactional自调失效用。

解决办法:使用代理对象执行插入用户,克服自调用问题。

六、Spring-Redis 七、Spring-MangoDB 八、Spring MVC Spring MVC流程

  • 第一步:发起请求到前端控制器(DispatcherServlet)
  • 第二步:前端控制器请求HandlerMapping查找 Handler (可以根据xml配置、注解进行查找)
  • 第三步:处理器映射器HandlerMapping向前端控制器返回Handler,HandlerMapping会把请求映射为HandlerExecutionChain对象(包含一个Handler处理器(页面控制器)对象,多个HandlerInterceptor拦截器对象),通过这种策略模式,很容易添加新的映射策略
  • 第四步:前端控制器调用处理器适配器去执行Handler
  • 第五步:处理器适配器HandlerAdapter将会根据适配的结果去执行Handler
  • 第六步:Handler执行完成给适配器返回ModelAndView
  • 第七步:处理器适配器向前端控制器返回ModelAndView (ModelAndView是springmvc框架的一个底层对象,包括 Model和view)
  • 第八步:前端控制器请求视图解析器去进行视图解析 (根据逻辑视图名解析成真正的视图(jsp)),通过这种策略很容易更换其他视图技术,只需要更改视图解析器即可
  • 第九步:视图解析器向前端控制器返回View
  • 第十步:前端控制器进行视图渲染 (视图渲染将模型数据(在ModelAndView对象中)填充到request域)
  • 第十一步:前端控制器向用户响应结果
SpringMVC常用注解有哪些 @Controller

 @Controller 用于标记在一个类上,使用它标记的类就是一个SpringMVC Controller 对象。分发处理器将会扫描使用了该注解的类的方法,并检测该方法是否使用了@RequestMapping 注解。

@RequestMapping

@RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。

@RequestMapping注解有六个属性:

  1. value:指定请求的实际地址;
  2. method: 指定请求的method类型, GET、POST、PUT、DELETE等
  3. consumes: 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html;
  4. produces:    指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回;
  5. params: 指定request中必须包含某些参数值是,才让该方法处理。
  6. headers: 指定request中必须包含某些指定的header值,才能让该方法处理请求。
@RequestParam

@RequestParam注解,该注解类型用于将指定的请求参数赋值给方法中的形参。

@RequestParam注解有4种属性:

  1. name属性:该属性的类型是String类型,它可以指定请求头绑定的名称;
  2. value属性:该属性的类型是String类型,它可以设置是name属性的别名;
  3. required属性:该属性的类型是boolean类型,它可以设置指定参数是否必须绑定;
  4. defalutValue属性:该属性的类型是String类型,它可以设置如果没有传递参数可以使用默认值。
@PathVaribale

@PathVaribale注解可以获得请求url中的动态参数。

@PathVaribale注解只支持一个属性value,类型String,表示绑定的名称,如果省略则默认绑定同名参数。

@RequestHeader

@RequestHeader注解用于将请求的头的信息区域数据映射到功能处理方法的参数上。

@RequestHeader注解有4种属性,分别如下:

  1. name属性:该属性的类型是String类型,它可以指定请求头绑定的名称;
  2. value属性:该属性的类型是String类型,它可以设置是name属性的别名;
  3. required属性:该属性的类型是boolean类型,它可以设置指定参数是否必须绑定;
  4. defalutValue属性:该属性的类型是String类型,它可以设置如果没有传递参数可以使用默认值。
@cookievalue

@cookievalue注解用于将请求的cookie数据映射到功能处理方法的参数上。

同样,它和@RequestHeader,还有@RequestParam注解一样,有相同的4种属性,分别如下:

  1. name属性:该属性的类型是String类型,它可以指定请求头绑定的名称;
  2. value属性:该属性的类型是String类型,它可以设置是name属性的别名;
  3. required属性:该属性的类型是boolean类型,它可以设置指定参数是否必须绑定;
  4. defalutValue属性:该属性的类型是String类型,它可以设置如果没有传递参数可以使用默认值。
@SessionAttributes

@SessionAttributes注解允许我们有选择地指定Model中的哪些属性需要转存到HttpSession对象当中。

@SessionAttributes注解有三个属性,分别如下:

  1. names属性:该属性的类型是String[],它可以指定Model中属性的名称,即存储在HttpSession当中的属性名称;
  2. value属性:该属性的类型是String[],它可以设置names属性的别名;
  3. types属性:该属性的类型是Class[] ,它可以指定参数是否必须绑定。

注意:@SessionAttributes只能声明在类似,而不能声明在方法上。

@ModelAttribute

@ModelAttribute注解将请求参数绑定到Model对象。

@ModelAttribute注解只支持一个属性value,类型为String,表示绑定的属性名称。

其他注解

@RequestBody:请求体参数转换

@ReponseBody:返回结果会转为JSON数据集

【JSR303数据验证】

@NotNull:验证规则不能为空

@Valid:启动验证

@InitBinder:可以用来绑定自定义验证器

九、Spring Security Spring Boot 中如何解决跨域问题 ?

在后端通过 跨域资源共享(CORS,Cross-origin resource sharing) 来解决跨域问题。要求先发送一个”预检”请求,待服务器批准后才能真正发起跨域访问请求。

  1. 方式1:返回新的CorsFilter(全局CORS配置)
  2. 方式2:重写WebMvcConfigurer(全局CORS配置)
  3. 方式3:使用注解(@CrossOrigin)(局部CORS配置)
  4. 方式4:手工设置响应头(HttpServletResponse )(局部CORS配置)

通过实现WebMvcConfigurer接口然后重写addCorsMappings方法解决跨域问题。(Interceptor拦截器在servlet之后执行)

@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后才进行Interceptor拦截器的处理。

返回新的CorsFilter(filter过滤器先于servlet执行)

@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);
    }
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/462059.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号