【Java面试】SpringBoot篇

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 【Java面试】SpringBoot篇

Spring和SpringBoot的关系和区别?

他们都是Spring生态的产品。

Spring Framework是一个容器框架。

SpringBoot他不是一个框架,他是一个可以快速构建基于Spring的脚手架,里面包含了Spring和各自框架,为开发Spring生态其他框架铺平道路。他是为了更快的去开发Spring生态的整个系统而诞生的。

2者不是一个层面的东西,没有可比性。

谈谈你对SpringBoot的理解,它有哪些特性?

从本质上来说,Spring Boot就是Spring,它做了那些没有它你自己也会去做的Spring Bean配置。Spring Boot使用“约定优于配置”的理念让你的项目快速地运行起来,使用Spring Boot很容易创建一个能独立运行、准生产级别、基于Spring框架的项目,使用Spring Boot你可以不用或者只需要很少的Spring配置

简而言之,Spring Boot本身并不提供Spring的核心功能,而是作为Spring的脚手架框架,以达到快速构建项目、预置三方配置、开箱即用的目的。Spring Boot有如下的优点:

  • 可以快速构建项目,内置许多starter自动配置,开箱即用;
  • 可以对主流开发框架的无配置集成;
  • 项目可独立运行,无需外部依赖Servlet容器;
  • 提供运行时的应用监控;
  • 内置web容器,无需依赖外部web服务器,省略了web.xml,直接运行jar文件就可以启动web项目
  • 可以极大地提高开发、部署效率;
  • 管理了第三方依赖的版本,减少版本冲突问题
  • 简化开发,采用JavaConfig的方式可以使用零xml的方式开发项目
  • 可以与云计算天然集成。

SpringBoot的核心注解

  1. @SpringBootApplication注解:这个注解标识了一个SpringBoot工程,它实际上是另外三个注解的组合,这三个注解是@SpringBootConfiguration,@EnableAutoConfguration,@ComponentScan。
  2. @SpringBootConfiguration:这个注解实际就是一个@Configuration,表示启动类也是一个配置类。
  3. @EnableAutoConfguration:向Spring容器中导入了一个Selector,用来加载ClassPath下spring.factories中所定义的自动配置类,将这些自动加载为配置Bean。
  4. @Conditional也很关键,如果没有它我们无法在自定义应用中进行定制开发
    @ConditionalOnBean
    @ConditionalOnClass
    @ConditionalOnExpression

说说你对SpringBoot自动配置的理解

自动装配简单来说就是自动吧第三方的bean加载到IOC容器中去。不需要开发人员在去写bean相关的配置。在sb项目中只要在启动类上加上@SpringBootApplication注解就可以实现自动装配。这个注解是一个复合注解,真正去实现自动装配的注解是@EnableAutoConfiguration。自动装配的实现主要依靠三个核心的技术。

第一个是引入starter。启动依赖组件的时候,这个组件里面必须包含@Configuration配置类,而在这个配置类中我们需要通过@Bean这个注解去声明要加载到IOC容器中的对象。

第二个是这个配置类是放在第三方的jar包中的。然后通过sb中的约定优于配置这样的一个理念,去吧这个配置类的全路径放在classpath:/META-INF/spring.factories文件里面。这样sb就可以知道第三方jar包里面这个配置类的位置。这个步骤主要使用到了spring中的SpringFactoriesLoader来完成的。

第三个是sb拿到所有第三方jar包里面的声明的配置类之后,在通过Spring提供的ImportSelector这样的一个接口,来实现对这些配置类的动态加载。从而去完成自动装配这样一个动作。

在我看来呢,sb是约定优于配置这一理念的产物,所以在很多的地方都会看到这一思想。它的出现让开发人员可以更加聚焦于业务代码的开发,而不需要去关心和业务无关的配置。其实自动装配的思想,在SpringFrameword3.x中的@Enable注解已经有了体现。这是一个模块

