Java面试——Spring Boot
更多内容,移步 IT-BLOG
一、谈谈你对 SpringBoot 的理解
简单说说我的理解:Java是一个静态语言,相比动态语言,它相对笨重,体现在我们搭建 SSM 框架写一个 Helloword 的时候相当复杂,需要写一大堆的配置。还有在导入 jar包依赖的时候版本号问题,令人头疼。但是,我们有 Spring呀,真的是 Java 开发人员的福音。SpringBoot 就是为解决这些问题而生的。让我们写一个 Helloword 跟动态语言一样简单。版本控制也通过 SpringBoot 与 Maven的插件进行整合管理,让我们将重点放在业务的开发之上。下面就说说其优点:
【1】创建独立的 Spring 应用,可以通过 java -jar xx.jar 直接运行;
【2】直接嵌入 Tomcat、Jetty或Undertow 等 Web 容器(不需要部署 war 文件),后期与云计算平台集成方便(docket);
【3】提供固化的 “starter” 的 pom 配置简化构建 maven 配置,避免大量的 Maven导入和各种版本冲突;
【4】当条件满足时自动装配 Spring 或第三方类库;
【5】提供运维特性,基于 ssh、http、telnet 对服务器进行监控、健康检查以及外部化配置;
【6】SpringBoot 不需要 XML 配置,也不是通过代码生成来实现,而是通过条件注解+类实现配置文件;
【7】基于环境的配置使用这些属性,您可以将您正在使用的环境传递到应用程序:-Dspring.profiles.active = {enviornment}。在加载主应用程序属性文件后,Spring 将在(application{environment}.properties)中加载后续的应用程序属性文件。
二、Spring 和 SpringBoot 有什么不同
【1】Maven 依赖:Spring Boot 对依赖进行了进一步封装(starter),我们只需要根据场景依赖 starter 即可。在进行构建期间,所有其他依赖项将自动添加到项目中。
1 <!--首先,让我们看一下使用Spring创建Web应用程序所需的最小依赖项--> 2 <dependency> 3 <groupId>org.springframework</groupId> 4 <artifactId>spring-web</artifactId> 5 <version>5.1.0.RELEASE</version> 6 </dependency> 7 <dependency> 8 <groupId>org.springframework</groupId> 9 <artifactId>spring-webmvc</artifactId> 10 <version>5.1.0.RELEASE</version> 11 </dependency> 12 13 <!--与Spring不同,Spring Boot只需要一个依赖项来启动和运行Web应用程序--> 14 <dependency> 15 <groupId>org.springframework.boot</groupId> 16 <artifactId>spring-boot-starter-web</artifactId> 17 <version>2.0.6.RELEASE</version> 18 </dependency>
【2】Spring Boot 拥有默认的配置信息,Spring Boot 只需要在 application 配置文件中配置几个属性来完成如下操作:所有Spring 配置都是通过一个名为 auto-configuration 的过程添加 Boot web starter 来自动包含的。这意味着Spring Boot 将查看应用程序中存在的依赖项,属性和 Bean,并根据这些依赖项,对属性和 bean进行配置。当然,如果我们想要添加自己的自定义配置,那么
Spring Boot 自动配置将会退回。
1 spring.mvc.view.prefix=/WEB-INF/jsp/ 2 spring.mvc.view.suffix=.jsp
【3】 默认情况下,Spring Boot 使用嵌入式容器来运行应用程序。在这种情况下,Spring Boot 使用 public static void main
入口点来启动嵌入式 Web服务器。此外,它还负责将 Servlet,Filter 和 ServletContextInitializer
bean 从应用程序上下文绑定到嵌入式 servlet容器。Spring Boot 的另一个特性是它会自动扫描同一个包中的所有类或 Main 类的子包中的组件。Spring Boot 提供了将其部署到外部容器的方式:
1 @SpringBootApplication 2 public class Application { 3 public static void main(String[] args) { 4 SpringApplication.run(Application.class, args); 5 } 6 }
【4】打包和部署:这两个框架都支持
Maven 和 Gradle 等通用包管理技术。但是在部署方面,这些框架差异很大。例如,Spring Boot Maven 插件在 Maven中提供 Spring Boot支持。它还允许打包可执行jar 或 war包。在部署环境中 Spring Boot 对比 Spring的一些优点包括:
■ 提供嵌入式容器支持;
■ 使用命令 java -jar独立运行 jar;
■ 在外部容器中部署时,可以选择排除依赖关系以避免潜在的 jar 冲突;
■ 部署时灵活指定配置文件的选项;
■ 用于集成测试的随机端口生成;
简而言之,我们可以说 Spring Boot 只是 Spring本身的扩展,使开发,测试和部署更加方便。
三、SpringBoot 与 Spring Cloud 的区别
【1】Spring Cloud 基于Spring Boot,为微服务体系开发中的架构问题,提供了一整套的解决方案——服务注册与发现,服务消费,服务保护与熔断,网关,分布式调用追踪,分布式配置管理等。
【2】Spring Cloud 是一个基于 SpringBoot 实现的云应用开发工具;SpringBoot 专注于快速、方便集成的单个个体,Spring Cloud 是关注全局的服务治理框架;SpringBoot使用了默认大于配置的理念,很多集成方案已经帮你选择好了,能不配置就不配置,Spring Cloud 很大的一部分是基于 SpringBoot 来实现。
四、SpringBoot 中的 application.properties 或者 application.yml 配置文件是什么
application.yml 和 application.properties(默认配置文件) 文件这两种文件都是 SpringBoot的配置文件,注释都可以用#号来注释,只不过因为application.yml 看起来更直观,更清晰。但是要注意一点:properties 文件的优先级高于 yml文件,即如果两个文件中都配置了端口号,只有 properties中的端口号有效,而 yml文件中端口配置无效。
【1】application.properties 文件,在 properties文件中是以 ”.”进行分割的;
【2】application.properties 文件,都是 K-V格式,并且通过 ” : ” 引号进行赋值;需要注意冒号后面有个空格;
1 server: 2 port: 8081 3 4 spring: 5 datasource: 6 name: test 7 url: jdbc:mysql://localhost:3306/springbootdatabase 8 username: root 9 password: 123456 10 # 使用druid数据源 11 type: com.alibaba.druid.pool.DruidDataSource 12 driver-class-name: com.mysql.jdbc.Driver 13 filters: stat 14 maxActive: 20 15 initialSize: 1 16 maxWait: 60000 17 minIdle: 1 18 timeBetweenEvictionRunsMillis: 60000 19 minEvictableIdleTimeMillis: 300000 20 validationQuery: select 'x' 21 testWhileIdle: true 22 testOnBorrow: false 23 testOnReturn: false 24 poolPreparedStatements: true 25 maxOpenPreparedStatements: 20
五、SpringBoot 的核心配置文件有哪几个?它们的区别是什么?
Spring Boot 中有以下两种配置文件:bootstrap (.yml 或者 .properties) 和 application (.yml 或者 .properties):bootstrap 是应用程序的父上下文,也就是说 bootstrap 加载优先于 applicaton。这两个上下文共用一个环境。它默认也不能被本地相同配置覆盖。主要给运维人员使用,可以对开发的一些配置进行覆盖。bootstrap 配置文件有以下几个应用场景:使用 Spring Cloud Config 配置中心时,这时需要在 bootstrap 配置文件中添加连接到配置中心的配置属性来加载外部配置中心的配置信息。一些固定的不能被覆盖的属性和一些加密/解密的场景。
六、SpringBoot 的配置文件有哪几种格式?它们有什么区别?
.properties 和 .yml,它们的区别主要是书写格式不同。
【1】.properties:通过.进行分割。
【2】.yml:赋值的时候,冒号后面有个空格。不支持 @PropertySource 注解导入配置。可以通过如下注解:@ConfigurationProperties(prefix="xxx") String 类型的一定需要 setter 来接收属性值;maps、collections和 arrays不需要。
七、SpringBoot 的核心注解是哪个?它主要由哪几个注解组成的?
启动类上面的注解是 @SpringBootApplication,它也是 Spring Boot 的核心注解,主要组合包含了以下 3 个注解:
【1】@SpringBootConfiguration:组合了 @Configuration 注解,实现配置文件的功能。
【2】@EnableAutoConfiguration:打开自动配置的功能,也可以关闭某个自动配置的选项,如关闭数据源自动配置功能: @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })。
【3】@ComponentScan:Spring组件扫描。
【源码博客连接】:链接
八、SpringBoot 自动配置及原理
【1】SpringBoot 启动的时候加载主配置类,@SpringBootApplication下开启了主配置功能 @EnableAutoConfiguration;
【2】@EnableAutoConfiguration 作用:①、利用 EnableAutoConfigurationImportSelector 给容器导入一些组件。
②、可以查看 selectImports() 方法的内容:List configurations = getCandidateConfigurations(annotationMetadata, attributes);获取候选的配置。SpringFactoriesLoader.loadFactoryNames() 扫描所有 jar包类路径下 META‐INF/spring.factories 把扫描到的这些文件的内容包装成 properties对象从 properties中获取到 EnableAutoConfiguration.class 类(类名)对应的值,然后把他们添加在容器中。
【3】将类路径下 META-INF/spring.factories 里面配置的所有 EnableAutoConfiguration 的值加入到了容器中;
每一个这样的 xxxAutoConfiguration 类都是容器中的一个组件,都加入到容器中。用他们来做自动配置;
【4】每一个自动配置类进行自动配置,以 HttpEncodingAutoConfiguration(Http编码自动配置)为例解释自动配置原理;
根据当前不同的条件判断,决定这个配置类是否生效?一但这个配置类生效;这个配置类就会给容器中添加各种组件;这些组件的属性是从对应的 properties类中获取的,这些类里面的每一个属性又是和配置文件绑定的;
【5】所有在配置文件中能配置的属性都是在 xxxxProperties 类中封装;配置文件能配置什么就可以参照某个功能对应的属性类
精髓:【1】SpringBoot 启动会加载大量的自动配置类;
【2】看我们需要的功能有没有SpringBoot 默认写好的自动配置类;
【3】我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件有,我们就不需要再来配置了)
【4】给容器中自动配置类添加组件的时候,会从 properties类中获取某些属性。我们就可以在配置文件中指定这些属性的值;
xxxxAutoConfigurartion:自动配置类,给容器中添加组件。xxxxProperties:封装配置文件中相关属性;
【更多配置信息连接】:链接
九、如何理解 SpringBoot 中的 Starters
Starters 可以理解为启动器,它包含了一系列可以集成到应用里面的依赖包,你可以一站式集成 Spring及其他技术,而不需要到处找示例代码和依赖包。如你想使用 Spring JPA访问数据库,只要加入 spring-boot-starter-data-jpa 启动器依赖就能使用了。Starters 包含了许多项目中需要用到的依赖,它们能快速持续的运行,都是一系列得到支持的管理传递性依赖。
【1】starters 命名:Spring Boot 官方的启动器都是以 spring-boot-starter-* 命名的,代表了一个特定的应用类型。第三方的启动器不能以 spring-boot开头命名,它们都被 Spring Boot官方保留。一般第三方应该这样命名,像 mybatis 的 mybatis-spring-boot-starter。
【2】starters 分类:① Spring Boot 应用类启动器;② Spring Boot 生产启动器;③ Spring Boot 技术类启动器;④ 其他第三方启动器;
十、SpringBoot 有哪几种读取配置的方式
在 application.yml 或者 application.properties 文件中添加:
【1】@Value 注解读取方式:
【2】@ConfigurationProperties 注解读取方式:
【3】 @PropertySource+@Value注解:读取指定文件
注意:@PropertySource不支持 yml文件读取。
【4】 @PropertySource+@ConfigurationProperties注解读取方式:
【5】 Environment 读取方式:
十一、Spring Boot 支持哪些日志框架?推荐和默认的日志框架是哪个?
Spring Boot 支持 Java Util Logging、Log4j2、Lockback 作为日志框架,如果你使用 starters启动器,Spring Boot 将使用Logback 作为默认日志框架。无论使用哪种日志框架,Spring Boot 都支持配置将日志输出到控制台或者文件中。spring-boot-starter 启动器包含 spring-boot-starter-logging 启动器并集成了slf4j 日志抽象及 Logback日志框架。
【日志源码博客连接】:链接
十二、SpringBoot 实现热部署有哪几种方式
在 Spring Boot 实现代码热部署是一件很简单的事情,代码的修改可以自动部署并重新热启动项目。
【1】引用 devtools 依赖:当修改 java类时就会热更新。
【2】然后依次点击 File-Settings-Build、Execution、Deployment-Complier,在右边界面找到图: 并打勾;下一步按住这几个键 Ctrl+Shift+Alt+/,选中 Registry ,在弹出的提示框中找到 compiler.automake.allow.when.app.running 如下图并打钩,就可以顺利使用了。
【3】devtools 会在 windows资源管理器占用 java进程,在开发工具里面杀不掉,只能手动 kill掉,不然重启会选成端口重复绑定报错。
注意事项:1、生产环境 devtools将被禁用,如 java -jar方式或者自定义的类加载器等都会识别为生产环境。
2、打包应用默认不会包含 devtools,除非你禁用 SpringBoot Maven 插件的 excludeDevtools 属性。
3、Thymeleaf 无需配置 spring.thymeleaf.cache:false,devtools 默认会自动设置,参考完整属性。
十三、如何理解 Spring Boot 配置加载顺序
Spring Boot 会涉及到各种各样的配置,如开发、测试、生产就至少 3 套配置信息了。Spring Boot 可以轻松的帮助我们使用相同的代码就能使开发、测试、生产环境使用不同的配置。在 Spring Boot 里面,可以使用以下几种方式来加载配置:
【1】properties文件;
【2】YML文件;
【3】系统环境变量;
【4】命令行参数等等;
【配置属性加载的顺序如下】:数字小的优先级越高,即数字小的会覆盖数字大的参数值,我们来实践下,验证以上配置参数的加载顺序。
十四、Spring Boot 如何定义多套不同环境配置
首先我们要了解一个名词:Profile。简单来说,Profile 就是 Spring Boot 可以对不同环境或者指令来读取不同的配置文件。假如有开发、测试、生产三个不同的环境,需要定义三个不同环境下的配置。
【1】基于 properties文件类型:你可以另外建立3个环境下的配置文件:然后在 applcation.properties 文件中指定当前的环境 spring.profiles.active=test,这时候读取的就是 application-test.properties文件。
【2】基于 yml文件类型:只需要一个 applcation.yml 文件就能搞定,推荐此方式。此时读取的就是 dev的配置。
【3】在 cmd 命令中指定:
【4】在IDEA 编辑器中指定:在运行按钮(绿色三角形按钮)旁边选择 Edit Configurations...
,在弹出的对话框中 Active profiles 输入 dev 或其他即可。这种方法只有在本地调试的时候才生效。
【优秀博客连接】:链接
十五、SpringBoot 启动类的原理
【源码连接】:链接
十六、SpringBoot 静态资源配置及原理
【源码连接】:链接
十七、SpringBoot 国际化配置及原理
【源码连接】:链接
十八、SpringBoot 模板引擎配置及原理
【源码连接】:链接
十九、SpringBoot 错误页面配置及原理
【源码连接】:链接
二十、SpringBoot 拦截器配置及原理
【源码连接】:链接
二十一、SpringBoot MVC配置及原理
【源码连接】:链接
二十二、SpringBoot 嵌入式容器配置及原理
【源码连接】:链接
二十三、如何在 Spring Boot 启动的时候运行一些特定的代码
如果想在 Spring Boot 启动的时候运行一些特定的代码,你可以实现接口 ApplicationRunner 或者 CommandLineRunner,这两个接口实现方式一样,它们都只提供了一个run方法。CommandLineRunner:启动获取命令行参数:
ApplicationRunner:启动获取应用启动的时候参数:
【启动顺序】:如果启动的时候有多个 ApplicationRunner 和CommandLineRunner,想控制它们的启动顺序,可以实现org.springframework.core.Ordered 接口或者使用 org.springframework.core.annotation.Order 注解。
二十四、自己实现一个 start
【博客链接】:链接