【面试宝典】spring常见面试题总结[上]

一、什么是 Spring 框架?

Spring 框架是一个为 Java 应用程序的开发提供了综合、广泛的基础性支持的 Java 平台。

Spring 帮助开发者解决基础性的问题,使开发者专注编写业务代码。

二、Spring Freamework 有哪些功能?

  • IOC: 控制反转
  • AOP: 面向切面可以将应用业务逻辑和系统服务分离,以实现高内聚。
  • 容器:Spring 负责创建和管理对象的声明周期和配置。
  • MVC: 对 web 应用提供了高度可配置性,其他框架集成也十分方便。
  • 事务管理:提供了用于事务管理的通用抽象层。Spring 的事务支持也可用于容器较少的环境。
  • JDBC异常:Spring 的 JDBC 抽象层提供了一个异常层次结构,简化了错误处理策略。

三、什么是 Spring Ioc 容器?

Spring 框架的核心是 Spring 容器。容器创建对象,将它们装配在一起,配置它们并管理它们的完整生命周期。Spring 容器使用依赖注入来管理组成应用程序的组件。容器通过读取提供的配置元数据来接收对象实例化,配置和组装的指令。

四、依赖注入的方式有哪几种?

  • 构造函数注入
  • setter 注入
  • 接口注入

五、IOC 的好处和实现机制

它将最小化应用程序中的代码量;它以最小的影响和最少的侵入机制促进松耦合;它支持即时实例化和延迟加载服务。

Spring 中 IOC 的实现原理就是工程模式加反射机制。

六、@Compoent、@Controller、@Repository、@Service 有何区别?

  • @Compoent:这个注解是将类标记为 bean。它是任何 Spring 管理组件的通用构造型。Spring 的组件扫描机制现在可以将其拾取并将拉入应用程序环境中。

  • @Controller:这将一个类标记为 Spring Web MVC 控制器。标有它的 Bean 会自动导入到 IOC 容器中。

  • @Service:此注解是组件注解的特化。它不会对 @Compoent 注解提供任何其他行为。你可以在服务层类中使用它,而不是 @Compoent,因为它以更好的方式指名了意图。

  • @Repository:这个注解是具有类似用途何和功能的 @Compoent 注解的特化。它为 DAO 提供了额外的好处。它即将 DAO 导入 IOC 容器,并使未检查的异常有资格转换为 Spring DataAccessException。

七、@Autowired 注解有什么用?

它可以准确的控制应该在何处以及如何进行自动装配。此注解用于在 setter 方法,构造函数,具有任意名称或多个参数的属性或者方法上自动装配 bean。默认情况下,它是类型驱动的注入。

八、spring 支持的事务管理类型

  • 程序化事务管理:在此过程中,在变成的帮助下管理事务,它为程序员提供了极大的灵活性。但是维护起来非常困难。

  • 声明式事务管理:在此,事务管理和业务代码分离。仅使用注解或基于 XML 的配置来管理事务。

九、BeanFactory 和 ApplicationContext 有什么区别?

BeanFactory 和 ApplicationContext 是 Spring 框架中的两个核心接口,它们都可以作为 Spring 的容器,但存在多方面的区别。以下是对两者区别的详细分析:

1、概念与功能

BeanFactory

  • 是 Spring 框架中最底层的接口,是 IOC(控制反转)的核心。
  • 提供了 Bean 的创建、配置、初始化和销毁等基本操作。
  • 功能包括 Bean 的定义、加载、实例化、依赖注入和生命周期的管理。
  • 主要面向 Spring 框架本身,是 Spring 的基础设施。

ApplicationContext

  • 继承自 BeanFactory 接口,除了包含 BeanFactory 的所有功能外,还提供了更多扩展功能。
  • 支持国际化、资源文件访问(如URL和文件)、事件传播等。
  • 面向使用 Spring框架 的开发者,提供了更完整的框架功能。
  • 被推荐为Java EE应用的首选容器。

2、加载机制

BeanFactory

  • 采用延时加载(Lazy Loading)机制,即在容器启动时不会注入 Bean,而是在需要使用Bean 的时候,才会对该 Bean 进行加载和实例化。
  • 如果 Bean 的某个属性没有注入,BeanFactory 加载时不会抛出异常,直至第一次调用getBean() 方法时才会抛出异常。

ApplicationContext

  • 在容器启动时,一次性创建并初始化所有的 Bean,因此运行时的速度相对 BeanFactory 较快。
  • 在容器启动时就可以发现 Spring 配置文件中存在的问题,有利于检测依赖属性是否注入。
  • 由于一次性加载所有 Bean,可能会导致内存占用较多,尤其是在 Bean 数量较多时,会影响程序的启动速度。

3、创建与注册方式

BeanFactory

  • 通常以编程的方式创建,如使用 XmlBeanFactoryDefaultListableBeanFactory 等实现类。
  • 需要手动注册 BeanPostProcessor 和 BeanFactoryPostProcessor 等。

