文章目录

  • 一、Spring面试题
    • 1.你为什么使用 Spring?
    • 2. Spring 支持几种 bean 的作用域?
    • 3.请问 Spring 有几种自动装配模式?
    • 4.对 Java 接口代理模式的实现原理的理解?
    • 5.怎么理解面向切面编程的切面?
    • 6.什么是 IOC 容器?
    • 7.为什么需要代理模式?
    • 8.讲讲静态代理模式的优点及其瓶颈?
    • 9.讲解 Spring 框架中基于 Schema 的 AOP 实现原理?
    • 10. 讲解 Spring 框架中如何基于 AOP 实现的事务管理?
    • 11. Spring 在 Bean 创建过程中是如何解决循环依赖的?
    • 12. Spring 中 Bean 是如何管理的?
    • 13. 请具体描述 IOC 容器对 Bean 的生命周期控制流程:
    • 14. BeanFactory 和 ApplicationContext 有什么区别?
    • 15. 谈谈 Spring Bean 创建过程中的设计模式?
    • 16. Spring MVC 运行流程
    • 17. Spring 框架中的单例 bean 是线程安全的吗?
    • 18. 解释 Spring 支持的几种 bean 的作用域
    • 19.解释 Spring 框架中 bean 的生命周期
    • 20.哪些是重要的 bean 生命周期方法?你能重载它们吗?
  • 二、SpringMvc面试题
    • 1、什么是 SpringMvc?
    • 2、Spring MVC 的优点:
    • 3、SpringMVC 工作原理?
    • 4、SpringMVC 流程?
    • 5、SpringMvc 的控制器是不是单例模式,如果是,有什么问题,怎么解决?
    • 6、如果你也用过 struts2.简单介绍下 springMVC 和 struts2 的区别有哪些?
    • 7、SpingMvc 中的控制器的注解一般用那个,有没有别的注解可以替代?
    • 8、 @RequestMapping 注解用在类上面有什么作用?
    • 9、怎么样把某个请求映射到特定的方法上面?
    • 10、如果在拦截请求中,我想拦截 get 方式提交的方法,怎么配置?
    • 11、怎么样在方法里面得到 Request,或者 Session?
    • 12、我想在拦截的方法里面得到从前台传入的参数,怎么得到?
    • 13、如果前台有很多个参数传入,并且这些参数都是一个对象的,那么怎么样快速得到这个对象?
    • 14、SpringMvc 中函数的返回值是什么?
    • 15、SpringMVC 怎么样设定重定向和转发的?
    • 16、SpringMvc 用什么对象从后台向前台传递数据的?
    • 17、SpringMvc 中有个类把视图和数据都合并的一起的,叫什么?
    • 18、怎么样把 ModelMap 里面的数据放入 Session 里面?
    • 19、SpringMvc 怎么和 AJAX 相互调用的?
    • 20、当一个方法向 AJAX 返回特殊对象,譬如 Object,List 等,需要做什么处理?
    • 21、SpringMvc 里面拦截器是怎么写的
    • 22、讲下 SpringMvc 的执行流程


前    言
本文仅收录了一些常见的Spring面试题,如需查看其它java面试题可查看我另一篇博文:

JAVA | 2021最全Java面试题及答案汇总


正    文

一、Spring面试题

1.你为什么使用 Spring?

轻量级:Spring 在大小和透明性方面绝对属于轻量级的,基础版本的 Spring 框架大约
只有 2MB。
控制反转(IOC):Spring 使用控制反转技术实现了松耦合。依赖被注入到对象,而不是
创建或寻找依赖对象。
面向切面编程(AOP): Spring 支持面向切面编程,同时把应用的业务逻辑与系统的服
务分离开来。
容器:Spring 包含并管理应用程序对象的配置及生命周期。
MVC 框架:Spring 的 web 框架是一个设计优良的 web MVC 框架,很好的取代了一些 web
框架。
事务管理:Spring 对下至本地业务上至全局业务(JAT)提供了统一的事务管理接口。
异常处理:Spring 提供一个方便的 API 将特定技术的异常(由 JDBC, Hibernate, 或 JDO
抛出)转化为一致的、Unchecked 异常。

