ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Spring面试25道经典题:IoC、Bean生命周期与配置方式全解析

Spring面试25道经典题:IoC、Bean生命周期与配置方式全解析

简介:经典Spring面试问答整理,面向Java开发工程师及正在备战Spring相关岗位面试的求职者,覆盖IoC控制反转、依赖注入、Bean生命周期与作用域、注解配置、自动装配等核心高频考点,同时涉及Spring框架模块划分、BeanFactory与ApplicationContext对比、事务管理等实际面试常见问题,帮助读者快速建立Spring知识脉络并查漏补缺。压缩包内含1个docx文档,共25道经典题目及详细参考答案,文件体积约88KB,轻量易读,方便随时随地翻阅学习。已有403人学习,文档按问答形式逐题展开,适合面试前集中复习,也可作为日常巩固Spring基础知识的随身笔记。内容在讲解核心原理时还结合了典型场景与设计模式说明,有助于提升对框架底层机制的理解,为后续深入源码学习打下基础。

1. Spring面试到底考什么:25道经典题背后的考点地图

Spring是Java后端面试绕不开的关卡,IoC、Bean生命周期、配置方式、线程安全这些点几乎每场都会被问到,而且面试官特别喜欢往深处追问一层。这25道经典题恰好覆盖了Spring面试的完整考点链:从概念到落地、从XML到注解、从单例到设计模式,全是最常考的骨架题。它不是一份拿来背的清单,而是一张考点地图。面试官问"什么是控制反转"不是要你背书,是要听你怎么把概念落到代码里、再落到项目场景中。备考的核心就是把这张地图上的每个考点拆成"概念一句话、代码一段、场景一个"的答题模板。下面按这条考点链依次拆解,照着准备基本能覆盖大多数Spring面试题。

2. 高频考点:IoC与依赖注入的三种实现方式与答题模板

2.1 概念题怎么答:IoC是思想,DI是机制

面试官问"什么是控制反转(IOC)"和"什么是依赖注入"时,最忌讳把两者混为一谈。正确答题顺序是:先给IoC下定义,再给出DI的定义,最后点明两者的关系。

控制反转是软件工程中的一种设计范式,核心在于对象之间的耦合关系在编译时通常是未知的,而是在运行时由装配器对象来绑定。传统编程里,业务逻辑的流程由应用程序中早已设定好关联关系的对象决定;用了IoC之后,业务逻辑流程由对象关系图决定,这个关系图由装配器负责实例化,对象间关联关系的定义也被抽象化了。听完这段如果面试官没喊停,立刻补一句关键收尾:绑定的过程就是通过"依赖注入"实现的,依赖注入是控制反转的基础——否则组件不受框架控制时,框架根本不知道要创建哪个组件。

在Java中依赖注入有三种实现方式:构造器注入、Setter方法注入、接口注入。Spring实际使用前两种,接口注入基本只停留在理论层面。答到这里再主动补一句"Spring里的IoC以BeanFactory和ApplicationContext为核心",就能自然衔接到下一题。

2.2 构造器注入与Setter注入:三个维度对比

第22题"构造器注入和setter方法注入之间的区别"几乎是必考的对比题,最优答法分三个维度:必要性、可变性、可测试性。

必要性层面,构造器注入强制依赖在对象创建的瞬间就必须完整提供,不会出现"对象建好了但依赖还是空的"这种中间状态;Setter注入允许对象先创建、后装配,适合可选依赖,但存在使用到未注入状态的风险。可变性层面,构造器注入一旦创建就不可换依赖,Setter在运行期还能调setter替换。可测试性层面,构造器注入直接new对象传参就能单测,Setter需要额外调用setter。

Spring团队官方推荐构造器注入,但面试别只答结论,补一句应用场景更显功底:业务服务类多用构造器注入,配置类里的可选参数用Setter更灵活。下面这段XML展示的是Setter注入真实写法,同时也是第12题"内部Bean"的绝佳示例:

<bean id="customerBean" class="com.example.common.Customer"> <property name="person"> <bean class="com.example.common.Person"> <property name="name" value="lokesh" /> <property name="address" value="India" /> <property name="age" value="34" /> </bean> </property> </bean>

当某个Bean只被另一个Bean使用一次时,直接在property或constructor-arg内部声明,不需要在顶层注册,这就是内部Bean。说到这可以顺带点一句"内部Bean没有id,外部拿不到它的引用",这种细节最容易让面试官眼前一亮。

