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