2. Spring 支持几种 bean 的作用域?

1)singleton:默认,每个容器中只有一个 bean 的实例,单例的模式由 BeanFactory
自身来维护。
2)prototype:为每一个 bean 请求提供一个实例。
3)request:为每一个网络请求创建一个实例,在请求完成以后,bean 会失效并被垃圾
回收器回收。
4)session:与 request 范围类似,确保每个 session 中有一个 bean 的实例,在 session
过期后,bean 会随之失效。
5)global-session:全局作用域,global-session 和 Portlet 应用相关。当你的应用
部署在 Portlet 容器中工作时,它包含很多 portlet。如果你想要声明让所有的 portlet 共
用全局的存储变量的话,那么这全局变量需要存储在 global-session 中。全局作用域与
Servlet 中的 session 作用域效果相同。

3.请问 Spring 有几种自动装配模式?

自动装配提供五种不同的模式供 Spring 容器用来自动装配 beans 之间的依赖注入:
no:默认的方式是不进行自动装配,通过手工设置 ref 属性来进行装配 bean。
byName:通过参数名自动装配,Spring 容器查找 beans 的属性,这些 beans 在 XML 配
置文件中被设置为 byName。之后容器试图匹配、装配和该 bean 的属性具有相同名字的 bean。
byType:通过参数的数据类型自动自动装配,Spring 容器查找 beans 的属性,这些 beans
在 XML 配置文件中被设置为 byType。之后容器试图匹配和装配和该 bean 的属性类型一样的
bean。如果有多个 bean 符合条件,则抛出错误。
constructor:这个同 byType 类似,不过是应用于构造函数的参数。如果在 BeanFactory
中不是恰好有一个 bean 与构造函数参数相同类型,则抛出一个严重的错误。
autodetect:如果有默认的构造方法,通过 construct 的方式自动装配,否则使用
byType 的方式自动装配。

4.对 Java 接口代理模式的实现原理的理解?

答:
1、字符串拼凑出代理类
2、用流的方式写到.Java 文件
3、动态编译.Java 文件
4、自定义类加载器把.class 文件加载到 jvm
5、返回代理类实例
其实核心就是根据接口反射出接口中的所有方法,然后通过拼凑或者 cglib 字节码的方
式把代理类反射出来,而代理类在内存中就会对某种类型的类进行调用,invocationHandler
(Jdk)或者 MethodInterceptor(cglib)

5.怎么理解面向切面编程的切面?

答:
切面指的是一类功能,比如事务,缓存,日志等。切面的作用是在目标对象方法执行前
或者后执行切面方法

6.什么是 IOC 容器?

答:
Spring IOC 负责创建对象、管理对象(通过依赖注入)、整合对象、配置对象以及管理
这些对象的生命周期。
Ioc 是把对象的控制权较给框架或容器,容器中存储了众多我们需要的对象,然后我们
就无需再手动的在代码中创建对象。需要什么对象就直接告诉容器我们需要什么对象,容器
会把对象根据一定的方式注入到我们的代码中。注入的过程被称为 DI。有时候需要动态的
指定我们需要什么对象,这个时候要让容器在众多对象中去寻找,容器寻找需要对象的过程,
称为 DL(Dependency Lookup, 依赖查找)。按照上面的理解,那么 IOC 包含了 DI 与 DL,并
且多了对象注册的过程。

7.为什么需要代理模式?

答:
代理其实是对开闭原则和里氏代换原则的一种实现,它强调在不修改老代码的基础上扩
展功能,代理模式大大提高了代码的灵活性,同时也使代码的可读性变差,同时动态代理也
加大了内存溢出的风险。

8.讲讲静态代理模式的优点及其瓶颈?

