• Spring Boot常见面试题


    Spring Boot简介

    Spring Boot 是由 Pivotal 团队提供,用来简化 Spring 应用创建、开发、部署的框架。它提供了丰富的Spring模块化支持,可以帮助开发者更轻松快捷地构建出企业级应用。Spring Boot通过自动配置功能,降低了复杂性,同时支持基于JVM的多种开源框架,可以缩短开发时间,使开发更加简单和高效。

    Spring Boot 优点

    Spring Boot有以下优势:
    (1) 容易上手,提升开发效率,为 Spring 开发提供一个更快、更广泛的入门体验。
    (2) 开箱即用,提供各种默认配置来简化项目配置。
    (3) 尽可能自动化配置Spring和第三方类库。
    (4) 内嵌式容器(如tomcat、jetty、Undertow)简化Web项目。
    (5) 没有冗余代码生成和XML配置的要求。
    (6) 避免大量的 Maven 导入和各种版本冲。

    Spring Boot 自动装配

    Spring Boot的自动装配是指Spring Boot会自动将一些配置类的Bean注册到IOC容器中,我们可以在需要的地方使用@Autowired或@Resource等注解来使用它。SpringBoot定义了一套接口规范,这套规范规定:Spring Boot在启动时会扫描外部引用jar包中的META-INF/spring.factories文件,将文件中配置的类型信息加载到Spring容器并执行类中定义的各种操作。
    自动装配可以简单理解为:通过注解或者一些简单的配置就能在Spring Boot的帮助下实现某块功能。这样就可以更快速地构建应用程序,而无需手动配置大量的Bean。

    自动装配原理简介

    Spring Boot 通过@EnableAutoConfiguration开启自动装配,通过 SpringFactoriesLoader 最终加载META-INF/spring.factories中的自动配置类实现自动装配,自动配置类其实就是通过@Conditional按需加载的配置类,想要其生效必须引入spring-boot-starter-xxx包实现起步依赖。
    可以直接使用@SpringBootApplication注解。@SpringBootApplication注解是一个组合注解,包含如下三个注解:
    @SpringBootConfiguration(里面就是@Configuration,标注当前类为配置类,其实只是做了一层封装改了个名字而已)
    @EnableAutoConfiguration(开启自动配置)
    @ComponentScan(包扫描)
    这样,在Spring Boot应用的main方法中 添加@SpringBootApplication或者@EnableAutoConfiguration注解接口。这样在程序执行的时候,会自动去maven中读取每个starter中的spring.factories文件,该文件里配置了所有需要被创建spring容器中的Bean。

    如何理解Spring Boot的约定优于配置?

    首先,约定优于配置是一种软件设计的范式,它的核心思想是减少软件开发人员对于配置项的维护,从而让开发人员更加聚焦在业务逻辑上。Spring Boot 就是约定优于配置这一理念下的产物,它类似于 Spring 框架下的一个脚手架,通过 Spring Boot,我们可以快速开发基于 Spring 生态下的应用程序。
    基于传统的 Spring 框架开发 web 应用,我们需要做很多和业务开发无关并且只需要做一次的配置,比如管理 jar 包依赖web.xml 维护Dispatch-Servlet.xml 配置项维护应用部署到 Web 容器第三方组件集成到Spring IOC 容器中的配置项维护而在 Spring Boot 中,我们不需要再去做这些繁琐的配置,SpringBoot已经自动帮我们完成了,这就是约定优于配置思想的体现。
    除此之外,Spring Boot 约定优于配置的体现还有很多,比如Spring Boot Starter 启动依赖,它能帮我们管理所有 jar 包版本如果当前应用依赖了spring mvc相关的jar,那么Spring Boot会自动内置Tomcat容器来运行 web 应用,我们不需要再去单独做应用部署。Spring Boot 的自动装配机制的实现中,通过扫描约定路径下的 spring.factories文件来识别配置类,实现 Bean 的自动装配。默认加载的配置文件 application.properties 等等。

    Spring Boot 中的 starter 到底是什么?

    首先,这个 Starter 并非什么新的技术点,还是基于 Spring 已有功能来实现的。首先它提供了一个自动化配置类,一般命名为 XXXAutoConfiguration ,在这个配置类中通过条件注解来决定一个配置是否生效(条件注解就是 Spring 中原本就有的),然后它还会提供一系列的默认配置,也允许开发者根据实际情况自定义相关配置,然后通过类型安全的属性注入将这些配置属性注入进来,新注入的属性会代替掉默认属性。正因为如此,很多第三方框架,只需要引入依赖就可以直接使用了。当然,开发者也可以自定义 Starter。
    Starter可以理解为启动器,它包含了一系列可以集成到应用里面的依赖包,可以实现一站式集成 Spring 及其他技术,而不需要到处找示例代码和依赖包。例如,如果想使用 Sping 和 JPA 访问数据库,只需要你的项目包含 spring-boot-starter-data-jpa 依赖项,就可以完美进行。

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

    新创建一个 Spring Boot 项目,默认都是有 parent 的,这个 parent 就是 spring-boot-starter-parent,spring-boot-starter-parent 主要有如下作用:
    定义了 Java 编译版本为 1.8。
    使用 UTF-8 格式编码。
    继承自 spring-boot-dependencies,这个里边定义了依赖的版本,也正是因为继承了这个依赖,所以我们在写依赖时才不需要写版本号。
    执行打包操作的配置。
    自动化的资源过滤。
    自动化的插件配置。
    针对 application.properties 和 application.yml 的资源过滤,包括通过 profile 定义的不同环境的配置文件,例如 application-dev.properties 和 application-dev.yml。

    Spring Boot配置文件

    在大多数情况下,自动配置的Bean可以满足基本需求,但还是需要覆盖一些配置以满足特定的需求。
    Spring的环境抽象是各种配置属性的一站式服务。它抽取了原始的属性,这样需要这些属性的Bean就可以从Spring中获取。Spring环境会拉取多个属性源,包括:
    (1) JVM系统属性;
    (2) 操作系统环境变量;
    (3) 命令行参数;
    (4) 应用属性配置文件。
    它会将这些属性聚合到一个源中,通过这个源可以注入到Spring的Bean中。
    请添加图片描述
    Spring 环境拉取多个属性源的属性,然后注入到Spring 的Bean中。这样通过 Spring Boot 自动配置的 Bean 就可以通过 Spring 环境进行配置。如,希望应用底层的Servlet容器使用另一个端口监听请求,而不再使用默认的8080端口,那么可以在application.properties文件中的属性(如server.port=9000)进行配置。
    注意,如果使用环境变量而不是系统属性,大多数操作系统不允许使用句点分隔的键名,但可以使用下划线代替(例如, SPRING_CONFIG_NAME 代替 spring.config.name)。

    properties文件和yaml文件

    SpringBoot配置文件支持的格式有两种:properties和yaml。这里重点说下yaml格式。yaml格式文件基本语法如下:

    大小写敏感
    使用缩进表示层级关系
    缩进不允许使用tab,只允许空格
    缩进的空格数不重要,只要相同层级的元素左对齐即可  
    使用#表示注释
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在选用配置文件类型时,可遵从以下原则:
    (1) 对于较复杂的数据结构(如数组),yaml优先于properties。
    (2) 对于支持的编程语言种类,yaml优先于properties。
    注:yaml除了支持Java语言,还支持python、go等大量编程语言。
    (3) yaml支持中文内容,properties若想支持中文内容只能用unicode编码。
    作为一种通用的格式,推荐使用yaml文件。

    配置文件加载

    springboot启动会扫描以下位置的application.properties/application.yaml文件作为其默认配置文件:

    优先级1:项目路径下的config文件夹配置文件
    优先级2:项目路径下配置文件
    优先级3:资源路径下的config文件夹配置文件
    优先级4:资源路径下配置文件
    
    • 1
    • 2
    • 3
    • 4

    请添加图片描述
    若相同优先级位置(同一目录下)下同时有properties文件和yaml文件,properties文件中的内容会覆盖yaml文件中的内容。(相同目录下,如果同时存在properties文件和yaml文件,则优先使用properties文件)

    加密配置属性

    使用 jasypt 实现加解密配置属性。这里采用非对称加密的实现。具体实施步骤如下:
    (1) 本地基于公钥手动将明文生成密文。
    (2) 将私钥存储到特定的文件中。
    (3) 将文件放到服务器指定位置。
    (4) 通过文件挂载的方式,引用文件。
    (5) 从文件中读取文件并将密文解密成明文。

    JavaBean 属性绑定

    Spring Boot在将 Environment 属性绑定到 @ConfigurationProperties Bean。将@ConfigurationProperties注解放到Spring Bean上之后,它就会为该Bean中那些能够根据Spring环境注入值的属性赋值。 示例如下:

    my:
      service:
        enable: true
        security:
            username: local
            pasword: ENC(xxxaaa)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    @ConfigurationProperties("my.service")
    public class MyProperties {
        private boolean enable;
        
        private final Security security = new Security();
    
        // getters/setters...
    
        public static class Security {
    
            private String username;
    
            private String pasword;
    
            // getters/setters...
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    Spring Boot 常见的读取配置的方式?

    Spring Boot 可以通过 @PropertySource(.properties文件),@Value,@Environment,@ConfigurationProperties 等方式来绑定变量。

    Spring Profiles

    Spring profiles是一种条件化的配置,在运行时,根据哪种profile处于激活状态,可以使用或忽略不同的Bean、配置类和配置属性。
    定义特定profile相关的属性的一种方式是创建另一个属性文件。文件的名称要遵循如下的约定:application-{profile名称}.文件后缀。然后,就可以在该文件中声明适用于该profile的配置属性了。
    对于存在多个profile的场景,可以使用 spring.profiles.active 属性来指定哪些配置文件是活动的(active)。示例如下:

    spring:
      profiles:
        active: production
    
    • 1
    • 2
    • 3

    对应Bean的定义补充@Profile注解,如果该Bean是和特定环境相关。

    @Profile("production")
    public class ProductionConfiguration {
        // ...
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    Spring Boot 异常处理

    Spring 提供了一种使用 ControllerAdvice 处理异常的非常有用的方法。 我们通过实现一个 ControlerAdvice 类,来处理控制器类抛出的所有异常。

    @ControllerAdvice
    public class GlobalExceptionHandler {
        @ExceptionHandler(Exception.class)
        public ModelAndView customException(Exception e) {
            ModelAndView mv = new ModelAndView();
            mv.addObject("message", e.getMessage());
            mv.setViewName("myerror");
            return mv;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    Spring Boot 任务执行和调度

    如果context没有 Executor Bean,Spring Boot会自动配置一个 ThreadPoolTaskExecutor ,它具有合理的默认值,可以自动与异步任务执行( @EnableAsync )和Spring MVC的异步请求处理相关联。
    可以配置的有:ThreadPoolTaskExecutor(异步任务)、ThreadPoolTaskScheduler(定时任务)。

    spring:
      task:
        execution:
          pool:
            max-size: 16
            queue-capacity: 100
            keep-alive: '10s'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    spring:
      task:
        scheduling:
          thread-name-prefix: "scheduling-"
          pool:
            size: 2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    Spring Boot 与第三方的集成

    Spring Boot集成日志

    Spring Boot在所有内部日志中使用 Commons Logging ,但对底层日志的实现保持开放。 为 Java Util Logging 、 Log4j2 、 Logback 提供了默认配置。 在每一种情况下,记录器(logger)都被预设为使用控制台输出,也可以选择输出到文件。
    默认情况下,如果使用 “Starter”,则默认使用Logback。 适当的Logback路由也包括在内,以确保使用Java Util Logging、Commons Logging、Log4J或SLF4J的依赖库都能正确工作。

    支持的日志级别从低到高依次是:

    TRACE < DEBUG < INFO < WARN < ERROR < FATAL  
    
    • 1

    一般需要从环境变量获取日志级别,方便线上动态调整,方便测试。

    Spring Boot 集成 Mybatis

    MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

    Spring Boot 集成Redis

    Redis是常用的缓存中间件。

    Spring Boot 集成MQ

    MQ有很多,主流的MQ有kafka、RocketMQ、RabbitMQ等。推荐使用Kafka。

    部署 Spring Boot 应用

    根据文件类型,可将Spring Boot应用构建成可执行JAR文件或传统的WAR文件。这种选择取决于要将应用部署到传统的Web应用服务器还是部署到云中。
    (1) 部署到Java应用服务器(Web容器)中。
    如果必须将应用部署到Tomcat、Jetty、WebLogic等Web容器中,只能将应用构建成WAR文件。注意,Spring Boot在构建时,默认内嵌Web容器。所以,该种场景的部署,还需移除对Tomcat等Web容器的依赖。WAR文件是专门针对在Web容器中部署设计的。
    (2) 部署到云平台。
    如果要将应用部署到云平台,可执行的JAR文件(内嵌Web容器,如Tomcat等)是最佳的选择。即使云平台支持WAR部署,JAR文件也要比WAR格式简单的多。
    接下来,将会关注三种部署场景:
    (1) 将Spring Boot应用以WAR文件的形式部署到Web容器中,如Tomcat。
    (2) 将Spring Boot应用作为可执行的JAR文件,推送到云平台。
    (3) 将Spring Boot应用打包到Docker容器,将其部署到任何支持Docker形式的平台中。

    构建和部署WAR文件

    如果要将应用程序部署到Web容器中,就需要构建一个WAR文件。为了让Web容器知道如何运行应用程序,需要创建Web.xml文件或Servlet Initializer类来声明Spring 的DispatchServlet。Spring Boot提供的SpringBootServletInitializer使这个过程变得更加简单。SpringBootServletInitializer是一个能够感知Spring Boot环境的特殊SpringWebApplicationInitializer实现。除了配置Spring的DispatchServlet之外,SpringBootServletInitializer还会查找Spring应用上下文中所有Filter、Servlet或ServletContextInitializer类型的Bean,并将其注册到Servlet容器中。

    @Configuration
    @ComponentScan
    @EnableAutoConfiguration
    public class Application extends SpringBootServletInitializer {
    
        public static void main(String[] args) {
            SpringApplication.run(Application.Class, args);
        }
    
        @Override
        protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
            return application.sources(Application.Class);
        }
    
        private static Class<Application> applicationClass = Application.class;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    此外,还需对项目的构建文件类型进行调整。如果使用Maven构建,只需要确保pom.xml文件元素设置为war即可:

    <packaging>warpackaging>
    
    • 1

    执行构建动作后,即可生成WAR文件。
    部署WAR文件就是WAR文件放到Web容器的指定目录。如Tomcat是webapp目录。
    随着进入云部署时代,JAR文件是更好的选择。

    构建和部署JAR文件

    基于JAR文件的方式,是目前的主流实现。
    服务器的硬件购买和维护成本可能代价高昂。当出现高负载时,恰当地对服务器进行扩展是非常困难的,对有些组织来说,这样做甚至是不允许的。如今,将应用部署到云中是一种人们广泛关注并能够节省成本的方案。
    我们有多种可选的云方案,但人们目前最关注的是平台即服务(Platform as a Service,PaaS)。PaaS提供现成的应用部署平台,其中包含多种可以绑定到应用上的附加服务(比如数据库和消息代理)。
    可提供推送工具将JAR文件推送到PaaS平台。如果推送成功,应用就可完成部署并处理请求。

    在Docker中运行Spring Boot应用

    在云中部署应用程序的另一种常见方法是将应用程序打包到Docker等容器中,然后发布到云中。如将应用程序推送到AWS这样的基础设施即服务(Infrastructure as a Service, IaaS)平台。
    容器化应用程序的概念借鉴了现实世界中的联运集装箱。在运输过程中,不管里面的东西是什么,所有的联运集装箱都有一个标准的尺寸和格式。按照类似的方式,容器化的应用程序遵循通用的容器格式,可以在任何地方部署和运行,而不必关心里面的应用是什么。
    Spotify提供了一个Maven插件,借助它可以轻易地将Spring Boot的构建结果创建为Docker容器。对应配置代码如下:

    <build>
        <plugins>
            <plugin>
                <groupId>com.spotifygroupId>
                <artifactId>dockerfile-maven-pluginartifactId>
                <version>1.4.3version>
                <configuration>
                    <reposity>
                        ${docker.image.prefix}/${project.artifactId}
                    reposity>
                    <buildArgs>
                    <JAR_FILE>target/${project.build.finalName}.jarJAR_FILE>
                    buildArgs>
                configuration>
            plugin>
        plugins>
    build>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    在代码块下,设置了一些属性,用于指导如何创建Docker镜像。

    使用NGINX做反向代理

    实际开发中,还会在服务器端使用NGINX做代理,也就是让Ngnix代理REST请求到Spring Boot应用程序。

    Spring Boot 中的监视器是什么?

    Spring boot actuator 是 spring 启动框架中的重要功能之一。Spring boot 监视器可帮助您访问生产环境中正在运行的应用程序的当前状态。
    有几个指标必须在生产环境中进行检查和监控。即使一些外部应用程序可能正在使用这些服务来向相关人员触发警报消息。监视器模块公开了一组可直接作为 HTTP URL 访问的REST 端点来检查状态。
    在平台上部署时,应用程序可以使用 Kubernetes Probes 等基础设施向平台提供有关其可用性的信息。Spring Boot对常用的 “liveness” 和 “readiness” 可用性状态提供了开箱即用的支持。如果你使用Spring Boot的 “actuator” ,那么这些状态将作为健康端点组(health endpoint groups)暴露出来。

    Liveness

    一个应用程序的 “Liveness” 状态告诉我们它的内部状态是否允许它正常工作,或者在当前失败的情况下自行恢复。

    Readiness

    应用程序的 “Readiness” 状态告诉平台,该应用程序是否准备好处理流量。 failing状态的 “Readiness” 告诉平台,它暂时不应该将流量发送到该应用程序。

    参考

    https://www.baidu.com/ 百度AI助手
    https://docs.spring.io/spring-boot/docs Spring Boot官方文档
    https://springdoc.cn/spring-boot/index.html Spring Boot 中文文档
    https://springdoc.cn/spring-boot/features.html#features.external-config Spring Boot 核心特性
    https://blog.csdn.net/ThinkWon/article/details/104397299 Spring Boot面试题
    https://cloud.tencent.com/developer/article/2110061 40个SpringBoot面试题
    https://blog.csdn.net/cx521600/article/details/90205359 SpringBoot常见的经典面试题
    https://zhuanlan.zhihu.com/p/643166816 2023 SpringBoogt高频面试题(精品)
    https://www.cnblogs.com/lenve/p/10748453.html SpringMVC 中 @ControllerAdvice 注解的三种使用场景

    https://cloud.tencent.com/developer/article/1481147 [Spring Boot] 如何优雅的对配置文件进行加密
    https://blog.csdn.net/justry_deng/article/details/95712802 SpringBoot使用jasypt加密密码等重要信息

  • 相关阅读:
    【历史上的今天】11 月 11 日:腾讯成立;信息论先驱出生;阿德曼提出 DNA 计算
    优步让一切人工智能化
    【Vue】父子组件间如何通过事件进行通信(2)
    corrplot包画相关性图详解
    【Vant2】Tab标签页组件自动跳转的坑
    海外商城小程序为什么这么受欢迎?
    服务器为什么会丢包
    MySQL的事务和存储引擎
    IDEA 快捷键记录【个人向】
    做酒类行业应该如何推广自身品牌?
  • 原文地址:https://blog.csdn.net/wangxufa/article/details/133033847