驱动注解,也就是我们只要添加这个注解,就能自动开启某个功能。而不需要针对这个功能去做bean的配置。enbale的底层也是自动帮我们去完成一个模块相关bean的注入的。

为什么SpringBoot的jar包可以直接运行?

  1. SpringBoot提供了一个插件spring-boot-maven-plugin用于把程序打包成一个可执行的jar包。
  2. Spring Boot应用打包之后,生成一个Fat jar(jar包中包含jar,比较臃肿,所以叫Fat.jar),包含了应用依赖的jar包和Sprirg Boot loader相关的类。
  3. java -jar会去找jar中的manifest文件,在那里面找到真正的启动类。
    这是因为Java已经定义了java -jar这个命令去加载jar包中的manifest文件,并且以这个文件中的Main-Class后面的路径来找到启动类。
  4. Fat jar的启动Main函数是JarLauncher,它负责创建一个LaunchedURLClassLoader来加载boot-lib下面的jar,并以一个新线程启动应用的Main函数。

SpringBoot的启动原理(还在改进)

会不会自定义Starter?大概实现过程?

我们需要在我们自定义的starter中的resources下创建文件夹META-INF并在METE-INF下创建文件spring.factories。

然后在里面设定你要自动配置的配置类的全路径。格式为

之后我们编写我们的配置类,并且在配置类中通过@Bean注解把要注入IOC容器中的bean进行声明。

SpringBoot读取配置文件的原理是什么?加载顺序是怎么样的?

通过事件监听的方式读取配置文件:ConfigFileApplicationListener

优先级从高到低,高优先级的配置覆盖低优先级的配置,所有配置会形成互补配置。

SpringBoot的默认日志实现框架是什么?怎么切换成别的?

默认的日志框架是logback。

SpringBoot项目的日志门面使用的是slf4j,而SpringBoot默认使用的是logback提供的桥接器,因此SpringBoot默认会使用logback进行日志功能。

想要切换日志,那么需要做如下操作:

1:将logback的场景启动器排除(slf4j只能运行有一个桥接器)

2:添加新的日志的场景启动器

3:添加新的日志的配置文件

目前springboot已经为我们提供了logfj2和logback的starter,因此我们可以直接开箱即用。

但是如果要使用logfj,那么就需要首先排除logbakc的依赖,然后添加log4j的桥接器,然后再添加log4j的配置文件。

说说你在开发的时候怎么在SpringBoot上进行扩展?

如果想要对某个功能进行扩展,那么首先得了解这个功能是如何进行配置的,因此我可能会先去查看这个功能的官方文档,之后大致了解之后,会查看底层源码。

这里我以AOP为例吧。

我们知道AOP默认使用的是cglib来进行动态代理,那么如果我想要它使用JDK提供的动态代理怎么办呢?

那么此时就得去查看AOP对应的配置类了。

我知道SpringBoot项目中的配置类一般名称为XxxAutoConfiguration。

因此我就会搜索AopAutoConfiguration。然后查找启动的可能的配置属性。

一般查看@Condition注解里面可能会有某个属性的开关。

那么如果找到了,那么只需要去配置文件中进行属性的修改配置即可。

当然,有些自动配置类提供对外的扩展接口,实现接口也可以进行扩展,比如我们的SpringMvc。

如果我们要对SpringMvc进行扩展,那么我们只要实现WebMvcConfigurer这个接口即可。

所以我一般都会选择看源码这种方式。IDEA非常方便,搜索对应的XxxAutoConfiguration即可。

SpringBoot是如何选择使用Jetty还是Tomcat的?

我们知道,我们是可以获取到SpringBoot要进行加载的Bean的类型的,那么如果我们获取到了所有要加载的Bean,那么此时就可以通过这些Bean对象来选择是使用Jetty还是Tomcat。