答:
静态代理一种傻瓜式的对目标类的增强,其核心就两点,1、跟目标类实现同一接口 2、
持有目标类的引用。 如果需要对目标类方法进行增强,就只要调用代理类的方法,在方法
里面写增强功能然后调用目标类方法即可。优点就是代码直观且执行速度快,缺点就是不够
灵活,代码量比较大,每一种类型的目标类都需要单独写一个代理类。

9.讲解 Spring 框架中基于 Schema 的 AOP 实现原理?

答:
这个是基于 xml 配置方式的 aop
<aop:config proxy-target-class=“true”>
<aop:pointcut expression=“execution(public void
org.aop.Object.Student.display())” id=“pointcut”/>
<aop:aspect ref=“advice”>
<aop:before method=“before” pointcut-ref=“pointcut”/>
<aop:after-returning method=“after” pointcut-ref=“pointcut” />
<aop:after-throwing method=“exception” pointcut-ref=“pointcut”
throwing=“x”/>
<aop:around method=“around” pointcut-ref=“pointcut”/>
</aop:aspect>
</aop:config>
AOP 实现流程
1、aop:config 自定义标签解析
2、自定义标签解析时封装对应的 aop 入口类,类的类型就是 BeanPostProcessor 接口
类型
3、Bean 实现化过程中会执行到 aop 入口类中
4、在 aop 入口类中,判断当前正在实例化的类是否在 pointcut 中,pointcut 可以理
解为一个模糊匹配,是一个 joinpoint 的集合
5、如果当前正在实例化的类在 pointcut 中,则返回该 bean 的代理,同时把所有配置
的 advice 封装成 MethodInterceptor 对象加入到容器中,封装成一个过滤器链
代理对象调用,jdk 调到 invocationHandler 中,cglib 调到 MethodInterceptor 的
callback 类中,然后在 invoke 方法中执行过滤器链。

10. 讲解 Spring 框架中如何基于 AOP 实现的事务管理?

答:
事务管理,是一个切面。在 aop 环节中,其他环节都一样,事务管理就是有自己单独的
advice,有单独的通知,是 TransactionInterceptor,它一样的会在拦截器链中被执行到,
这个 TransactionInterceptor 拦截器类是通过解析tx:advice自定义标签得到的。

11. Spring 在 Bean 创建过程中是如何解决循环依赖的?

答:
循环依赖只会存在在单例实例中,多例循环依赖直接报错。
A 类实例化后,把实例放 map 容器中,A 类中有一个 B 类属性,A 类实例化要进行 IOC
依赖注入,这时候 B 类需要实例化,B 类实例化跟 A 类一样,实例化后方 map 容器中。B 类
中有一个 A 类属性,接着 B 类的 IOC 过程,又去实例化 A 类,这时候实例化 A 类过程中从
map 容器发现 A 类已经在容器中了,就直接返回了 A 的实例,依赖注入到 B 类中 A 属性中,
B 类 IOC 完成后,B 实例化就完全完成了,就返回给 A 类的 IOC 过程。这就是循环依赖的解
决。

12. Spring 中 Bean 是如何管理的?

答:
在 Spring 框架中,一旦把一个 bean 纳入到 Spring IoC 容器之中,这个 bean 的生命周
期就会交由容器进行管理,一般担当管理者角色的是 BeanFactory 或 ApplicationContext。
认识一下 Bean 的生命周期活动,对更好的利用它有很大的帮助。
概括来说主要有四个阶段:实例化,初始化,使用,销毁。

13. 请具体描述 IOC 容器对 Bean 的生命周期控制流程:

通过构造器或工厂方法创建 Bean 实例
. 为 Bean 的属性设置值和对其他 Bean 的引用
. 将 Bean 实例传递给 Bean 后置处理器的 postProcessBeforeInitialization 方法
. 调用 Bean 的初始化方法(init-method)
. 将 Bean 实例传递给 Bean 后置处理器的 postProcessAfterInitialization 方法
. Bean 可以使用了
. 当容器关闭时, 调用 Bean 的销毁方法(destroy-method)

14. BeanFactory 和 ApplicationContext 有什么区别?

