logo

Spring面试18问:从基础到进阶的全面解析

作者:渣渣辉2025.09.26 20:48浏览量:2

简介:本文汇总了Spring面试中常见的18个核心问题,涵盖IoC/AOP原理、事务管理、依赖注入、Bean生命周期等关键技术点,帮助开发者系统梳理知识体系,提升面试通过率。

一、基础概念与核心机制

1. Spring IoC容器的工作原理是什么?
IoC(控制反转)的核心是通过容器管理Bean的生命周期,将对象创建、依赖注入的权力从代码转移到配置文件或注解中。其实现步骤包括:

  • 配置解析:通过XML、JavaConfig或注解(如@Component)定义Bean。
  • Bean注册:容器扫描配置,将Bean定义存入BeanDefinitionMap。
  • 依赖注入:通过@Autowired@Resource自动装配,调用setter方法或构造器注入。
  • 初始化:执行@PostConstructInitializingBean接口方法。

2. 依赖注入的三种方式及其区别

  • 构造器注入:通过构造函数传入依赖,确保不可变性,推荐用于必须依赖。
    1. @Service
    2. public class UserService {
    3. private final UserRepository repository;
    4. @Autowired
    5. public UserService(UserRepository repository) {
    6. this.repository = repository;
    7. }
    8. }
  • Setter注入:通过setter方法注入,适合可选依赖,但可能引发NPE。
  • 字段注入:直接通过@Autowired注解字段,简洁但不利于单元测试(需反射)。

3. Bean的生命周期详解
Bean从创建到销毁经历以下阶段:

  1. 实例化:调用无参构造器或工厂方法。
  2. 属性赋值:执行setter方法或直接字段注入。
  3. Aware接口回调:如BeanNameAwareApplicationContextAware
  4. 初始化前:执行BeanPostProcessor.postProcessBeforeInitialization()
  5. 初始化:调用@PostConstructInitializingBean.afterPropertiesSet()
  6. 初始化后:执行BeanPostProcessor.postProcessAfterInitialization()(如AOP代理创建)。
  7. 销毁:调用DisposableBean.destroy()@PreDestroy

二、AOP与事务管理

4. Spring AOP的实现原理及适用场景
AOP通过动态代理实现,分为JDK动态代理(接口)和CGLIB代理(类)。核心组件包括:

  • 切面(Aspect):定义横切逻辑(如日志、事务)。
  • 切点(Pointcut):匹配连接点(方法执行点),如@Pointcut("execution(* com.example..*.*(..))")
  • 通知(Advice):在切点执行前/后/环绕等操作。

5. 声明式事务的传播行为与隔离级别

  • 传播行为
    • REQUIRED(默认):存在事务则加入,否则新建。
    • REQUIRES_NEW:总是新建事务,挂起当前事务。
  • 隔离级别
    • READ_COMMITTED:防止脏读,Oracle默认级别。
    • SERIALIZABLE:最高隔离,但性能最低。

6. 事务失效的常见原因

  • 自调用问题:类内部方法调用未经过代理,需通过AopContext.currentProxy()获取代理对象。
  • 异常不匹配:未捕获RuntimeExceptionError,需指定@Transactional(rollbackFor = Exception.class)
  • 数据库引擎不支持:如MyISAM引擎不支持事务。

三、数据访问与集成

7. JdbcTemplate与JPA/Hibernate的区别

  • JdbcTemplate:底层JDBC封装,需手动编写SQL,适合简单CRUD。
    1. jdbcTemplate.queryForList("SELECT * FROM users", User.class);
  • JPA/Hibernate:ORM框架,通过实体类映射表,支持HQL和Criteria查询。
    1. @Entity
    2. public class User {
    3. @Id @GeneratedValue private Long id;
    4. private String name;
    5. }
    6. // 查询
    7. userRepository.findByName("Alice");

8. Spring Data JPA的自定义查询方法
通过方法名派生查询或@Query注解实现:

  1. public interface UserRepository extends JpaRepository<User, Long> {
  2. // 方法名派生
  3. List<User> findByNameAndAgeGreaterThan(String name, int age);
  4. // 自定义HQL
  5. @Query("SELECT u FROM User u WHERE u.email LIKE ?1%")
  6. List<User> findByEmailPrefix(String prefix);
  7. }

四、高级特性与最佳实践

9. Spring Boot自动配置的原理
通过@EnableAutoConfiguration注解触发,依赖spring-boot-autoconfigure模块中的META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件,按条件(如@ConditionalOnClass)加载配置类。

10. 如何自定义Starter?
步骤如下:

  1. 创建spring.factories文件,指定自动配置类。
  2. 定义@Configuration类,通过@Conditional控制加载。
  3. 打包为jar并发布到Maven仓库。

11. 性能优化建议

  • 懒加载:使用@Lazy延迟Bean初始化。
  • 缓存:通过@Cacheable注解启用缓存。
  • 异步处理@Async注解方法,配合线程池配置。

五、常见问题排查

12. 循环依赖的解决方案

  • 构造器注入:直接报错,需重构设计。
  • Setter/字段注入:三级缓存(BeanDefinition→早期对象→完整对象)解决。

13. Bean未找到的常见原因

六、扩展与进阶

14. Spring Security的核心流程

  1. 认证:通过AuthenticationManager验证凭据。
  2. 授权AccessDecisionManager根据权限决策。
  3. 过滤器链:如UsernamePasswordAuthenticationFilter处理登录。

15. WebFlux与Servlet的对比

  • Servlet:阻塞IO,适合传统MVC。
  • WebFlux:响应式编程,基于Reactor,适合高并发场景。

16. 测试支持

  • MockMvc:模拟HTTP请求测试Controller。
    1. mockMvc.perform(get("/api/users"))
    2. .andExpect(status().isOk());
  • @DataJpaTest:集成JPA测试,自动配置内存数据库。

七、设计模式与源码解析

17. 模板方法模式的应用
JdbcTemplateexecute()方法定义骨架,子类实现doInConnection()

18. 观察者模式的实现
通过ApplicationEventPublisher发布事件,@EventListener监听:

  1. @Service
  2. public class EventService {
  3. @Autowired private ApplicationEventPublisher publisher;
  4. public void triggerEvent() {
  5. publisher.publishEvent(new CustomEvent(this, "data"));
  6. }
  7. }
  8. @Component
  9. public class EventListener {
  10. @EventListener
  11. public void handle(CustomEvent event) {
  12. System.out.println("Received: " + event.getData());
  13. }
  14. }

总结

本文通过18个核心问题,系统梳理了Spring框架从基础到进阶的知识点,涵盖IoC、AOP、事务、数据访问、性能优化等关键领域。掌握这些内容不仅能应对面试,更能提升实际开发中的问题解决能力。建议结合源码阅读(如DefaultListableBeanFactory)和实战项目深化理解。

相关文章推荐

发表评论

活动