比如我定义了Tomcat,那么我就选择加载Tomcat,反之我可以加载Jetty。如果都定义或者都没有定义,那么会进行报错。其中没有名字报错是因为你明明把这个项目声明为了一个Web项目,结果你没有对应的服务器,或者就是你只能选择一个服务器,结果你给我定义了多个服务器,那么我选那个?所以会报错。那么如果流程正常,我就会创建这个Bean,也就是Tomcat或者Jetty服务器。

但是其实SpringBoot默认把Jetty,Tomcat,Undertow三个Web服务器都声明为了Bean,那么很明显会出现冲突。所以此时就通过@Condition进行条件判断来选择加载那个Bean。

所以其大致流程为:

首先通过getWebServerFactory方法来获取一个ServletWebServerFactory对象,其中Jetty和Tomcat都实现了这个接口。

那么如果返回的是Tomcat的ServerFatory,那么之后的getWebServer方法返回的就是Tomcat这个web服务,反之就是Jetty。在这个方法中,Tomcat和Jetty都会在其中创建自己,然后作为一个对象返回。

那么我们知道SpringBoot默认使用的是Tomcat,那么要做到这样,只要保证我们的依赖中只有Tomcat而没有Jetty和Undertow即可。

所以此时我们引入的web-starter中,其中默认就是帮助我们引入了Tomcat这个依赖,所以,默认使用的就是Tomcat。而我们只需要使用exclude去排除tomcat依赖,并且引入我们需要的服务器,就可以转换服务器的类型。

并且,我们知道默认的Tomca的端口是8080,原因是因为SpringBoot项目中默认把这个端口写死在了Tomcat服务器的父类中。那么如果我们想要修改这个端口,就需要使用Spring提供的后置处理----BeanPostProcess来进行对端口的修改。

最终追述到ServerProperties这个配置类即可。其中有一个port属性,这个属性就会覆盖原有的Tomcat的端口。