1)BeanFactory 是 Spring 里面最底层的接口,包含了各种 Bean 的定义,读取 bean 配
置文档,管理 bean 的加载、实例化,控制 bean 的生命周期,维护 bean 之间的依赖关系。
ApplicationContext 接口作为 BeanFactory 的派生,除了提供 BeanFactory 所具有的功能
外,还提供了更完整的框架功能。
2)BeanFactroy 采用的是延迟加载形式来注入 Bean 的,即只有在使用到某个 Bean 时(调 用 getBean()),才对该 Bean 进行加载实例化。ApplicationContext 是在容器启动时,一次
性创建了所有的 Bean。这样在容器启动时,我们就可以发现 Spring 中存在的配置错误,这
样有利于检查所依赖属性是否注。
3)BeanFactory 通常以编程的方式被创建,ApplicationContext 还能以声明的方式创
建,如使用 ContextLoader。
4)BeanFactory 和 ApplicationContext 都支持 BeanPostProcessor 、
BeanFactoryPostProcessor 的使用,但两者之间的区别是:BeanFactory 需要手动注册,而
ApplicationContext 则是自动注册。

15. 谈谈 Spring Bean 创建过程中的设计模式?

策略模式、代理模式、适配器模式

16. Spring MVC 运行流程

答:
第一步:发起请求到前端控制器(DispatcherServlet)
第二步:前端控制器请求 HandlerMapping 查找 Handler( 可以根据 xml 配置、注解进
行查找)
第三步:处理器映射器 HandlerMapping 向前端控制器返回 Handler
第四步:前端控制器调用处理器适配器去执行 Handler
第五步:处理器适配器去执行 Handler
第六步:Handler 执行完成给适配器返回 ModelAndView
第七步:处理器适配器向前端控制器返回 ModelAndView(ModelAndView 是 springmvc
框架的一个底层对象,包括 Model 和 view)
第八步:前端控制器请求视图解析器去进行视图解析(根据逻辑视图名解析成真正的视
图(jsp))
第九步:视图解析器向前端控制器返回 View
第十步:前端控制器进行视图渲染( 视图渲染将模型数据(在 ModelAndView 对象中)
填充到 request 域)
第十一步:前端控制器向用户响应结果

17. Spring 框架中的单例 bean 是线程安全的吗?

一般的 Web 应用划分为展现层、服务层和持久层三个层次,在不同的层中编写对应的逻
辑,下层通过接口向上层开放功能调用。在一般情况下,从接收请求到返回响应所经过的所
有程序调用都同属于一个线程
ThreadLocal 是解决线程安全问题一个很好的思路,它通过为每个线程提供一个独立的
变量副本解决了变量并发访问的冲突问题。在很多情况下,ThreadLocal 比直接使用
synchronized 同步机制解决线程安全问题更简单,更方便,且结果程序拥有更高的并发性。
线程安全问题都是由全局变量及静态变量引起的。
无状态就是一次操作,不能保存数据。无状态对象(Stateless Bean),就是没有实例变
量的对象 .不能保存数据,是不变类,是线程安全的。
当然也可以通过加 sync 锁的方法来解决线程安全,这种以时间换空间的场景在高并发
场景下显然是不实际的。

18. 解释 Spring 支持的几种 bean 的作用域

Spring 框架支持以下五种 bean 的作用域:
singleton:bean 在每个 Springioc 容器中只有一个实例。
prototype:一个 bean 的定义可以有多个实例。
request :每次 http 请求都会创建 一 个 bean ,该作用域仅在基于 web 的
SpringApplicationContext 情形下有效。
session:在一个 HTTPSession 中,一个 bean 定义对应一个实例。该作用域仅在基于
web 的 SpringApplicationContext 情形下有效。
global-session:在一个全局的 HTTPSession 中,一个 bean 定义对应一个实例。该
作用域仅在基于 web 的 SpringApplicationContext 情形下有效。
缺省的 Springbean 的作用域是 Singleton.