2.3 真题演练:BeanFactory与ApplicationContext的区别

第5题是Spring面试出场率最高的题之一。标准答题路径是三层递进:先讲关系,再讲加载时机差异,最后讲扩展功能。

关系上,ApplicationContext是BeanFactory的子接口,属增强版。BeanFactory是Spring IoC容器的核心接口,可以理解为"含有Bean定义的工厂类",在客户端请求时实例化bean,同时负责Bean生命周期和初始化/销毁方法的调用。ApplicationContext在具备这些能力之外,还扩展了三个能力:支持国际化的文本消息、统一的资源文件读取方式、支持已注册在监听器中的Bean事件。

加载时机是关键得分点:BeanFactory是懒加载,调用getBean()时才实例化;ApplicationContext是预加载,容器启动时就实例化所有单例Bean,所以能提前暴露配置错误,代价是启动更慢、内存占用更高。常见ApplicationContext实现类有三种,逐一报名字并给出一行代码:

// classpath下的XML配置文件 ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml"); // 文件系统中的XML配置文件 ApplicationContext context = new FileSystemXmlApplicationContext("bean.xml"); // Java配置类 ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);

面试官追问"你项目里用哪种",答AnnotationConfigApplicationContext(对应Spring Boot和Java Config趋势),再补一句"老SSH项目才会看到ClassPathXmlApplicationContext"。把这句说出来,等于告诉面试官你见过两种年代的项目。

2.4 注入Collection和Properties:XML配置的实操题

第14题考Spring如何注入Java集合类,答法就是报出四种标签并各给一段代码: 装配可重复的List值,装配无重复的Set值,注入键值对任何类型都可, 注入键和值均为字符串的键值对。

<bean id="javaCollection" class="com.example.JavaCollection"> <property name="customList"> <list> <value>INDIA</value> <value>USA</value> </list> </property> <property name="customMap"> <map> <entry key="1" value="INDIA"/> <entry key="2" value="USA"/> </map> </property> <property name="customProperties"> <props> <prop key="admin">admin@nospam.com</prop> <prop key="support">support@nospam.com</prop> </props> </property> </bean>

第15题专门考Properties注入,除了上面的 写法,还有一种高级答法:用util命名空间从properties文件创建独立的Properties Bean,再通过setter方法注入引用。两种方法对比一下, 适合配置内联少量键值对,util方式适合复用外部配置文件。这题答完,面试官对你的XML功底基本心里有数了。

3. 高频考点:Bean生命周期、作用域与线程安全真相

3.1 Bean生命周期:四组回调一个不落

第10题考Bean生命周期时,面试官想听的不是"初始化然后销毁"六个字,而是完整的回调机制。Spring Bean的生命周期由BeanFactory管理,分成两组回调:初始化之后调用的回调和销毁之前调用的回调。管理这些回调一共有四种方式,缺一不可:

InitializingBean和DisposableBean接口。afterPropertiesSet()在属性设置完成后触发,destroy()在销毁前触发。缺点是接口方法名固定、侵入代码。

针对特殊行为的Aware接口。BeanFactoryAware、ApplicationContextAware等,用于让Bean感知容器环境。这一条答出来通常能拉开差距,很多候选者只记得前两条。

配置文件里的custom init-method和destroy-method。这是最灵活的方案,任意类里写任意public方法,在XML里配对声明即可,不要求实现框架接口:

<bean id="demoBean" class="com.example.task.DemoBean" init-method="customInit" destroy-method="customDestroy"> </bean>

@PostConstruct和@PreDestroy注解。Java标准注解,标注在方法上,由容器扫描执行,适合Java Config和注解驱动项目。

答题时建议顺手提一句执行顺序:构造Bean实例后,先执行@PostConstruct,再走InitializingBean的afterPropertiesSet,最后才调init-method;销毁侧顺序正好相反,先@PreDestroy,再destroy(),最后destroy-method。能说出这个顺序,这道题直接满分。

3.2 五种作用域:一张表过完,注意两个坑

第11题考Bean作用域,五种作用域名称都自说明,但面试容易丢分在两个细节上。先把五种作用域背熟:

作用域实例数生命周期典型场景
singleton每个容器一个容器启动到关闭默认,无状态Service/DAO
prototype每次请求创建新实例获取Bean时创建有状态对象
request每个HTTP请求一个实例请求结束即失效Web请求级临时对象
session每个Session一个实例Session过期失效用户级状态对象
global-session每个全局Session一个Portlet应用场景多个Portlet共享全局变量

