Skip to content

SpringBoot2核心功能面试题库 ​

生成时间:2026-05-23 16:20


本轮 SpringBoot2核心功能面试题库(带答案) ​

【面试题】1. SpringBoot自动配置原理是什么?@EnableAutoConfiguration是如何工作的? ​

【标准答案】 SpringBoot自动配置原理核心是"约定优于配置"。@EnableAutoConfiguration通过@Import导入AutoConfigurationImportSelector,这个类会扫描类路径下的META-INF/spring.factories文件(SpringBoot 2.7后也支持META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports),加载所有EnableAutoConfiguration配置类的全限定名。

每个自动配置类上有大量条件注解,比如@ConditionalOnClass判断类路径是否存在某类,@ConditionalOnMissingBean判断容器是否已有Bean,@ConditionalOnProperty判断配置项。只有所有条件满足,自动配置类才会生效,向容器注入默认Bean。

比如我们引入spring-boot-starter-web,类路径有DispatcherServlet类,WebMvcAutoConfiguration条件满足,就自动配置好视图解析器、静态资源处理等。我们只需要覆盖默认配置或注入同名Bean就能替换默认实现。

【面试题】2. application.yml和application.properties加载顺序是什么?多环境Profile如何使用? ​

【标准答案】 配置文件加载顺序按优先级从高到低:命令行参数 > 操作系统环境变量 > application-{profile}.properties/yml > application.properties/yml > jar包内部的application.properties/yml。同一目录下,.properties优先级高于.yml。

Profile多环境用法:第一步,配置文件命名application-dev.yml、application-prod.yml;第二步,激活方式有四种:启动参数spring.profiles.active=dev、环境变量SPRING_PROFILES_ACTIVE=dev、配置文件中写spring.profiles.active=dev、代码中SpringApplication.setAdditionalProfiles。第三步,可以用@Profile("dev")注解在Bean上,只有对应环境激活时才注入。还可以在配置文件中用---分隔多个Profile配置块,用spring.config.activate.on-profile指定。

实际项目建议:开发环境dev、测试环境test、生产环境prod,敏感配置用环境变量或配置中心,不要写死在配置文件。

【面试题】3. BeanFactory和ApplicationContext有什么区别?IoC容器启动流程是怎样的? ​

【标准答案】 BeanFactory是Spring最底层容器,提供基础的依赖注入功能,懒加载Bean,适合资源受限环境。ApplicationContext继承BeanFactory,增加了国际化、事件发布、资源加载、AOP支持等企业级功能,默认预加载所有单例Bean。

IoC容器启动流程分五步:第一步,SpringApplication.run()创建ApplicationContext;第二步,prepareEnvironment准备环境配置,加载application.yml等配置;第三步,refresh()核心流程:先obtainFreshBeanFactory获取BeanFactory,然后invokeBeanFactoryPostProcessors执行BeanDefinitionRegistryPostProcessor扫描解析配置类,注册BeanDefinition;第四步,finishBeanFactoryInitialization实例化所有非懒加载单例Bean,经历实例化→属性填充→初始化→销毁注册的完整生命周期;第五步,publishEvent发布ContextRefreshedEvent事件,容器就绪。

关键点:BeanPostProcessor在Bean初始化前后拦截增强,是AOP、事务等功能的基石。

【面试题】4. @Import注解有哪三种用法?@Import和@ComponentScan有什么区别? ​

【标准答案】 @Import三种用法:第一种,直接导入普通类@Import(UserService.class),把类注册为Bean;第二种,导入ImportSelector实现类,selectImports()返回需要导入的类全限定名数组,EnableAutoConfiguration就是这种方式;第三种,导入ImportBeanDefinitionRegistrar实现类,通过BeanDefinitionRegistry手动注册BeanDefinition,MyBatis的@MapperScan就是用这种方式批量注册Mapper接口代理Bean。

@ComponentScan是包扫描,扫描指定包及其子包下所有@Component/@Service/@Repository/@Controller注解类,自动注册Bean。@Import是精确导入,不依赖注解标记,适合导入第三方库的类或按条件动态导入。

实战中,自定义Starter用@Import+ImportSelector,业务代码用@ComponentScan,各司其职。

【面试题】5. Spring AOP的代理方式是什么?JDK动态代理和CGLIB有什么区别? ​

【标准答案】 Spring AOP默认代理策略:如果目标类实现了接口,用JDK动态代理;如果没实现接口,用CGLIB代理。可以通过spring.aop.proxy-target-class=true强制全部使用CGLIB,SpringBoot 2.x默认为true。

JDK动态代理基于接口,通过反射生成代理类,代理类实现相同接口,InvocationHandler拦截方法调用。CGLIB基于继承,生成目标类的子类,覆盖方法并拦截,MethodInterceptor处理增强。JDK代理生成类速度快,但方法调用时反射慢;CGLIB生成类慢,但方法调用时性能好。

限制:JDK代理只能代理接口方法,类自身的public方法无法代理;CGLIB无法代理final类和final方法。实际开发中,SpringBoot默认CGLIB,避免接口方法代理不全的问题。

【面试题】6. Spring事件机制怎么用?ApplicationListener和@EventListener有什么区别? ​

【标准答案】 Spring事件机制三要素:事件类继承ApplicationEvent、发布者注入ApplicationEventPublisher调用publishEvent()、监听者实现ApplicationListener接口或用@EventListener注解。