相关实践学习
通过日志服务实现云资源OSS的安全审计
本实验介绍如何通过日志服务实现云资源OSS的安全审计。
相关文章
|
4月前
|
缓存 Java 关系型数据库
2025 年最新华为 Java 面试题及答案,全方位打造面试宝典
Java面试高频考点与实践指南(150字摘要) 本文系统梳理了Java面试核心考点,包括Java基础(数据类型、面向对象特性、常用类使用)、并发编程(线程机制、锁原理、并发容器)、JVM(内存模型、GC算法、类加载机制)、Spring框架(IoC/AOP、Bean生命周期、事务管理)、数据库(MySQL引擎、事务隔离、索引优化)及分布式(CAP理论、ID生成、Redis缓存)。同时提供华为级实战代码,涵盖Spring Cloud Alibaba微服务、Sentinel限流、Seata分布式事务,以及完整的D
203 2
|
3月前
|
缓存 Java API
Java 面试实操指南与最新技术结合的实战攻略
本指南涵盖Java 17+新特性、Spring Boot 3微服务、响应式编程、容器化部署与数据缓存实操,结合代码案例解析高频面试技术点,助你掌握最新Java技术栈,提升实战能力,轻松应对Java中高级岗位面试。
337 0
|
3月前
|
Java 数据库连接 API
Java 8 + 特性及 Spring Boot 与 Hibernate 等最新技术的实操内容详解
本内容涵盖Java 8+核心语法、Spring Boot与Hibernate实操,按考试考点分类整理,含技术详解与代码示例,助力掌握最新Java技术与应用。
112 2
|
4月前
|
算法 架构师 Java
Java 开发岗及 java 架构师百度校招历年经典面试题汇总
以下是百度校招Java岗位面试题精选摘要(150字): Java开发岗重点关注集合类、并发和系统设计。HashMap线程安全可通过Collections.synchronizedMap()或ConcurrentHashMap实现,后者采用分段锁提升并发性能。负载均衡算法包括轮询、加权轮询和最少连接数,一致性哈希可均匀分布请求。Redis持久化有RDB(快照恢复快)和AOF(日志更安全)两种方式。架构师岗涉及JMM内存模型、happens-before原则和无锁数据结构(基于CAS)。
117 5
|
4月前
|
Java API 微服务
2025 年 Java 校招面试全攻略:从面试心得看 Java 岗位求职技巧
《2025年Java校招最新技术要点与实操指南》 本文梳理了2025年Java校招的核心技术栈,并提供了可直接运行的代码实例。重点技术包括: Java 17+新特性(Record类、Sealed类等) Spring Boot 3+WebFlux响应式编程 微服务架构与Spring Cloud组件 Docker容器化部署 Redis缓存集成 OpenAI API调用 通过实际代码演示了如何应用这些技术,如Java 17的Record类简化POJO、WebFlux构建响应式API、Docker容器化部署。
156 5
|
4月前
|
缓存 NoSQL Java
Java Redis 面试题集锦 常见高频面试题目及解析
本文总结了Redis在Java中的核心面试题,包括数据类型操作、单线程高性能原理、键过期策略及分布式锁实现等关键内容。通过Jedis代码示例展示了String、List等数据类型的操作方法,讲解了惰性删除和定期删除相结合的过期策略,并提供了Spring Boot配置Redis过期时间的方案。文章还探讨了缓存穿透、雪崩等问题解决方案,以及基于Redis的分布式锁实现,帮助开发者全面掌握Redis在Java应用中的实践要点。
203 6
|
4月前
|
安全 Java API
2025 年 Java 校招面试常见问题及详细答案汇总
本资料涵盖Java校招常见面试题,包括Java基础、并发编程、JVM、Spring框架、分布式与微服务等核心知识点,并提供详细解析与实操代码,助力2025校招备战。
201 1
|
4月前
|
算法 Java 微服务
2025 年 Java 面试宝典社招春招秋招实操全方位攻略
2025年Java面试宝典涵盖核心技术及最新趋势,分为四大板块:1. Java基础:深入数据类型、多态等特性,结合学生信息管理等实例;2. JVM核心:解析内存模型与GC算法,附多线程转账等场景应用;3. 高并发方案:详解synchronized与线程池配置,提供Web服务器优化案例;4. Spring生态:剖析IoC/AOP原理,演示微服务架构实现。特别新增Java 17+特性实操,包括Record类、密封接口等语法糖,整合Spring Boot 3、响应式编程及云原生技术,通过订单状态机、API网关配置。
270 1
|
4月前
|
Java 数据库连接 API
Java 对象模型现代化实践 基于 Spring Boot 与 MyBatis Plus 的实现方案深度解析
本文介绍了基于Spring Boot与MyBatis-Plus的Java对象模型现代化实践方案。采用Spring Boot 3.1.2作为基础框架,结合MyBatis-Plus 3.5.3.1进行数据访问层实现,使用Lombok简化PO对象,MapStruct处理对象转换。文章详细讲解了数据库设计、PO对象实现、DAO层构建、业务逻辑封装以及DTO/VO转换等核心环节,提供了一个完整的现代化Java对象模型实现案例。通过分层设计和对象转换,实现了业务逻辑与数据访问的解耦,提高了代码的可维护性和扩展性。
169 1
|
4月前
|
缓存 算法 NoSQL
校招 Java 面试高频常见知识点深度解析与实战案例详细分享
《2025校招Java面试核心指南》总结了Java技术栈的最新考点,涵盖基础语法、并发编程和云原生技术三大维度: 现代Java特性:重点解析Java 17密封类、Record类型及响应式Stream API,通过电商案例演示函数式数据处理 并发革命:对比传统线程池与Java 21虚拟线程,详解Reactor模式在秒杀系统中的应用及背压机制 云原生实践:提供Spring Boot容器化部署方案,分析Spring WebFlux响应式编程和Redis Cluster缓存策略。
94 1