Java面试八股Spring篇(4500字)
Spring Boot、Spring MVC 和 Spring 有什么区别?
-
Spring
:是核心框架,提供依赖注入(IoC
)和面向切面编程(AOP
)的基础功能,是其他模块的基石。 -
Spring MVC
:是基于Spring
的Web
框架,专注于MVC
模式(模型-视图-控制器),用于处理HTTP
请求和响应,支持URL
路由、模板引擎等Web
开发功能。 -
Spring Boot
:是Spring
的快速开发工具,通过自动配置(如内嵌 Tomcat)和 Starter 依赖简化了项目搭建
BeanFactory
和 ApplicationContex
有什么区别?
-
BeanFactory
:Spring
的基础容器,提供基本的依赖注入功能,采用延迟加载。 -
ApplicationContext
:BeanFactory
的子接口,是更高级的容器,如国际化支持、事件发布、AOP
等,采用预加载策略。
SpringMVC 怎么样设定重定向和转发的?
-
转发:返回视图名前加
forward:
,如return "forward:/path"
。 -
重定向:返回视图名前加
redirect:
,如return "redirect:/path"
。
当一个方法向AJAX
返回特殊对象,比如Object
,List
等,需要做什么处理?
- 使用
@ResponseBody
注解将返回值序列化为 JSON/XML,并配合@RestController
或配置消息转换器(如 Jackson)。示例:
SpringMvc 用什么对象从后台向前台传递数据的?
- 可以使用
Model
、ModelMap
或ModelAndView
对象来传递数据
AOP(面向切面编程)
-
切入点:需要织入逻辑(增强功能)的方法。
-
通知:织入的具体逻辑(增强的代码逻辑),如前置、后置、环绕通知。
-
切面:绑定通知与切入点的关系。
-
作用:统一处理日志、性能监控、事务管理,减少代码冗余,提升可维护性。
Spring AOP和IOC是什么?使用场景有哪些?Spring 事务,事务的属性,数据库隔离级别
-
AOP
是面向切面编程,指在不影响原有代码的基础上对代码进行功能增强,使用场景有日志记录和权限控制,性能监控等 -
IOC
是控制反转, 指的是对象创建、依赖管理的控制权程序本身转移到IOC
容器 -
容器的作用是创建
bean
实例并管理bean
的生命周期,并实现依赖注入 -
DI
依赖注入是实现IOC
的一种方式, 就是将依赖对象注入到目标对象中(给对象传递需要使用的其他对象),实现解耦合 -
DI
的实现方式有setter
注入,构造器注入,字段注入(使用@Autowired
注解)
//Setter 注入
public class UserService {private UserRepository userRepository;public void setUserRepository(UserRepository userRepository) {this.userRepository = userRepository;}
}
//构造器注入
public class UserService {private final UserRepository userRepository;public UserService(UserRepository userRepository) {this.userRepository = userRepository;}
}
//字段注入
public class UserService {@Autowiredprivate UserRepository userRepository;
}
DI
的使用场景有 : 控制对象生命周期,自动注入依赖对象(如@Autowired
), 配置管理(如使用application.yml
或@Value
等)
Spring事务管理
-
Spring
事务保证一组数据库操作要么全部成功,要么全部失败(原子性),避免数据不一致,分为声明式事务和编程式事务,声明式事务通过注解,如@Transactional
实现。编程式事务通过TransactionTemplate
或PlatformTransactionManager
手动控制。 -
事务的属性:
propagation
(传播行为):如REQUIRED
、REQUIRES_NEW
等
isolation
(隔离级别):见下文
timeout
:超时时间
readOnly
:只读事务(可优化性能)
rollbackFor
:哪些异常触发回滚 -
数据库隔离级别:
隔离级别 | 说明 | 可避免问题 |
---|---|---|
READ UNCOMMITTED | 读未提交 | 无法避免任何问题 |
READ COMMITTED | 读已提交(Oracle 默认) | 避免脏读 |
REPEATABLE READ | 可重复读(MySQL 默认) | 避免脏读、不可重复读 |
SERIALIZABLE | 串行化(最高级别) | 避免所有并发问题 |
什么是Spring的bean?
Spring
的Bean
,简单来说就是由Spring
容器“产生”并“管理”的Java
对象,bean
的创建、配置以及生命周期都由容器负责
Bean 的生命周期
-
bean
实例化:通过反射或工厂方法创建Bean
实例。 -
属性赋值:为
Bean
设置相关属性和依赖 -
初始化:完成
Bean
的初始化。 -
使用:
Bean
处于活动状态,可以在应用程序中使用。 -
销毁:容器关闭时调用销毁方法释放资源
Spring Bean 的配置方式主要有三种:
-
XML
配置:通过<beans>
和<bean>
标签声明Bean
定义。 -
基于注解的配置:利用类级别或成员级别注解(如
@Component
、@Service
、@Controller
、@Repository
)自动扫描并注册Bean
。 -
使用
@Configuration
配置类结合@Bean
注解注册Bean
。
IoC接口
![[Pasted image 20250513142459.png]]
延迟加载: 真正需要bean
时才创建bean
实例
Spring 如何解决循环依赖?
Spring
通过三级缓存
来解决循环依赖问题.
Spring
创建Bean
的流程:
-
先去
一级缓存
中获取,存在就返回。 -
如果不存在或者对象正在创建中,于是去
二级缓存
中获取。 -
如果还没有获取到,就去
三级缓存
中获取,通过执行ObjectFactory
的getObject()
就可以获取该对象,获取成功之后,从三级缓存
移除,并将该对象加入到二级缓存
中。
Spring MVC 的核心组件有哪些?
DispatcherServlet
:核心的中央处理器,负责接收请求、分发,并给予客户端响应。HandlerMapping
:处理器映射器,根据 URL 去匹配查找能处理的Handler
,并会将请求涉及到的拦截器和Handler
一起封装。HandlerAdapter
:处理器适配器,根据HandlerMapping
找到的Handler
,适配执行对应的Handler
;Handler
:请求处理器,处理实际请求的处理器。ViewResolver
:视图解析器,根据Handler
返回的逻辑视图 / 视图,解析并渲染真正的视图,并传递给DispatcherServlet
响应客户端
单点登录
-
身份提供者:集中式认证中心,用户首次登录后颁发
JWT Token
。 -
服务提供者:各应用接收并校验
Token
,有效则允许访问。 -
Token
传递:可通过HTTP Header
、Cookie
或重定向参数传递
cookie和session的区别
- 存储位置:
Cookie
在客户端(浏览器),Session
在服务器端。 Cookie
占用内存更小,容易暴露,Session
存储容量更大,更安全。
get和post请求的区别
get
请求参数写在url
后面,暴露在地址栏,而且url
有长度限制post
请求的参数写在请求体中,没有长度限制- 传输敏感数据时推荐使用
post
HTTP请求状态码
-
200 OK
:请求已成功。 -
301 Moved Permanently
:资源已被永久移动到新 URI,以后应使用新的 URI。 -
302 Found
:资源临时位于不同 URI,应继续使用原 URI 发起请求。 -
400 Bad Request
:请求格式错误。 -
401 Unauthorized
:请求需要身份验证。 -
403 Forbidden
:认证成功但权限不足。 -
404 Not Found
:请求的资源不存在。 -
405 Method Not Allowed
:请求方法不允许。 -
500 Internal Server Error
:服务器内部错误 -
502 Bad Gateway
:网关/代理错误,上游服务器无响应
过滤器和拦截器的区别
Filter(过滤器)
属于Servlet
层,Interceptor(拦截器)
属于Spring MVC
层Filter
可以拦截所有请求,包括静态资源。Interceptor
只能拦截DispatcherServlet
处理的请求(即控制器 Controller 相关请求)。
HTTP方法
请求类型 | 描述 |
---|---|
GET | 获取资源 |
POST | 创建新资源 |
PUT | 更新现有资源 |
DELETE | 删除资源 |
PATCH | 部分更新现有资源 |
@Component 和 @Bean 的区别是什么?
-
@Component
于类,@Bean
用于方法。 -
@Component
标注的类不用编写配置,@Bean
定义的Bean
需要在配置类中定义方法来返回对象实例。 -
@Bean
注解比@Component
注解的自定义性更强,而且很多地方我们只能通过@Bean
注解来注册bean
。比如当我们引用第三方库中的类需要装配到Spring
容器时,则只能通过@Bean
来实现。
@Autowired和@Resource注解的区别
对比维度 | @Autowired | @Resource(JSR - 250) |
---|---|---|
自动装配机制 | 基于基于类型进行自动装配。如果多个匹配,需结合 @Qualifier 按名称选择。 | 优先按名称装配(指定 name 属性),若找不到对应名称的Bean ,则按类型装配。 |
注入位置 | 可用于字段、构造函数、方法参数等多种场景。 | 常用于字段和方法参数的注入。 |
灵活性 | 配合@Qualifier 可灵活指定注入的 Bean,适合复杂场景。 | 主要通过名称查找,灵活性稍逊于 @Autowired 和 @Qualifier 的组合。 |
@Controller和@RestController注解的区别
-
@Controller
返回的是视图名称,需要结合模型和视图解析器进行页面渲染。 -
@RestController
将方法返回值直接填入 HTTP 响应体中,返回的通常是JSON
。
将一个类声明为 Bean 的注解有哪些?
@Component
:通用注解,可标注任意类为Spring
组件。如果一个Bean
不知道属于哪个层,可以使用@Component
注解标注。@Repository
: 对应持久层即Dao
层,主要用于数据库相关操作。@Service
: 对应服务层,主要涉及一些复杂的逻辑,需要用到Dao
层。@Controller
: 对应Spring MVC
控制层,主要用于接受用户请求并调用Service
层返回数据给前端页面