19.解释 Spring 框架中 bean 的生命周期

Spring 容器从 XML 文件中读取 bean 的定义,并实例化 bean。
Spring 根据 bean 的定义填充所有的属性。
如果 bean 实现了 BeanNameAware 接口,Spring 传递 bean 的 ID 到 setBeanName
方法。
如 果 Bean 实现了 BeanFactoryAware 接口, Spring 传 递 beanfactory 给
setBeanFactory 方法。
如果有任何与 bean 相关联的 BeanPostProcessors , Spring 会 在
postProcesserBeforeInitialization()方法内调用它们。
如果 bean 实现 IntializingBean 了,调用它的 afterPropertySet 方法,
如果 bean 声明了初始化方法,调用此初始化方法。
如果有 BeanPostProcessors 和 bean 关联,这些 bean 的
postProcessAfterInitialization()方法将被调用。
如果 bean 实现了 DisposableBean,它将调用 destroy()方法。

20.哪些是重要的 bean 生命周期方法?你能重载它们吗?

有两个重要的 bean 生命周期方法,第一个是 setup,它是在容器加载 bean 的
时候被调用。第二个方法是 teardown 它是在容器卸载类的时候被调用。Thebean 标签
有两个重要的属性(init-method 和 destroy-method)。用它
们你可以自己定制初始化和注销方法。它们也有相应的注解(@PostConstruct
和@PreDestroy)。

二、SpringMvc面试题

1、什么是 SpringMvc?

答:SpringMvc 是 spring 的一个模块,基于 MVC 的一个框架,无需中间整合层来整合。

2、Spring MVC 的优点:

答:
1)它是基于组件技术的.全部的应用对象,无论控制器和视图,还是业务对象之类的都是 java
组件.并且和 Spring 提供的其他基础结构紧密集成. 2)不依赖于 Servlet API(目标虽是如此,但是在实现的时候确实是依赖于 Servlet 的) 3)可以任意使用各种视图技术,而不仅仅局限于 JSP
4)支持各种请求资源的映射策略
5)它应是易于扩展的

3、SpringMVC 工作原理?

答:
1)客户端发送请求到 DispatcherServlet
2)DispatcherServlet 查询 handlerMapping 找到处理请求的 Controller
3)Controller 调用业务逻辑后,返回 ModelAndView
4)DispatcherServlet 查询 ModelAndView,找到指定视图
5)视图将结果返回到客户端

4、SpringMVC 流程?

答:
1)用户发送请求至前端控制器 DispatcherServlet。 2)DispatcherServlet 收到请求调用 HandlerMapping 处理器映射器。
3)处理器映射器找到具体的处理器(可以根据 xml 配置、注解进行查找),生成处理器对象
及处理器拦截器(如果有则生成)一并返回给 DispatcherServlet。 4)DispatcherServlet 调用 HandlerAdapter 处理器适配器。
5)HandlerAdapter 经过适配调用具体的处理器(Controller,也叫后端控制器)。 6)Controller 执行完成返回 ModelAndView。
7)HandlerAdapter 将 controller 执行结果 ModelAndView 返回给 DispatcherServlet。 8)DispatcherServlet 将 ModelAndView 传给 ViewReslover 视图解析器。
9)ViewReslover 解析后返回具体 View。
10)DispatcherServlet 根据 View 进行渲染视图(即将模型数据填充至视图中)。
11)DispatcherServlet 响应用户。

5、SpringMvc 的控制器是不是单例模式,如果是,有什么问题,怎么解决?

答:是单例模式,所以在多线程访问的时候有线程安全问题,不要用同步,会影响性能的,解决
方案是在控制器里面不能写字段。

6、如果你也用过 struts2.简单介绍下 springMVC 和 struts2 的区别有哪些?