第一个易错点是singleton的边界:它是"每个Spring容器一个",不是"每个JVM一个",两个容器各自管理各自的单例。第二个易错点在于prototype:容器创建后就撒手不管了,不会执行它的destroy回调,因为容器不再跟踪prototype Bean的生命周期。很多候选人背表很熟,被追问"prototype作用域下destroy方法会执行吗"直接卡壳。给出明确答案后,再补一句"所以prototype Bean的资源释放通常靠Bean自身或调用方管理",面试官会点头。

3.3 单例Bean线程安全:这是陷阱题

第13题是个典型的陷阱题,面试官故意问"Spring框架中的单例Bean是线程安全的吗"。这个问题的正确答案非常明确:不是!Spring并没有对单例Bean做任何多线程封装处理,线程安全和并发问题需要开发者自行解决。

但这里有个微妙之处:为什么很多人觉得Spring单例Bean安全?原因在于大部分Spring Bean没有可变状态,比如Service类和DAO类,没有成员变量,天然线程安全。如果你的Bean有多种状态,比如ViewModel对象,就必须自行保证线程安全。最浅显的解决办法就是把多态Bean的作用域从singleton改为prototype。

面试作答时,用"分两类"结构:无状态Bean直接用单例完全没问题,这是主流;有状态Bean要么改prototype,要么用ThreadLocal等机制隔离状态。最后补一句"实际项目里我会先看Bean里有没有可变的成员变量,再决定要不要改作用域",把话题从背书拉到工程判断。

3.4 真题演练:Spring用了哪些设计模式,怎么答不落俗套

第25题考Spring中使用的设计模式。这道题看似开放,其实有固定得分点。至少要说清五种:工厂模式——BeanFactory用来创建和管理Bean;单例模式——默认的singleton作用域;代理模式——AOP通过代理对象包裹目标方法;模板方法——JdbcTemplate、RestTemplate等;观察者模式——ApplicationEvent和监听器机制。

答题技巧是每个模式都带一句"用在哪",别只甩名词。比如"Spring的AOP用代理模式,事务管理就是靠生成代理对象在目标方法前后追加事务逻辑"。这样答比干列举有说服力多了。顺带把第23题事件机制串进来:Spring的事件类型基于ApplicationEvent,通过ApplicationContext发布,由ApplicationListener监听,这就是观察者模式在容器里的落地。

3.5 文件资源加载:FileSystemResource和ClassPathResource的区别

第24题容易被忽略,但大厂偶尔会考。FileSystemResource基于文件系统中的文件路径读取资源,ClassPathResource基于classpath类路径读取。前者的路径锚点是项目运行目录,后者的锚点是编译后classes目录。回答时给一个判断标准:打包成Jar运行后,ClassPathResource更可靠,因为文件系统路径在部署环境下经常不可控。

4. 高频考点:三大配置方式与注解装配的实战答法

4.1 三种配置方式怎么选:XML、注解、Java Config

第6题问Spring有几种配置方式,标准答案是三种:基于XML的配置、基于注解的配置、基于Java的配置。面试时按时间线和适用场景讲才有层次:最早的SSH项目全是XML,配置文件和Java代码分离但冗长;Spring 2.5引入注解,把Bean描述搬到组件类内部,XML瘦身成 context:annotation-config/ 加Bean定义;Spring 3.0后Java Config成为主流,@Configuration和@Bean接管配置,XML逐渐退居为兼容旧项目的方案。

在Spring Boot体系里,Java Config + 注解扫描是默认姿势,但XML仍在老项目里大量存在。面试官真正想验证的是:你既会看老代码,也知道新趋势。所以别只答"有三种",要顺着讲清楚"为什么从XML迁到Java Config"——类型安全、可重构、IDE友好。

4.2 XML配置细节:命名空间与DispatcherServlet

第7题考XML配置,答题锚点是Spring主要命名空间:context、beans、jdbc、tx、aop、mvc和aso,每个命名空间对应一组XML标签能力。核心配置文件以 开头,里面是Bean定义和应用配置选项。给一段实际配置作为例证:

<beans> <bean name="viewResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver"/> <bean name="jsonTemplate" class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"/> <bean id="restTemplate" class="org.springframework.web.client.RestTemplate"/> </beans>

