Spring
约 4218 字大约 14 分钟
2026-04-04
[TOC]
循环依赖
什么是循环依赖(常问)�?- Spring 面试�?- 面试�?- 程序员求职面试刷题神器
多个bean相互依赖
spring使用三级缓存解决
一级缓存:存储完全初始化的单例bean
二级缓存:存储未完全初始化,但已经实例化的bean,用于提前暴露对象,避免循环依赖
三级缓存:存储对象工厂,需要时可创建早期bean(支持aop创建代理对象�? 解决步骤�? 1.创建bean实例,并加入三级缓存
2.当bean依赖另一个未初始化的bean时,spring从三级缓存获取bean的工厂,生成该bean的代理对�? 3.代理对象存入二级缓存,解决循环依�? 4.所有依赖bean完全初始化后,bean将转移到一级缓�?
为什么要使用二级缓存�?
一级缓存也可以,主要能准确标识bean是实例化后的还是实例化后但是属性未完整填充�?
为什么要使用三级缓存�?
如果bean被代理了,因为被代理对象是在初始化后生成的,直接使用二级缓存不做处理会导致都是bean未代理的原始对象�?
spring IOC
什么是 Spring IOC�?- Spring 面试�?- 面试�?- 程序员求职面试刷题神器
通过依赖注入(通过构造器、setter、接口)实现,让对象的创建和依赖关系交给spring容器负责,不由对象自身控�?
spring bean
什么是 Spring Bean�?- Spring 面试�?- 面试�?- 程序员求职面试刷题神器
通过spring管理的bean对象�?
spring bean作用�?
Spring Bean 一共有几种作用域? - Spring 面试�?- 面试�?- 程序员求职面试刷题神器
singleton:单�? prototype:原型,多实�? request:每一个request请求中都有一个bean实例
session:每一个http seesion请求中都有一个bean实例
application:整个servletContext生命周期,只有一个bean实例
websocket:一个websocket生命周期,只有一个bean实例
spring bean的生命周�?
说下 Spring Bean 的生命周期? - Spring 面试�?- 面试�?- 程序员求职面试刷题神器
实例化:spring容器根据配置文件或注解实例化bean对象
属性注入:spring将依赖注入到bean实例
初始化前的扩展机制:实现了BeanNameAware等aware接口,则执行aware注入
初始化前:可通过BeanPostProcessor接口对bean进行额外处理
初始化:调用InitializingBean接口的afterPropertiesSet()方法或通过init-method属性指定的初始化方�? 初始化后:可通过BeanProcessor进行处理
使用bean:可被其它bean使用
销毁:调用DispsableBean接口的destory()方法或通过destory-method属性指定的销毁方法�? 
spring注入方式有几�?
Spring 一共有几种注入方式�?- Spring 面试�?- 面试�?- 程序员求职面试刷题神器
构造器
spring提倡使用构造函数注入,构造器注入返回给客户端时一定是完整�?
public class MyService {
private final MyDependency myDependency;
@Autowired
public MyService(MyDependency myDependency) {
this.myDependency = myDependency;
}
}setter
public class MyService {
private MyDependency myDependency;
@Autowired
public void setMyDependency(MyDependency myDependency) {
this.myDependency = myDependency;
}
}字段注入
@Autowired
public class MyService {
@Autowired
private MyDependency myDependency;
}方法注入
@Autowired
public class MyService {
public void performAction(@Autowired MyDependency myDependency) {
myDependency.doSomething();
}
}接口回调注入:定义的内建接口,如BeanFactoryAware,会进行BeanFactory的注�?
public interface Aware {
}
public interface BeanFactoryAware extends Aware {
void setBeanFactory(BeanFactory var1) throws BeansException;
}AOP
什么是 AOP�?- Spring 面试�?- 面试�?- 程序员求职面试刷题神器
面向切面编程,将与业务无关的横切关注点抽取处理,通过声明的方式动态地应用到业务方法上,而不是将这些代码直接嵌入业务逻辑中�? 切面(Aspect 观察的方向):横切关注点,需要观察什么东西,如日志、事�?
/**
* 请求响应日志 AOP
**/
@Aspect
@Component
@Slf4j
public class LogInterceptor {
/**
* 执行拦截
*/
@Around("execution(* site.xiaofei.apibackend.controller.*.*(..))")
public Object doInterceptor(ProceedingJoinPoint point) throws Throwable {**连接�?*(Join Point):程序执行中的一个特定位置,如方法调用、异常抛�? 通知(Advice 向某人提供观察结果):在连接点执行的操作,前置、后置、环绕(在方法执行前后都可执行)、异常(方法抛出异常后执行)、返回(方法成功返回后执行)
**切入�?*(Pointcut 切割点、划分点):定义的一组连接点的集合,在什么地方使用通知,限制范围;通常通过表达式来匹配方法或类
@Pointcut("execution(* com.example.service.*.*(..))")
public void serviceMethods() {}织入(Waeving 编织的过程、交织的过程):将切面应用到目标对象的过程。可在编译、类加载时、运行时进行织入
spring aop默认的动态代�?
Spring AOP默认用的是什么动态代理,两者的区别�?- Spring 面试�?- 面试�?- 程序员求职面试刷题神器
spring framework默认使用JDK动态代理,SpringBoot 2.x默认使用CGLIB动态代�?
JDK动态代�?
基于接口实现,通过反射机制,由Proxy类和InvocationHandler接口实现。代理类在运行时生成,并调用InvocationHandler的invoke方法
CGLIB动态代�?
基于类继承,通过继承目标类创建代理类,并重写插入切面逻辑。通过字节码技术生成目标类的子类,来实现对目标方法的代�? 不能代理final类的final方法
Enhancer类创建代理对�? MethodInterceptor接口的intercept方法
spring中的ApplicationContext
Spring 中的 ApplicationContext 是什么? - Spring 面试�?- 面试�?- 程序员求职面试刷题神器
多个底层接口组合后的接口,包�?大功能:
- 核心容器 BeanFactory
- 国际�?MessageSource
- 资源获取 ResourceLoader
- 环境信息 EnvironmentCapable
- 事件发布 ApplicationEventPublisher

spring拦截�?
能说�?Spring 拦截链的实现吗? - Spring 面试�?- 面试�?- 程序员求职面试刷题神器
指一系列拦截器(AOP切面、过滤器、拦截器)依次作用于请求或方法调用,实现横切关注点的处理
HandlerInterceptor(MVC拦截器):拦截http请求并进行预处理和后处理。实现HandlerInterceptor接口的preHandle、postHandle、afterCompletion,可在请求到达控制器之前、之后以及请求完成后进行处理
Filter(过滤器):基于servlet api的过滤器,可对请求进行初步筛选。Filter接口的doFilter方法拦截请求
AOP拦截链(切面):定义切面可实现方法前后的处理。@Before、@After、@Around等注解用于控制拦截的执行顺序
Spring MVC
说下�?Spring MVC 的理解? - Spring 面试�?- 面试�?- 程序员求职面试刷题神器
Spring MVC 具体的工作原理? - Spring 面试�?- 面试�?- 程序员求职面试刷题神器
请求处理流程:模型层(Model)、视图层(View)、控制层(Controller),提供一种松耦合的方式将用户请求、业务逻辑和视图渲染分�? 基于servlet api构建,核心是DispatcherServlet前端控制器。通过注解、配置方式,将http请求映射到控制器方法,由控制器处理请求逻辑并将数据返回给视图层进行渲染�? 主要功能:请求映射、数据绑定、视图解析、表单处理、异常处�? 
- DispatcherServlet接受请求并调用HandlerMapping查找对应的控制器
- HandlerAdapter调用具体的Controller方法处理请求
- Controller返回ModelAndView,包含视图名和模型数�?4. ViewResolver解析视图并渲染结�?5. DispatcherServlet将处理结果返回给客户�?
spring 事务隔离级别
- DEFAULT:默认,使用底层数据库的默认隔离级别,如果数据库无特殊配置,通常默认为READ_COMMITTED
- READ_UNCOMMITTED:读未提交,允许事务读取尚未提交的数据,可能会导致脏读、不可重复读、幻�?3. READ_COMMITTED:读已提交,只允许读取已经提交的数据,避免脏读,可能出现不可重复读、幻�?4. REPEATABLE_READ:确保在同一事务内的多次读取结果一致,避免脏读、不可重复读,可能出现幻�?5. SERIALIZABLE:通过强制事务按顺序执行,完全避免脏读、不可重复读、幻�?
spring 事务传播行为
Spring 有哪几种事务传播行为? - Spring 面试�?- 面试�?- 程序员求职面试刷题神器
required(默认行为):方法会加入现有事务,如果没有就创建一个新事务
requires_new:强制启动一个新事务,无论当前是否存在事务。如果有就挂起,直到新事务完�? nested:如果当前存在事务,会在当前事务中创建一个嵌套事务,子事务可以独立回滚而不影响主事�? supports:支持事务,不强制要求。如果有事务,加入当前事务,没有就以非事务方式执�? mandatory:方法必须在已有事务中运行,如果当前没有事务就抛异常
not_supported:不支持事务,如果存在事务,将当前事务挂起,并以非事务方式执�? never:不允许在事务中运行,如果当前没有事务就抛异�?
spring 通知类型
Spring 通知有哪些类型? - Spring 面试�?- 面试�?- 程序员求职面试刷题神器
前置通知
后置通知
后置异常通知:在目标方法抛出异常后执�? 后置最终通知:无论目标方法如何结束(正确返回或抛出异常),都会执�? 环绕通知
@Qualifier注解
@Qualifier 注解有什么作�?- Spring 面试�?- 面试�?- 程序员求职面试刷题神器
Spring中的@Primary注解的作用是什么? - Spring 面试�?- 面试�?- 程序员求职面试刷题神器
在依赖注入时消除歧义。当一个类型同多个实现类时,可以指定需要注入的bean
@Primary首选Bean,@Qualifier会覆盖@Primary
@Bean和@Component
@Bean和@Component有什么区别? - Spring 面试�?- 面试�?- 程序员求职面试刷题神器
都是定义spring容器中bean的注�?
| 特�? | @Bean | @Component |
|---|---|---|
| 使用位置 | 方法级别(@Configuration�? | 类级�? |
| 扫描机制 | 不支持自动扫描,需要手动注�? | 支持自动扫描,通过@Component自动发现 |
| 主要用�? | 配置第三方库或复杂对�? | 自动发现并注册类 |
| 常见场景 | 手动配置复杂对象、第三方库类(Redis、Mybatis,Api文档�? | 自定义服务(AOP)、DAO层、控制器等类的自动注�? |
| 灵活�? | 灵活、适合复杂初始�? | 自定化更强、适合类的简单注�? |
@Component与@Controller、@Repository、@Service
@Component、@Controller、@Repository和@Service 的区别? - Spring 面试�?- 面试�?- 程序员求职面试刷题神器
本质没区别,其它3个都是@Component的衍生注解。都用@Component都可�? @Component:通用注解,用于将任意类注册为spring容器中的bean
@Controller:专门用于spring MVC中的控制器层注解。用于处理http请求,并将结果返回给客户�? @Repository:标识业务逻辑层的类,主要用于编写服务�? @Service:用于数据访问层(DAO),与数据库交互
spring事务什么情况下会失�?
Spring 事务在什么情况下会失效? - Spring 面试�?- 面试�?- 程序员求职面试刷题神器
失效的情况都是用了声明式事务(@Transactional�?
- rollbackFor没设置对
- propagation传播机制配置错误
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
public void addUserAndAddress(User user,Address address) throws Exception {
userMapper.save(user);
addAddress(address);
}
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
public void addAddress(Address address) {
addressMapper.save(address);
}异常被捕获,没抛出异�?
同一个类中方法调用,事务基于动态代理,同类的方法调用不会走代理方法
@Transactional应用在非public方法
@Transactional应用在final和static方式,aop(springBoot2.x默认是cglib,Spring默认是jdk)默认是CGLIB代理,无法对final方法子类化。static是静态方法,属于类,不属于实例对象,无法被代�?
多线程环境,@Transactional基于ThreadLocal存储上下文,多线程情况下每个线程都有自己的上下文
数据库引擎不支持事务(Mysql MyISAM�?
@Value
Spring中的@Value注解的作用是什么? - Spring 面试�?- 面试�?- 程序员求职面试刷题神器
注入外部配置值(属性文件、环境变量、系统属性)到spring管理的bean�?
@Profile("dev")
Spring 中的 @Profile 注解的作用是什么? - Spring 面试�?- 面试�?- 程序员求职面试刷题神器
定义配置文件所属环�?
@RequestBody和@ResponseBody
Spring 中的 @RequestBody �?@ResponseBody 注解的作用是什么? - Spring 面试�?- 面试�?- 程序员求职面试刷题神器
@RequestBody:将http请求体中的数据绑定到方法参数�? @ResponseBody:将控制器方法返回的结果直接写入http响应体中
@PathVariable
Spring 中的 @PathVariable 注解的作用是什么? - Spring 面试�?- 面试�?- 程序员求职面试刷题神器
从url模板中提取变量值的注解
@GetMapping("/users/{userId}")
public ResponseEntity<User> getUserById(@PathVariable("userId") String userId) {
User user = userService.getUserById(userId);
if (user != null) {
return ResponseEntity.ok(user);
} else {
return ResponseEntity.notFound().build();
}
}@RequestParam:从请求查询的参数中提取数据�?users?id=1
@ModelAttribute
Spring中的 @ModelAttribute 注解的作用是什么? - Spring 面试�?- 面试�?- 程序员求职面试刷题神器
用于方法参数:表示将请求中的参数绑定到某个对象上
用于方法级别:表示在执行任何控制器方法之前,先运行带有该注解的方�?
@ExceptionHandler
Spring 中的 @ExceptionHandler 注解的作用是什么? - Spring 面试�?- 面试�?- 程序员求职面试刷题神器
处理控制器中抛出的异常,通常和@RestControllerAdvice一起使用,表示标识全局异常处理�? 优先级是:局部控制器@ExceptionHandler > 全局@RestControllerAdvice
@ResponseStatus
Spring 中的 @ResponseStatus 注解的作用是什么? - Spring 面试�?- 面试�?- 程序员求职面试刷题神器
将指定的状态码和原因设置到响应的HTTP状态中
@ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "未找�?)
public class UserNotFoundException extends RuntimeException {
// 异常类实�?}@RequestHeader和@CookValue
Spring 中的 @RequestHeader �?@CookieValue 注解的作用是什么? - Spring 面试�?- 面试�?- 程序员求职面试刷题神器
@RequestHeader:提取HTTP请求头中的�? @CookValue:提取HTTP请求的Cookie的�?
@SessionAttribute
Spring 中的 @SessionAttribute 注解的作用是什么? - Spring 面试�?- 面试�?- 程序员求职面试刷题神器
从当前HTTP会话(Session)中获取属性�?
@Validated和@Valid
Spring 中的 @Validated �?@Valid 注解有什么区别? - Spring 面试�?- 面试�?- 程序员求职面试刷题神器
@Validated:用于方法参数和类字段上,验证参数是否合�? @Valid:支持分组验�?
@Conditional
Spring 中的 @Conditional 注解的作用是什么? - Spring 面试�?- 面试�?- 程序员求职面试刷题神器
有条件的装配Bean,实现Condition接口实现matches方法
@Lazy
Spring 中的 @Lazy 注解的作用是什么? - Spring 面试�?- 面试�?- 程序员求职面试刷题神器
不在spring容器启动时去加载bean,而是需要的时候再去加载Bean
和@Component,@Bean一起使�? 和@Autowrite一起使用,使用构造函数注入可解决循环依赖
@PropertySource
Spring 中的 @PropertySource 注解的作用是什么? - Spring 面试�?- 面试�?- 程序员求职面试刷题神器
加载.properties属性文件,结合@Value和Environment
spring MVC拦截�?
Spring MVC 中的拦截器是什么?如何定义一个拦截器�?- Spring 面试�?- 面试�?- 程序员求职面试刷题神器
在请求处理流程的不同阶段拦截HTTP请求和响应,并对其进行预处理或后处理。如权限验证、日志记录、性能监控
实现HandlerInterceptor接口,重写preHandle、postHandle(控制器执行之后视图渲染之前)、afterCompletion
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 在请求到达控制器之前处理
System.out.println("Pre Handle method is Calling");
return true; // 返回 true 继续处理请求,返�?false 阻止请求继续
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// 在控制器执行之后,视图渲染之前处�? System.out.println("Post Handle method is Calling");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception exception) throws Exception {
// 在整个请求完成之后回�? System.out.println("Request and Response is completed");
}
}通过WebMvcConfigurer或xml配置来注册拦截器,并指定拦截路径
@Configuration
public class WebConfig implements WebMvcConfigurer {
//注册拦截�? @Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor())
.addPathPatterns("/api/**") // 拦截 /api/** 下的所有请�? .excludePathPatterns("/api/login", "/api/register"); // 排除特定路径
}
}过滤器:servlet的一部分,拦截所有HTTP请求,不依赖spring
拦截器:依赖spring mvc