ApplicationContext

  • 以声明的方式创建,如使用 ClassPathXmlApplicationContextFileSystemXmlApplicationContext 等实现类。
  • 自动注册 BeanPostProcessor 和 BeanFactoryPostProcessor 等,简化了配置过程。

十、Spring Bean 的声明周期

Spring Bean的生命周期是指从Bean的创建、初始化到销毁的整个过程,这个过程由Spring IoC容器(Inversion of Control,控制反转容器)控制。Spring Bean的生命周期可以大致分为几个主要阶段,每个阶段都包含特定的操作和回调点,允许开发者在Bean的生命周期中的不同点插入自定义逻辑。以下是对Spring Bean生命周期的详细解释:

1、Bean元信息配置阶段

  • 定义Bean信息 :通过XML配置文件、注解(如@Component@Service等)、Java代码(使用@Bean注解)或properties文件等方式定义Bean的信息。
  • 解析Bean信息 :Spring容器启动时,会解析这些配置信息,将其转换为内部的BeanDefinition对象。BeanDefinition包含了Bean的元数据信息,如类名、作用域、依赖关系等。

2、Bean注册阶段

  • 注册Bean到容器 :解析后的BeanDefinition对象会被注册到Spring IoC容器中,容器会维护一个Bean定义的注册表,用于后续的Bean实例化和依赖注入。

3、Bean实例化阶段

  • 实例化前阶段:在Bean实例化之前,可能会进行一些前置处理,如检查Bean的依赖项是否已准备好。
  • 实例化阶段 :根据BeanDefinition中的信息,使用反射机制创建Bean的实例。对于单例Bean,Spring容器会缓存这个实例,以便后续请求时直接返回。

4、属性赋值阶段

  • 实例化后阶段:Bean实例化完成后,但属性还未赋值之前,可能会进行一些额外的处理。
  • 属性赋值前阶段:设置Bean的属性值之前,可能需要进行一些准备工作。
  • 属性赋值阶段 :Spring根据BeanDefinition中的依赖信息,通过依赖注入的方式为Bean的属性赋值。这包括通过构造函数注入、Setter方法注入等方式。

5、初始化阶段

  • Aware接口回调阶段 :如果Bean实现了特定的Aware接口(如BeanNameAwareBeanFactoryAwareApplicationContextAware等),Spring容器会回调这些接口的相应方法,将容器相关的信息注入到Bean中。
  • 初始化前阶段:在Bean正式初始化之前,可能会执行一些前置处理逻辑。
  • 初始化阶段
    • 如果Bean实现了InitializingBean接口,会调用其afterPropertiesSet()方法。
    • 如果在Bean配置中指定了init-method,则会调用该方法。
  • 初始化后阶段:Bean初始化完成后,可能会执行一些后置处理逻辑。

6、使用阶段

  • Bean的使用:初始化完成后,Bean就可以被应用程序使用了。Spring容器负责维护Bean的实例,并根据需要将其注入到其他Bean中。

7、销毁阶段

  • 销毁前阶段:在Bean销毁之前,可能会执行一些清理工作。
  • 销毁阶段
    • 如果Bean实现了DisposableBean接口,会调用其destroy()方法。
    • 如果在Bean配置中指定了destroy-method,则会调用该方法。
    • 对于单例Bean,Spring容器关闭时会自动调用这些销毁方法。

总结

Spring Bean的生命周期是一个从定义到销毁的完整过程,其中包含了多个阶段和回调点。通过在这些回调点插入自定义逻辑,开发者可以对Bean的生命周期进行精细控制,以满足复杂的应用需求。

相关推荐
Cosolar4 小时前
FunASR 前端语音识别代码解析
前端·面试·github
weixin_419658315 小时前
Spring 的统一功能
java·后端·spring
小许学java6 小时前
Spring AI-流式编程
java·后端·spring·sse·spring ai
躬身入世,以生证道6 小时前
面试技术栈 —— 简历篇
面试·职场和发展
Asmalin6 小时前
【代码随想录day 35】 力扣 01背包问题 一维
算法·leetcode·职场和发展
程序员飞哥8 小时前
如何设计多级缓存架构并解决一致性问题?
java·后端·面试
Lisonseekpan8 小时前
Java Caffeine 高性能缓存库详解与使用案例
java·后端·spring·缓存
SXJR9 小时前
Spring前置准备(七)——DefaultListableBeanFactory
java·spring boot·后端·spring·源码·spring源码·java开发
道可到11 小时前
百度面试真题 Java 面试通关笔记 04 |JMM 与 Happens-Before并发正确性的基石(面试可复述版)
java·后端·面试
bot55566612 小时前
“企业微信iPad协议”静默 72 小时:一台被遗忘的测试机如何成为私域的逃生梯
javascript·面试