如果是Web应用,还要配DispatcherServlet,web.xml里声明Servlet并映射到根路径,这已经是Spring MVC的入口配置。完整答法可以补一句:DispatcherServlet本质是一个Servlet,负责拦截请求并分发给Controller,所有Spring MVC组件的装配都从它开始。这段一说,配置题的广度和Web层功底都露出来了。

4.3 Java Config:@Configuration与@Bean的正确打开方式

第8题考Java配置,核心是@Configuration和@Bean两个注解。@Configuration注解类表示"这个类的主要目的是作为Bean定义的资源";@Bean标注的方法负责实例化、配置和初始化一个新对象,交给IoC容器管理,作用等同于XML里的 元素。给出代码就是最好的回答:

@Configuration public class AppConfig { @Bean public MyService myService() { return new MyServiceImpl(); } }

这段配置等价于XML里的 。实例化方式是用AnnotationConfigApplicationContext读取配置类:

ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class); MyService myService = ctx.getBean(MyService.class); myService.doStuff();

再往深处讲一步,配合组件扫描,用@ComponentScan指定包路径,容器自动扫描包内带@Component的类并注册成Bean:

@Configuration @ComponentScan(basePackages = "com.example") public class AppConfig { // ... }

Web环境下要用AnnotationConfigWebApplicationContext,配置到ContextLoaderListener或DispatcherServlet的contextClass参数里。这题的加分细节是点名"@Configuration类内部调用@Bean方法可以设置Bean间的依赖关系",大多数人会漏这句。

4.4 注解装配:默认关闭这个坑,必须主动提起

第9题考注解配置,最容易被忽略也最常丢分的是这个前置条件:注解注入在Spring中是默认关闭的,需要先配置 context:annotation-config/ 才能启用注解装配模式。

<beans> <context:annotation-config/> <!-- bean definitions go here --> </beans>

答完配置再进入注解主体。核心注解分四类:@Required作用于设值方法,强制属性必须被设置;@Autowired可作用于属性、方法、构造方法,按类型自动装配;@Qualifier配合@Autowired消除特定Bean装配的歧义;JSR-250系列包括@Resource、@PostConstruct、@PreDestroy。

面试官通常会追问"@Autowired和@Resource有什么区别",这题在清单里没有,但属于高频延伸题。标准答法:@Autowired是Spring注解按类型注入,@Resource是JSR-250标准注解默认按名称注入,找不到名称再按类型。还会追问"注解和XML同时存在时谁生效",答案是注解注入在XML注入之前被处理,XML会覆盖同属性的注解结果。

4.5 自动装配模式与@Qualifier救场

第16题考自动装配,先讲XML机制。Spring容器可以自动装配合作关系Bean的关联关系,在Bean配置上设置autowire属性,有以下几种模式:byName按属性名查找Bean,byType按类型查找Bean,constructor用于构造器参数,no表示不自动装配。

<bean id="employeeDAO" class="com.example.EmployeeDAOImpl" autowire="byName" />

接下来自然引出@Autowired注解:它在Spring中按类型自动装配。但实际项目里接口常有多个实现,按类型装配产生歧义,Spring不知道注入哪个。此时用@Qualifier指定Bean名称,消除歧义:

@Autowired @Qualifier("employeeDAOImpl") private EmployeeDAO employeeDAO;

答题收尾时给一个工程选择:byName依赖命名规范,脆;byType遇到多实现就歧义,需要@Qualifier救场;实际项目里更推荐构造器注入加@Qualifier,兼顾装配确定性和可测试性。这段话能让面试官看到你不是只背了XML,而是真在项目里权衡过。

5. 易错题/失分点:5道高频误答与正确答法

5.1 把IoC直接等同于DI

错在哪:回答"什么是控制反转"时直接说"控制反转就是把new对象的操作交给Spring,也叫依赖注入"。 为什么错:IoC和DI不是一个概念。IoC是设计思想,DI是实现这种思想的具体机制,两者是从属关系,不是同义词。 怎么答对:先说IoC是解耦思想——对象间耦合关系在编译时未知,运行时由容器绑定;再说DI是着陆方式——编译阶段不知道依赖来自哪个类,由容器实例化并注入;最后补一句"DI是IoC的基础,否则容器无法知道创建哪个组件"。

5.2 BeanFactory与ApplicationContext的加载时机答反

错在哪:答成"BeanFactory启动时预加载所有Bean,ApplicationContext延迟加载"。 为什么错:把两者完全搞反了。BeanFactory是懒加载,直到getBean()调用才实例化Bean;ApplicationContext是预加载,启动时就把单例Bean全部实例化。 怎么答对:先把加载时机说对,再说扩展功能。扩展功能至少报三个:国际化文本消息、统一资源文件读取、监听器中注册的Bean事件。加载时机是硬性得分点,一旦答反,后面功能答得再多也救不回来。

5.3 说"注解装配默认开启"

错在哪:回答Spring注解配置时,直接掏出@Autowired就开写,完全不提前置配置。 为什么错:Spring框架里注解装配默认关闭,必须显示配置 context:annotation-config/ 才会生效,否则注解全被忽略。Spring Boot的自动配置掩盖了这个底层事实,所以背过Spring Boot的人特别容易踩这个坑。 怎么答对:先承认默认关闭,再贴 context:annotation-config/ 开启配置,然后说明注解注入先于XML注入被处理、XML会覆盖同属性的注解结果。

5.4 单例Bean是线程安全的,这句话本身就是错的

错在哪:听到"单例"就默认安全,直接断言Spring的单例Bean线程安全。 为什么错:单例模式解决的是实例数量问题,不解决多线程竞争问题。Spring没有对单例Bean做锁、ThreadLocal之类任何封装,所以它本身不保证线程安全。 怎么答对:无状态Bean场景下天然安全,这是"大部分Service和DAO是安全的"的原因;有状态Bean必须自行保证线程安全,最直接的方案是把作用域改成prototype或用ThreadLocal隔离。

5.5 构造器注入和Setter注入,只背结论不讲依据

错在哪:只答一句"Spring推荐构造器注入",然后在追问下支支吾吾。 为什么错:对比题要的是判断依据,不是推荐结论。面试官想听的是你清楚构造器注入百分百保证依赖完整、Setter注入允许延迟装配但存在半初始状态。 怎么答对:用三个维度展开对比——必要性看是否强制提供依赖,可变性看运行期能否换实现,可测试性看单测时构造对象是否方便。最后落到选择标准:必需依赖构造器优先,可选依赖Setter更灵活。

6. 答题技巧:三步应答法与高频追问预案

6.1 三步应答法:概念-代码-落地

Spring面试题大多有共同套路,按"概念一句话、代码一段、落地场景一个"三步走基本不慌。第一步用一句话定调,比如"IoC是一种解耦思想,DI是它的实现机制",别展开,等面试官追问。第二步拿代码证明你会写,生命周期题就贴init-method配置,注入题就写@Autowired加@Qualifier。第三步一定落到场景:"我项目里Service都用构造器注入,遇到多实现就配合@Qualifier指定Bean名"。三步走完,面试官至少认为你既懂原理又能动手。

6.2 高频追问预案:把25题串成网状

Spring的追问路径其实很固定。你答完BeanFactory和ApplicationContext的区别,他大概率接着问"那你Spring Boot项目里用的是哪个Context";你答完Bean生命周期,他会追问"如果同时有init-method和@PostConstruct,执行顺序谁先谁后"。这类追问考的是知识网络。建议把25题按链路串起来:IoC概念,三种注入,配置方式,Bean生命周期,作用域,线程安全,注解装配,事件与设计模式。答任何一问前先在脑中定位自己处于链上哪一环,被追问时就能顺着链往上下游接话,而不是干愣着。

6.3 经验面怎么串:把考点锚定到项目三层

如果面试就着项目经历问Spring,别只答"我们项目用了SpringBoot",要把考点锚定到三个层面。容器层面说你项目里哪些类被IoC管理——Controller依赖Service、Service依赖DAO;配置层面说你们用Java Config加注解扫描,没有XML;运行层面说事务靠AOP声明式管理,切面代理包住了Service方法。哪怕只是CRUD项目,也能用这套结构撑起"我理解容器在管理我的Bean"的深度。

我备考这25道题最深的一条教训是:干背答案过不了追问。以前我把"单例Bean线程安全"背成"Spring默认安全",结果被面试官连续追问"你项目里那个带状态的后台线程池怎么办",当场卡住。从那以后我每次复习Spring,都强制自己走一遍"概念到代码到场景"三步,就算只是写个小Demo验证Bean生命周期回调顺序,也比反复啃文档管用。希望帮到你。

本文还有配套的精品资源,点击获取

返回列表