答:
1)springmvc 的入口是一个 servlet 即前端控制器,而 struts2 入口是一个 filter 过虑器。
2)springmvc 是基于方法开发(一个 url 对应一个方法),请求参数传递到方法的形参,可以
设计为单例或多例(建议单例),struts2 是基于类开发,传递参数是通过类的属性,只能设
计为多例。
3)Struts 采用值栈存储请求和响应的数据,通过 OGNL 存取数据,springmvc 通过参数解
析器是将 request 请求内容解析,并给方法形参赋值,将数据和视图封装成 ModelAndView
对象,最后又将 ModelAndView 中的模型数据通过 reques 域传输到页面。Jsp 视图解析器默
认使用 jstl。

7、SpingMvc 中的控制器的注解一般用那个,有没有别的注解可以替代?

答:一般用@Conntroller 注解,表示是表现层,不能用用别的注解代替。

8、 @RequestMapping 注解用在类上面有什么作用?

答:是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所
有响应请求的方法都是以该地址作为父路径。

9、怎么样把某个请求映射到特定的方法上面?

答:直接在方法上面加上注解@RequestMapping,并且在这个注解里面写上要拦截的路径

10、如果在拦截请求中,我想拦截 get 方式提交的方法,怎么配置?

答:可以在@RequestMapping 注解里面加上 method=RequestMethod.GET

11、怎么样在方法里面得到 Request,或者 Session?

答:直接在方法的形参中声明 request,SpringMvc 就自动把 request 对象传入

12、我想在拦截的方法里面得到从前台传入的参数,怎么得到?

答:直接在形参里面声明这个参数就可以,但必须名字和传过来的参数一样

13、如果前台有很多个参数传入,并且这些参数都是一个对象的,那么怎么样快速得到这个对象?

答:直接在方法中声明这个对象,SpringMvc 就自动会把属性赋值到这个对象里面。

14、SpringMvc 中函数的返回值是什么?

答:返回值可以有很多类型,有 String, ModelAndView,当一般用 String 比较好。

15、SpringMVC 怎么样设定重定向和转发的?

答:在返回值前面加"forward:“就可以让结果转发,譬如"forward:user.do?name=method4” 在
返回值前面加"redirect:“就可以让返回值重定向,譬如"redirect:http://www.baidu”

16、SpringMvc 用什么对象从后台向前台传递数据的?

答:通过 ModelMap 对象,可以在这个对象里面用 put 方法,把对象加到里面,前台就可以通
过 el 表达式拿到。

17、SpringMvc 中有个类把视图和数据都合并的一起的,叫什么?

答:叫 ModelAndView。

18、怎么样把 ModelMap 里面的数据放入 Session 里面?

答:可以在类上面加上@SessionAttributes 注解,里面包含的字符串就是要放入 session 里面
的 key

19、SpringMvc 怎么和 AJAX 相互调用的?

答:
通过 Jackson 框架就可以把 Java 里面的对象直接转化成 Js 可以识别的 Json 对象。
具体步骤如下 : 1)加入 Jackson.jar
2)在配置文件中配置 json 的映射
3)在接受 Ajax 方法里面可以直接返回 Object,List 等,但方法前面要加上@ResponseBody
注解

20、当一个方法向 AJAX 返回特殊对象,譬如 Object,List 等,需要做什么处理?

答:要加上@ResponseBody 注解

21、SpringMvc 里面拦截器是怎么写的

答:有两种写法,一种是实现接口,另外一种是继承适配器类,然后在 SpringMvc 的配置文件中
配置拦截器即可:

mvc:interceptors

mvc:interceptor
<mvc:mapping path="/modelMap.do" />

</mvc:interceptor>
</mvc:interceptors>

22、讲下 SpringMvc 的执行流程

答:系统启动的时候根据配置文件创建 spring 的容器, 首先是发送 http 请求到核心控制器
disPatherServlet,spring 容器通过映射器去寻找业务控制器,使用适配器找到相应的业务
类,在进业务类时进行数据封装,在封装前可能会涉及到类型转换,执行完业务类后使用
ModelAndView 进行视图转发,数据放在 model 中,用 map 传递数据进行页面显示。

更多推荐

Spring & SpringMvc 面试题及答案