用法示例:自定义OrderCreatedEvent extends ApplicationEvent,包含订单ID;OrderService发布事件applicationEventPublisher.publishEvent(new OrderCreatedEvent(orderId));NotificationService监听@EventListener public void onOrderCreated(OrderCreatedEvent event)。

两种方式区别:ApplicationListener是接口实现,可以声明监听特定事件类型,泛型指定;@EventListener是注解方式,更简洁,支持条件过滤@EventListener(condition = "event.orderId > 1000"),支持异步@EventListener @Async。内置事件:ContextRefreshedEvent容器刷新完成、ContextClosedEvent容器关闭、ApplicationReadyEvent应用就绪。

注意:默认同步执行,事件监听器抛异常会影响发布者;用@Async异步执行解耦,但要配置线程池。

【面试题】7. SpringBoot嵌入式容器如何切换和调优?Tomcat、Undertow、Jetty怎么选? ​

【标准答案】 切换容器:默认Tomcat,要换成Undertow,排除spring-boot-starter-tomcat依赖,引入spring-boot-starter-undertow。Jetty同理。

调优配置:server.port端口,server.tomcat.max-threads最大工作线程数,server.tomcat.accept-count等待队列长度,server.tomcat.max-connections最大连接数,server.connection-timeout连接超时。Undertow用server.undertow.threads.io/io线程数,server.undertow.threads.worker工作线程数。

选型:Tomcat成熟稳定,生态最完善,默认首选;Undertow非阻塞IO,高并发场景性能更优,内存占用低;Jetty轻量级,适合嵌入式场景,长连接性能好。一般业务系统用Tomcat足够,网关、高并发API用Undertow。

实际调优建议:压测找到瓶颈,不要盲目调大线程数;连接数=QPS×平均响应时间,留20%余量;配合HikariCP连接池、Redis缓存一起优化,不要只盯容器。

【面试题】8. SpringBoot事务管理@Transactional怎么用?传播行为和隔离级别有哪些? ​

【标准答案】 @Transactional用法:加在类上,类所有public方法都有事务;加在方法上,只该方法有事务;属性配置:value指定事务管理器,propagation传播行为,isolation隔离级别,timeout超时秒数,readOnly只读优化,rollbackFor/noRollbackFor指定异常回滚规则。

传播行为七种:REQUIRED默认,有事务就加入,没有就新建;SUPPORTS有就加入,没有就非事务执行;MANDATORY必须已有事务,否则抛异常;REQUIRES_NEW新建事务,挂起当前;NOT_SUPPORTED非事务执行,挂起当前;NEVER非事务执行,有事务抛异常;NESTED嵌套事务,外层回滚内层也回滚。

隔离级别五种:DEFAULT用数据库默认;READ_UNCOMMITTED读未提交,脏读;READ_COMMITTED读已提交,不可重复读;REPEATABLE_READ可重复读,幻读;SERIALIZABLE串行化,性能最差。

实战注意:事务失效场景——方法非public、自调用绕过代理、异常被catch吞掉、数据库引擎不支持事务。排查用日志打印事务状态,或断点看代理类。

【面试题】9. @Cacheable缓存注解怎么用?如何集成Redis做缓存? ​

【标准答案】 @Cacheable用法:在方法上加@Cacheable(value="user", key="#id"),第一次调用执行方法并存缓存,后续直接返回缓存。value指定缓存名称,key用SpEL表达式指定缓存键。@CachePut每次都执行方法并更新缓存。@CacheEvict删除缓存,allEntries=true清空整个缓存。

集成Redis步骤:第一步,引入spring-boot-starter-data-redis依赖;第二步,配置spring.redis.host、port、password、database;第三步,主类加@EnableCaching开启缓存;第四步,配置RedisCacheManager自定义序列化、过期时间。SpringBoot 2.x默认用Lettuce客户端,比Jedis性能好,连接池用CommonsPool。

进阶配置:@Cacheable(cacheNames="user", key="#id", unless="#result == null")结果为null不缓存;@CacheConfig(cacheNames="user")类级别统一缓存名;自定义CacheResolver实现多级缓存,本地Caffeine+远程Redis。注意:缓存穿透用缓存null值或布隆过滤器,缓存击穿用分布式锁,缓存雪崩用随机过期时间。

【面试题】10. SpringBoot打包部署怎么做?分层JAR和Docker镜像怎么优化? ​

【标准答案】 打包方式:spring-boot-maven-plugin插件执行mvn clean package,生成可执行JAR,包含BOOT-INF/classes业务代码、BOOT-INF/lib依赖JAR、META-INF启动信息、org.springframework.boot.loader启动器。

分层JAR优化:SpringBoot 2.3+支持分层,配置spring-boot-maven-plugin的layers.enabled=true,生成四个层级:dependencies依赖、spring-boot-loader启动器、snapshot-dependencies快照依赖、application业务代码。Dockerfile分层构建,依赖层不变就复用缓存,加快构建速度。

Docker镜像最佳实践:第一步,多阶段构建,maven构建层+运行层;第二步,基础镜像用eclipse-temurin:17-jre-alpine,体积小;第三步,分层COPY,依赖先复制,应用后复制;第四步,JVM参数-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0,容器内内存感知。

生产调优:启动脚本加-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/logs/dump.hprof;优雅停机server.shutdown=graceful,等待请求处理完;健康检查用Actuator的/health端点配合K8s livenessProbe/readinessProbe。


题目统计: 共10道,覆盖自动配置、配置管理、Bean生命周期、注解驱动、AOP、事件机制、Web开发、事务管理、缓存、打包部署等核心知识点。