Spring 面试点(八股)
基础部分
- Spring是什么?
Spring是Java后端开发框架,核心是管理Java对象,核心特性为控制反转(IoC)和面向切面编程(AOP),能降低对象依赖耦合,提供事务管理、日志等通用功能,生态涵盖Spring Boot、Spring MVC等。 - Spring有哪些模块?
核心模块包括Core(IoC基础)、Beans(Bean管理)、Context(企业级功能如国际化)、AOP(切面编程)、Web/WebMVC(Web开发)、Data Access(数据库操作)、Test(测试支持)等。 - Spring有哪些常用注解?
- Bean管理:
@Component
、@Service
、@Controller
、@Repository
- 依赖注入:
@Autowired
、@Resource
、@Qualifier
- 配置:
@Configuration
、@Bean
、@Value
- Web:
@RestController
、@RequestMapping
、@GetMapping
- AOP:
@Aspect
、@Pointcut
、@Before
- 事务:
@Transactional
- Bean管理:
- Spring用了哪些设计模式?
工厂模式(BeanFactory创建Bean)、单例模式(默认Bean为单例)、代理模式(AOP动态代理)、模板方法模式(JdbcTemplate)、观察者模式(事件机制)、适配器模式等。 - Spring容器和Web容器的区别?
- Spring容器:IoC容器,管理Bean生命周期和依赖,专注业务对象管理。
- Web容器(如Tomcat):处理HTTP请求,管理Servlet生命周期,负责网络通信。
- 关系:Web容器接收请求后,通过DispatcherServlet调用Spring容器中的Bean处理业务。
IoC部分
- 什么是IoC?
控制反转(IoC)指对象创建和依赖管理的控制权由业务代码转移到Spring容器。依赖注入(DI)是其实现方式,如@Autowired
注入依赖,降低代码耦合。 - IoC的实现机制?
- 加载Bean定义:扫描注解类,封装为BeanDefinition。
- 准备Bean工厂:DefaultListableBeanFactory负责Bean创建。
- 实例化与初始化:反射创建Bean,注入依赖,执行初始化方法。
- 缓存管理:通过三级缓存解决循环依赖。
- BeanFactory和ApplicationContext的区别?
- BeanFactory:基础IoC功能,懒加载(获取时创建Bean),仅提供
getBean()
等核心方法。 - ApplicationContext:继承BeanFactory,提供国际化、事件发布等企业级功能,预加载单例Bean。
- BeanFactory:基础IoC功能,懒加载(获取时创建Bean),仅提供
- 项目启动时Spring的IoC会做什么?
- 扫描并注册Bean:根据
@ComponentScan
扫描注解类,生成BeanDefinition。 - 实例化与注入:按依赖顺序创建Bean,注入依赖,执行初始化方法。
- 处理循环依赖:通过三级缓存确保依赖正确注入。
- 扫描并注册Bean:根据
- 如何理解Bean?
Bean是Spring容器管理的Java对象,由容器负责创建、注入依赖和销毁,与普通对象的区别在于生命周期由容器管控。常用@Component
、@Bean
定义。 - Bean的生命周期?
- 实例化:反射调用构造方法创建对象。
- 属性注入:注入
@Autowired
等依赖。 - 初始化:执行
@PostConstruct
、InitializingBean.afterPropertiesSet()
、init-method
。 - 使用:被其他Bean调用。
- 销毁:执行
@PreDestroy
、DisposableBean.destroy()
、destroy-method
。
- 为什么IDEA不推荐使用@Autowired?
- 字段注入不利于测试,需反射或容器才能注入依赖。
- 隐藏循环依赖问题,构造方法注入可在启动时发现。
- 无法用
final
修饰字段,构造方法注入更推荐。
- @Autowired的实现原理?
基于BeanPostProcessor,扫描Bean的字段、方法,封装注入元数据,通过反射按类型查找匹配Bean并注入(如字段注入调用Field.set()
)。 - 什么是自动装配?
Spring自动完成Bean依赖注入,无需手动指定。类型包括按名称(byName)、按类型(byType)、构造器注入等,注解时代常用@Autowired
(按类型)和@Resource
(按名称)。 - Bean的作用域有哪些?
singleton
:默认,容器中唯一实例。prototype
:每次获取创建新实例。request
:每个HTTP请求一个实例。session
:每个会话一个实例。application
:全局应用一个实例。
- Spring单例Bean会有线程安全问题吗?
容器保证创建过程线程安全,但Bean若有可变状态(如成员变量),多线程下可能不安全。解决方式:用局部变量、ThreadLocal、线程安全集合(如ConcurrentHashMap),或改为prototype作用域。 - 什么是循环依赖?
两个或多个Bean相互依赖,如A依赖B,B依赖A,或自身依赖(C依赖C)。 - Spring如何解决循环依赖?
通过三级缓存:- 一级缓存(singletonObjects):存放完全初始化的Bean。
- 二级缓存(earlySingletonObjects):存放实例化但未初始化的Bean。
- 三级缓存(singletonFactories):存放Bean工厂,用于生成早期引用。
流程:创建A时将其工厂放入三级缓存,A依赖B时,B从三级缓存获取A的早期引用,完成注入后A再初始化。
- 为什么需要三级缓存而非两级?
解决AOP代理问题。三级缓存存Bean工厂,在获取时动态生成代理对象,确保循环依赖中注入的Bean与最终容器中的代理对象一致,避免两级缓存导致的对象不一致问题。
AOP部分
- 什么是AOP?
面向切面编程(AOP)将日志、事务等通用逻辑(横切关注点)从业务代码中抽取,通过切面统一处理,减少重复代码。核心是动态代理(JDK或CGLIB)。 - AOP的应用场景有哪些?
日志记录、权限校验、事务管理、异常处理、性能监控等。 - Spring AOP和AspectJ的区别?
- Spring AOP:基于动态代理,运行时织入,仅支持方法级拦截,依赖Spring容器。
- AspectJ:编译期/类加载期织入,支持字段、构造器等拦截,功能更强大,不依赖Spring。
- AOP和反射的区别?
- 反射:动态获取类信息并调用方法,直接操作对象。
- AOP:基于代理,在方法执行前后插入逻辑,侧重横切逻辑复用,底层可使用反射。
- JDK动态代理和CGLIB代理的区别?
- JDK动态代理:基于接口,生成实现接口的代理类,反射调用目标方法。
- CGLIB代理:基于继承,生成目标类的子类,重写方法实现增强,性能优于JDK。
- Spring默认:目标类有接口用JDK,否则用CGLIB。
事务部分
- 对Spring事务的理解?
Spring事务通过AOP实现,支持声明式(@Transactional
)和编程式事务。核心特性是ACID(原子性、一致性、隔离性、持久性),确保业务操作的完整性。 - 声明式事务的实现原理?
基于AOP,@Transactional
标注的方法被代理,代理对象在方法执行前开启事务,执行后提交/回滚(异常时),底层通过TransactionManager管理事务。 - @Transactional在哪些情况下会失效?
- 方法非public(Spring不拦截非public方法)。
- 自调用(类内部方法调用,未经过代理)。
- 异常被捕获(未抛出,无法触发回滚)。
- 错误配置
rollbackFor
(默认仅回滚RuntimeException)。
- Spring事务的隔离级别?
DEFAULT
:默认(数据库级别)。READ_UNCOMMITTED
:允许读取未提交数据(脏读)。READ_COMMITTED
:避免脏读。REPEATABLE_READ
:避免脏读、不可重复读。SERIALIZABLE
:最高级别,避免幻读。
- Spring的事务传播机制?
定义多事务方法调用时的行为,常用:REQUIRED
:默认,当前无事务则创建,有则加入。REQUIRES_NEW
:无论是否有事务,均创建新事务。NESTED
:嵌套事务,外层回滚内层也回滚。
MVC部分
- Spring MVC的核心组件有哪些?
- DispatcherServlet:前端控制器,分发请求。
- HandlerMapping:映射请求到Handler。
- HandlerAdapter:执行Handler。
- ViewResolver:解析视图。
- ModelAndView:封装模型和视图。
- Spring MVC的工作流程?
- 客户端发送请求到DispatcherServlet。
- DispatcherServlet通过HandlerMapping找到对应Handler。
- HandlerAdapter执行Handler,返回ModelAndView。
- ViewResolver解析视图,DispatcherServlet渲染视图并响应。
- SpringMVC Restful风格的接口流程?
用@GetMapping
、@PostMapping
等注解映射HTTP方法,通过@PathVariable
获取路径参数,@RequestBody
接收JSON数据,返回JSON格式响应,符合REST规范(资源导向,无状态)。
Spring Boot部分
- 介绍一下SpringBoot?
简化Spring应用开发的框架,核心特性:自动配置(减少XML)、起步依赖(整合常用组件)、嵌入式容器(如Tomcat)、监控功能,快速构建独立运行的应用。 - Spring Boot的自动装配原理?
@SpringBootApplication
包含@EnableAutoConfiguration
。- 扫描
META-INF/spring.factories
中的自动配置类(如DataSourceAutoConfiguration
)。 - 通过
@Conditional
注解条件加载配置(如类路径存在指定类时生效)。
- 如何自定义一个SpringBoot Starter?
- 创建Maven项目,定义starter依赖。
- 编写自动配置类(
@Configuration
),用@Bean
注册组件。 - 在
META-INF/spring.factories
中配置自动配置类。
- Spring Boot启动原理?
SpringApplication.run()
启动,初始化容器。- 加载自动配置类,扫描Bean并注册。
- 启动嵌入式容器(如Tomcat),发布应用就绪事件。
- SpringBoot和SpringMVC的区别?
- SpringMVC:Web框架,处理HTTP请求,实现MVC架构。
- SpringBoot:简化Spring应用开发,整合SpringMVC等组件,提供自动配置和嵌入式容器。
- Spring Boot和Spring的区别?
- Spring:核心框架,提供IoC、AOP等基础功能,需手动配置。
- SpringBoot:基于Spring,简化配置(约定大于配置),整合常用组件,快速开发。
Spring Cloud部分
- 对SpringCloud了解多少?
微服务架构工具集,基于Spring Boot,提供服务注册发现(Eureka)、配置中心(Config)、负载均衡(Ribbon)、断路器(Hystrix)、网关(Gateway)等组件,解决微服务通信、容错等问题。
补充部分
- SpringTask了解吗?
Spring的定时任务框架,通过@Scheduled
注解配置定时任务,支持 cron 表达式、固定延迟/间隔执行,简化定时任务开发。 - Spring Cache了解吗?
缓存抽象框架,通过@Cacheable
、@CachePut
、@CacheEvict
等注解实现缓存管理,支持整合Redis、EhCache等缓存中间件,减少数据库访问。