Java SSM与SpringBoot面试题全面解析:从基础到源码
前言
在Java后端开发领域,SSM(Spring+SpringMVC+MyBatis)框架组合和SpringBoot是面试中的必考知识点。本文将系统整理这些框架在面试中常见的基础、中等和底层问题,帮助开发者全面准备面试。文章内容涵盖核心概念、使用技巧以及源码层面的解析,适合不同层次的开发者阅读参考。
一、Spring框架基础问题
1. Spring核心概念
问题:什么是IoC和DI?它们有什么区别?
IoC(Inversion of Control,控制反转)是一种设计原则,将对象的创建和管理权从应用程序代码转移到容器。DI(Dependency Injection,依赖注入)是IoC的一种实现方式,通过构造函数、setter方法或接口注入依赖对象。
区别:
-
IoC是设计思想,DI是实现方式
-
IoC强调控制权的反转,DI强调依赖关系的注入方式
问题:Spring中Bean的作用域有哪些?
-
singleton(默认):每个Spring容器中一个Bean定义对应一个实例
-
prototype:每次请求都创建新实例
-
request:每个HTTP请求创建一个实例
-
session:每个HTTP会话创建一个实例
-
application:每个ServletContext生命周期内一个实例
-
websocket:每个WebSocket会话一个实例
2. Spring AOP基础
问题:解释AOP及其核心概念
AOP(Aspect-Oriented Programming)面向切面编程,用于将横切关注点(如日志、事务)与业务逻辑分离。
核心概念:
-
Aspect(切面):跨多个类的模块化关注点
-
Join point(连接点):程序执行过程中的点,如方法执行
-
Advice(通知):在连接点执行的动作
-
Pointcut(切入点):匹配连接点的谓词
-
Target object(目标对象):被一个或多个切面通知的对象
-
Weaving(织入):将切面与其他应用类型或对象连接的过程
二、SpringMVC基础问题
1. 核心流程
问题:描述SpringMVC请求处理流程
-
用户发送请求到前端控制器DispatcherServlet
-
DispatcherServlet调用HandlerMapping确定请求对应的Controller
-
DispatcherServlet将请求分发给确定的Controller
-
Controller处理请求并返回ModelAndView对象
-
DispatcherServlet调用ViewResolver解析视图
-
View渲染数据并返回给客户端
2. 常用注解
问题:SpringMVC常用注解及其作用
-
@Controller:标识一个类作为控制器
-
@RequestMapping:映射URL到控制器方法
-
@RequestParam:绑定请求参数到方法参数
-
@PathVariable:绑定URL模板变量到方法参数
-
@ResponseBody:直接返回数据而非视图
-
@RestController:组合@Controller和@ResponseBody
-
@ModelAttribute:绑定方法参数或方法返回值到模型
-
@SessionAttributes:声明会话级模型属性
三、MyBatis基础问题
1. 核心概念
问题:#{}和${}的区别是什么?
-
#{}:预编译处理,MyBatis会生成PreparedStatement,能防止SQL注入
-
${}:字符串替换,直接拼接到SQL中,有SQL注入风险
问题:MyBatis的一级缓存和二级缓存
-
一级缓存:
-
SqlSession级别,默认开启
-
同一个SqlSession中执行相同查询会使用缓存
-
执行增删改或调用clearCache()会清空缓存
-
-
二级缓存:
-
Mapper级别,需要手动配置
-
多个SqlSession共享缓存
-
缓存数据会序列化到磁盘
-
四、SpringBoot基础问题
1. 核心特性
问题:SpringBoot自动配置原理
-
@SpringBootApplication组合了@EnableAutoConfiguration
-
@EnableAutoConfiguration导入AutoConfigurationImportSelector
-
AutoConfigurationImportSelector加载META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件
-
条件注解(@Conditional)决定哪些配置类生效
-
自动配置Bean被创建并加入应用上下文
问题:SpringBoot starter的作用
Starter是一组依赖描述符,可以一站式添加相关技术所需依赖。它简化了构建配置,开发者只需添加一个starter依赖,就能获得开发特定功能所需的所有依赖。
五、中等难度问题
1. Spring中等问题
问题:Spring事务传播行为有哪些?
-
REQUIRED(默认):当前有事务则加入,没有则新建
-
SUPPORTS:当前有事务则加入,没有则以非事务执行
-
MANDATORY:当前有事务则加入,没有则抛出异常
-
REQUIRES_NEW:新建事务,挂起当前事务
-
NOT_SUPPORTED:以非事务执行,挂起当前事务
-
NEVER:以非事务执行,当前有事务则抛出异常
-
NESTED:当前有事务则在嵌套事务内执行,没有则新建
问题:Spring如何解决循环依赖?
通过三级缓存解决setter注入的循环依赖:
-
singletonObjects:存放完全初始化好的Bean
-
earlySingletonObjects:存放原始Bean(未填充属性)
-
singletonFactories:存放Bean工厂
解决过程:
-
创建A时,将A的ObjectFactory放入三级缓存
-
A填充属性时需要B,开始创建B
-
B填充属性时需要A,从三级缓存获取A的ObjectFactory得到A(早期引用)
-
B完成初始化,A得到B完成初始化
2. SpringBoot中等问题
问题:SpringBoot外部化配置加载顺序
-
命令行参数
-
来自java:comp/env的JNDI属性
-
Java系统属性(System.getProperties())
-
操作系统环境变量
-
随机属性(带random.*)
-
应用外的application-{profile}.properties或.yml
-
应用内的application-{profile}.properties或.yml
-
应用外的application.properties或.yml
-
应用内的application.properties或.yml
-
@Configuration类上的@PropertySource
-
默认属性(SpringApplication.setDefaultProperties)
六、底层与源码问题
1. Spring底层问题
问题:Spring AOP动态代理实现方式及区别
-
JDK动态代理:
-
基于接口实现
-
通过Proxy.newProxyInstance()创建代理
-
代理类继承Proxy并实现目标接口
-
性能较好,但只能代理接口方法
-
-
CGLIB代理:
-
基于类实现
-
通过继承目标类生成子类
-
需要引入CGLIB库
-
可以代理类方法,但final方法不能被代理
-
创建代理较慢,但执行效率高
-
问题:Spring Bean生命周期
-
实例化Bean(通过构造函数或工厂方法)
-
填充属性(依赖注入)
-
调用BeanNameAware的setBeanName()
-
调用BeanFactoryAware的setBeanFactory()
-
调用ApplicationContextAware的setApplicationContext()
-
前置初始化(BeanPostProcessor的postProcessBeforeInitialization)
-
调用InitializingBean的afterPropertiesSet()
-
调用自定义init-method
-
后置初始化(BeanPostProcessor的postProcessAfterInitialization)
-
Bean准备就绪,可使用
-
容器关闭时调用DisposableBean的destroy()
-
调用自定义destroy-method
2. SpringBoot底层问题
问题:SpringBoot启动过程
-
创建SpringApplication实例
-
推断应用类型(Web/非Web)
-
加载META-INF/spring.factories中的ApplicationContextInitializer和ApplicationListener
-
推断主配置类
-
-
执行run方法
-
准备环境(Environment)
-
打印Banner
-
创建应用上下文(AnnotationConfigServletWebServerApplicationContext等)
-
准备上下文(加载配置源、注册Bean等)
-
刷新上下文(核心,调用AbstractApplicationContext.refresh())
-
执行Runners(ApplicationRunner和CommandLineRunner)
-
问题:SpringBoot内嵌Tomcat原理
-
通过spring-boot-starter-web引入Tomcat依赖
-
SpringBoot自动配置(TomcatServletWebServerFactoryAutoConfiguration)创建ServletWebServerFactory
-
WebServerFactoryCustomizerBeanPostProcessor后置处理器定制服务器
-
DispatcherServletAutoConfiguration注册DispatcherServlet
-
启动时通过ServletWebServerApplicationContext创建并启动Tomcat
七、综合实战问题
问题:如何设计一个RESTful API并考虑异常处理、安全性和性能?
-
RESTful设计:
-
合理使用HTTP方法(GET/POST/PUT/DELETE)
-
资源命名规范(/users/{id})
-
合适的状态码(200/201/400/404等)
-
HATEOAS支持
-
-
异常处理:
-
使用@ControllerAdvice全局异常处理
-
自定义异常和错误码
-
统一响应格式
-
-
安全性:
-
使用Spring Security
-
HTTPS加密
-
认证(JWT/OAuth2)
-
防CSRF/XSS/SQL注入
-
-
性能:
-
缓存(Spring Cache/Redis)
-
异步处理(@Async)
-
分页查询
-
压缩响应
-
连接池配置
-
结语
掌握SSM和SpringBoot框架不仅需要了解基本用法,还需要深入理解其设计思想和实现原理。面试前建议结合实际问题动手实践,阅读部分核心源码,这样在回答问题时才能游刃有余。本文整理的问题涵盖了大部分面试场景,但技术不断发展,建议持续关注框架的最新动态和最佳实践。