老生常谈的Spring面试题
- 1、使用Spring框架的好处
- 2、Spring组成模块有哪些
- 3、解释AOP模块是什么?
- 4、Spring 应用程序有哪些不同组件
- 5、什么是 Spring IOC 容器
- 6、什么是依赖注入
- 7、可以通过多少种方式完成依赖注入
- 8、区分构造函数注入和 setter 注入
- 9、spring 中有多少种 IOC 容器
- 10、BeanFactory和ApplicationContext有什么区别
- 11、什么是 spring bean?
- 12、spring 提供了哪些配置方式?
- 13、spring 支持几种 bean scope
- 14、spring bean 容器的生命周期是什么样的?
- 15、什么是 spring 的内部 bean?
- 16、什么是 spring 装配
- 17、自动装配有哪些方式?
- 18、自动装配有什么局限?
- 19、什么是基于注解的容器配置
- 20、如何在 spring 中启动注解装配?
- 21、@Component, @Controller, @Repository,@Service 有何区别?
- 22、@Required 注解有什么用?
- 23、@Autowired 注解有什么用?
- 24、@Qualifier 注解有什么用?
- 25、列举 spring 支持的事务管理类型
- 26、spring 支持哪些 ORM 框架
- 27、什么是 AOP?
- 28、什么是 Aspect?
- 29、AOP 有哪些实现方式?
- 30、Spring AOP and AspectJ AOP 有什么区别?
- 31、解释一下Spring AOP里面的几个名词:
- 32 、Spring AOP advice通知类型:
- 33、如何理解 Spring 中的代理?
- 34、Spring MVC 框架有什么用?
- 35、描述下Spring MVC的工作流程
- 36、介绍一下 WebApplicationContext
- 37、Spring MVC的主要组件?
- 38、SpringMVC怎么样设定重定向和转发的?
- 39、SpringMvc的控制器是不是单例模式,如果是,有什么问题,怎么解决?
- 40、SpringMVC常用的注解有哪些?
以下是我在网上浏览数十个博客总结出来Spring比较常见的面试题,喜欢大家能喜欢,不喜勿喷!!!
1、使用Spring框架的好处
-
轻量:Spring是轻量的,基本的版本大约2MB。
-
控制反转:Spring通过控制反转实现了松散耦合,对象们给出它们的依赖,而不是创建或查找依赖的对象们。
-
面向切面的编程(AOP):Spring支持面向切面的编程,并且把应用业务逻辑和系统服务分开。
-
容器:Spring包含并管理应用中对象的生命周期和配置。
-
MVC框架:Spring的WEB框架是个精心设计的框架,是Web框架的一个很好的替代品。
-
事务管理:Spring提供一个持续的事务管理接口,可以扩展到上至本地事务下至全局事务(JTA)。
-
异常处理:Spring提供方便的API把具体技术相关的异常(比如由JDBC,HibernateorJDO抛出的)转化为一致的unchecked异常。
2、Spring组成模块有哪些
以下是Spring 框架的基本模块:
- Core module
- Bean module
- Context module
- Expression Language module
- JDBC module
- ORM module
- OXM module
- Java Messaging Service(JMS) module
- Transaction module
- Web module
- Web-Servlet module
- Web-Struts module
- Web-Portlet module
3、解释AOP模块是什么?
AOP模块用于发给我们的Spring应用做面向切面的开发,很多支持由AOP联盟提供,这样就确保了Spring和其他AOP框架的共通性。这个模块将元数据编程引入Spring。
4、Spring 应用程序有哪些不同组件
Spring 应用一般有以下组件:
(1) 接口 - 定义功能。
(2)Bean 类 - 它包含属性,setter 和 getter 方法,函数等。
(3)Spring 面向切面编程(AOP) - 提供面向切面编程的功能。
(4)Bean 配置文件 - 包含类的信息以及如何配置它们。
(5)用户程序 - 它使用接口。
5、什么是 Spring IOC 容器
Spring 框架的核心是 Spring 容器。容器创建对象,将它们装配在一起,配置它们并管理它们的完整生命周期。Spring 容器使用依赖注入来管理组成应用程序的组件。容器通过读取提供的配置元数据来接收对象进行实例化,配置和组装的指令。该元数据可以通过 XML,Java 注解或 Java 代码提供。
6、什么是依赖注入
在依赖注入中,您不必创建对象,但必须描述如何创建它们。您不是直接在代码 中将组件和服务连接在一起,而是描述配置文件中哪些组件需要哪些服务。由 IoC 容器将它们装配在一起。
7、可以通过多少种方式完成依赖注入
通常,依赖注入可以通过三种方式完成,即:
(1)构造函数注入
(2)setter 注入
(3) 接口注入(Spring4.0之后取消了)
8、区分构造函数注入和 setter 注入
构造方法注入 | Setter注入 |
---|---|
没有部分注入 | 有部分注入 |
不会覆盖setter属性 | 会覆盖setter属性 |
适用于设置很多属性 | 适用于设置少量属性 |
9、spring 中有多少种 IOC 容器
1、BeanFactory: BeanFactory 就像一个包含 bean 集合的工厂类。它会在客户端要求时实例化 bean。
2、ApplicationContext:ApplicationContext 接口扩展了 BeanFactory 接口。它在 BeanFactory 基础上提供了一些额外的功能(如第10条所示)。
10、BeanFactory和ApplicationContext有什么区别
BeanFactory和ApplicationContext是Spring的两大核心接口,都可以当做Spring的容器。其ApplicationContext是BeanFactory的子接口。
(1)BeanFactory:是Spring里面最底层的接口,包含了各种Bean的定义,读取bean配置文档,管理bean的加载、实例化,控制bean的生命周期,维护bean之间的依赖关系。ApplicationContext接口作为BeanFactory的派生,除了提供BeanFactory所具有的功能外,还提供了更完整的框架功能:
- 继承MessageSource,因此支持国际化。
- 统一的资源文件访问方式。
- 提供在监听器中注册bean的事件。
- 同时加载多个配置文件。
- 载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层。
(2)
-
BeanFactroy采用的是延迟加载形式来注入Bean的,即只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化。这样,我们就不能发现一些存在的Spring的配置问题。如果Bean的某一个属性没有注入,BeanFacotry加载后,直至第一次使用调用getBean方法才会抛出异常。
-
ApplicationContext,它是在容器启动时,一次性创建了所有的Bean。这样,在容器启动时,我们就可以发现Spring中存在的配置错误,这样有利于检查所依赖属性是否注入。 ApplicationContext启动后预载入所有的单实例Bean,通过预载入单实例bean ,确保当你需要的时候,你就不用等待,因为它们已经创建好了。
-
相对于基本的BeanFactory,ApplicationContext 唯一的不足是占用内存空间。当应用程序配置Bean较多时,程序启动较慢。
(3)BeanFactory通常以编程的方式被创建,ApplicationContext还能以声明的方式创建,如使用ContextLoader。
(4)BeanFactory和ApplicationContext都支持BeanPostProcessor、BeanFactoryPostProcessor的使用,但两者之间的区别是:BeanFactory需要手动注册,而ApplicationContext则是自动注册。
11、什么是 spring bean?
(1)它们是构成用户应用程序主干的对象。
(2)Bean 由 Spring IoC 容器管理。
(3)它们由 Spring IoC 容器实例化,配置,装配和管理。
(4)Bean 是基于用户提供给容器的配置元数据创建。
12、spring 提供了哪些配置方式?
- XML
- JavaConfig
- 注解
13、spring 支持几种 bean scope
- singleton:默认,每个容器中只有一个bean的实例,单例的模式由BeanFactory自身来维护。
- prototype:为每一个bean请求提供一个实例。
- request:为每一个网络请求创建一个实例,在请求完成以后,bean会失效并被垃圾回收器回收。
- session:与request范围类似,确保每个session中有一个bean的实例,在session过期后,bean会随之失效。
- global-session:全局作用域,global-session和Portlet应用相关。当你的应用部署在Portlet容器中工作时,它包含很多portlet。如果你想要声明让所有的portlet共用全局的存储变量的话,那么这全局变量需要存储在global-session中。全局作用域与Servlet中的session作用域效果相同。
14、spring bean 容器的生命周期是什么样的?
spring bean 容器的生命周期流程如下:
(1)Spring 容器根据配置中的 bean 定义中实例化 bean。
(2)Spring 使用依赖注入填充所有属性,如 bean 中所定义的配置。
(3)如果 bean 实现BeanNameAware 接口,则工厂通过传递 bean 的 ID 来调用setBeanName()。
(4)如果 bean 实现 BeanFactoryAware 接口,工厂通过传递自身的实例来调用 setBeanFactory()。
(5)如果存在与 bean 关联的任何BeanPostProcessors,则调用preProcessBeforeInitialization() 方法。
(6)如果为 bean 指定了 init 方法( 的 init-method 属性),那么将调 用它。
(7)最后,如果存在与 bean 关联的任何 BeanPostProcessors,则将调用 postProcessAfterInitialization() 方法。
(8)如果 bean 实现DisposableBean 接口,当 spring 容器关闭时,会调用 destory()。
(9)如果为bean 指定了 destroy 方法( 的 destroy-method 属性),那么将 调用它。
15、什么是 spring 的内部 bean?
只有将 bean 用作另一个 bean 的属性时,才能将 bean 声明为内部 bean。为了定义 bean,Spring 的基于 XML 的配置元数据在 或 中提供了 元素的使用。内部 bean 总是匿名的,它们总是作为原型。
16、什么是 spring 装配
当 bean 在 Spring 容器中组合在一起时,它被称为装配或 bean 装配。Spring容器需要知道需要什么 bean 以及容器应该如何使用依赖注入来将 bean 绑定在一起,同时装配 bean。
17、自动装配有哪些方式?
-
no - 这是默认设置,表示没有自动装配。应使用显式 bean 引用进行装配。
-
byName - 它根据 bean 的名称注入对象依赖项。它匹配并装配其属性与 XML文件中由相同名称定义的 bean。
-
byType - 它根据类型注入对象依赖项。如果属性的类型与 XML 文件中的一个 bean 名称匹配,则匹配并装配属性。构造函数- 它通过调用类的构造函数来注入依赖项。它有大量的参数。
-
autodetect - 首先容器尝试通过构造函数使用 autowire 装配,如果不能,则尝试通过 byType 自动装配。
18、自动装配有什么局限?
- 覆盖的可能性 - 您始终可以使用 和 设置指定依赖项,这将覆盖自动装配。
- 基本元数据类型 - 简单属性(如原数据类型,字符串和类)无法自动装配。令人困惑的性质 - 总是喜欢使用明确的装配,因为自动装配不太精确。
19、什么是基于注解的容器配置
不使用 XML 来描述 bean 装配,开发人员通过在相关的类,方法或字段声明上使用注解将配置移动到组件类本身。它可以作为 XML 设置的替代方案。例如:Spring 的 Java 配置是通过使用 @Bean 和 @Configuration 来实现。
@Bean 注解扮演与 元素相同的角色。 @Configuration 类允许通过简单地调用同一个类中的其他 @Bean 方法来定义 bean 间依赖关系。
20、如何在 spring 中启动注解装配?
默认情况下,Spring 容器中未打开注解装配。因此,要使用基于注解装配,我们必须通过配置 <context:annotation-config/> 元素在 Spring 配置文件中启用它。
21、@Component, @Controller, @Repository,@Service 有何区别?
@Component :这将 java 类标记为 bean。它是任何 Spring 管理组件的通用构造型。spring 的组件扫描机制现在可以将其拾取并将其拉入应用程序环境中。
@Controller :这将一个类标记为 Spring Web MVC 控制器。标有它的Bean 会自动导入到 IoC 容器中。
@Service :此注解是组件注解的特化。它不会对 @Component 注解提供任何其他行为。您可以在服务层类中使用@Service 而不是 @Component,因为它以更好的方式指定了意图。
@Repository :这个注解是具有类似用途和功能的 @Component 注解的特化。它为 DAO 提供了额外的好处。它将 DAO 导入 IoC 容器,并使未经检查的异常有资格转换为 Spring DataAccessException。
22、@Required 注解有什么用?
@Required 应用于 bean 属性 setter 方法。此注解仅指示必须在配置时使用bean 定义中的显式属性值或使用自动装配填充受影响的 bean 属性。如果尚未填充受影响的 bean 属性,则容器将抛出 BeanInitializationException
23、@Autowired 注解有什么用?
@Autowired 可以更准确地控制应该在何处以及如何进行自动装配。此注解用于在 setter 方法,构造函数,具有任意名称或多个参数的属性或方法上自动装配bean。默认情况下,它是根据bytepe的注入。
24、@Qualifier 注解有什么用?
当您创建多个相同类型的 bean 并希望仅使用属性装配其中一个 bean 时,您可以使用@Qualifier 注解和 @Autowired 通过指定应该装配哪个确切的 bean来消除歧义。
25、列举 spring 支持的事务管理类型
Spring 支持两种类型的事务管理:
(1)程序化事务管理:在此过程中,在编程的帮助下管理事务。它为您提供极大的灵活性,但维护起来非常困难。
(2) 声明式事务管理:在此,事务管理与业务代码分离。仅使用注解或基于 XML的配置来管理事务。
26、spring 支持哪些 ORM 框架
-
Hibernate
-
iBatis
-
JPA
-
JDO
-
OJB
27、什么是 AOP?
AOP(Aspect-Oriented Programming), 即 面向切面编程, 它与OOP( Object-Oriented Programming, 面向对象编程) 相辅相成, 提供了与OOP 不同的抽象软件结构的视角. 在 OOP 中, 我们以类(class)作为我们的基本单元, 而 AOP 中的基本单元是 Aspect(切面)
28、什么是 Aspect?
aspect 由 pointcount 和 advice 组成, 它既包含了横切逻辑的定义, 也包括了连接点的定义. Spring AOP 就是负责实施切面的框架, 它将切面所定义的横切逻辑编织到切面所指定的连接点中. AOP 的工作重心在于如何将增强编织目标对象的连接点上, 这里包含两个工作:
(1)如何通过 pointcut 和 advice 定位到特定的 joinpoint 上
(2)如何在advice 中编写切面代码.
29、AOP 有哪些实现方式?
实现 AOP 的技术,主要分为两大类:
- 静态代理
指使用 AOP 框架提供的命令进行编译,从而在编译阶段就可生成 AOP 代理类,因此也称为编译时增强;
(1)编译时编织(特殊编译器实现)
(2)类加载时编织(特殊的类加载器实现)。
- 动态代理
在运行时在内存中“临时”生成 AOP 动态代理类,因此也被称为运行时增强。
(1)JDK 动态代理
(2)CGLIB
30、Spring AOP and AspectJ AOP 有什么区别?
Spring AOP 基于动态代理方式实现;AspectJ 基于静态代理方式实现。SpringAOP 仅支持方法级别的 PointCut;提供了完全的 AOP 支持,它还支持属性级别的 PointCut。
31、解释一下Spring AOP里面的几个名词:
- 切面(Aspect):被抽取的公共模块,可能会横切多个对象。 在Spring AOP中,切面可以使用通用类(基于模式的风格) 或者在普通类中以 @AspectJ 注解来实现。
- 连接点(Join point):指方法,在Spring AOP中,一个连接点 总是 代表一个方法的执行。
- 通知(Advice):在切面的某个特定的连接点(Join point)上执行的动作。通知有各种类型,其中包括“around”、“before”和“after”等通知。许多AOP框架,包括Spring,都是以拦截器做通知模型, 并维护一个以连接点为中心的拦截器链。
- 切入点(Pointcut):切入点是指 我们要对哪些Join point进行拦截的定义。通过切入点表达式,指定拦截的方法,比如指定拦截add*、search*。
- 引入(Introduction):(也被称为内部类型声明(inter-type declaration))。声明额外的方法或者某个类型的字段。Spring允许引入新的接口(以及一个对应的实现)到任何被代理的对象。例如,你可以使用一个引入来使bean实现 IsModified 接口,以便简化缓存机制。
- 目标对象(Target Object): 被一个或者多个切面(aspect)所通知(advise)的对象。也有人把它叫做 被通知(adviced) 对象。 既然Spring AOP是通过运行时代理实现的,这个对象永远是一个 被代理(proxied) 对象。
- 代理对象(aop Proxy ) 包含了原始对象的代码和增加后的代码的那个对象
- 织入(Weaving):指把增强应用到目标对象来创建新的代理对象的过程。Spring是在运行时完成织入。
切入点(pointcut)和连接点(join point)匹配的概念是AOP的关键,这使得AOP不同于其它仅仅提供拦截功能的旧技术。 切入点使得定位通知(advice)可独立于OO层次。 例如,一个提供声明式事务管理的around通知可以被应用到一组横跨多个对象中的方法上(例如服务层的所有业务操作)。
32 、Spring AOP advice通知类型:
-
Before 连接点执行之前,但是无法阻止连接点的正常执行,除非该段执行抛出异常
-
After 连接点正常执行之后,执行过程中正常执行返回退出,非异常退出
-
After throwing 执行抛出异常的时候
-
After (finally) 无论连接点是正常退出还是异常退出,都会执行
-
Around advice: 围绕连接点执行,例如方法调用。这是最有用的切面方式。around通知可以在方法调用之前和之后执行自定义行为。它还负责选择是继续加入点还是通过返回自己的返回值或抛出异常来快速建议的方法执行。
33、如何理解 Spring 中的代理?
将 Advice 应用于目标对象后创建的对象称为代理。在客户端对象的情况下,目标对象和代理对象是相同的。 Advice + Target Object = Proxy
34、Spring MVC 框架有什么用?
Spring Web MVC 框架提供 模型-视图-控制器 架构和随时可用的组件,用于开发灵活且松散耦合的 Web 应用程序。MVC 模式有助于分离应用程序的不同方面,如输入逻辑,业务逻辑和 UI 逻辑,同时在所有这些元素之间提供松散耦合。
35、描述下Spring MVC的工作流程
(1)向服务器发送 HTTP 请求,请求被前端控制器 DispatcherServlet 捕获。
(2) DispatcherServlet 根据 -servlet.xml 中的配置对请求的 URL 进行解析,得到请求资源标识符(URI)。然后根据该 URI,调用 HandlerMapping获得该 Handler 配置的所有相关的对象(包括 Handler 对象以及 Handler 对象对应的拦截器),最后以HandlerExecutionChain 对象的形式返回。
(3) DispatcherServlet 根据获得的 Handler,选择一个合适的HandlerAdapter。(附注:如果成功获得 HandlerAdapter 后,此时将开始执行拦截器的 preHandler(…)方法)
(4)提取 Request 中的模型数据,填充 Handler 入参,开始执行 Handler( Controller)。在填充 Handler 的入参过程中,根据你的配置,Spring 将帮你做一些额外的工作:
1) HttpMessageConveter:将请求消息(如 Json、xml 等数据)转换成一个对象,将对象转换为指定的响应信息。
2)数据转换:对请求消息进行数据转换。如 String 转换成 Integer、Double 等。
3)数据根式化:对请求消息进行数据格式化。如将字符串转换成格式化数字或格式化日期等。
4)数据验证:验证数据的有效性(长度、格式等),验证结果存储到BindingResult 或 Error 中。
(5)Handler(Controller)执行完成后,向 DispatcherServlet 返回一个ModelAndView 对象;
(6)根据返回的 ModelAndView,选择一个适合的 ViewResolver(必须是已经注册到 Spring 容器中的 ViewResolver)返回给 DispatcherServlet。
(7) ViewResolver 结合 Model 和 View,来渲染视图。
(8)视图负责将渲染结果返回给客户端。
36、介绍一下 WebApplicationContext
WebApplicationContext 是 ApplicationContext 的扩展。它具有 Web 应用程序所需的一些额外功能。它与普通的 ApplicationContext 在解析主题和决定与哪个 servlet 关联的能力方面有所不同。
37、Spring MVC的主要组件?
(1)前端控制器 DispatcherServlet(不需要程序员开发)
作用:接收请求、响应结果,相当于转发器,有了DispatcherServlet 就减少了其它组件之间的耦合度。
(2)处理器映射器HandlerMapping(不需要程序员开发)
作用:根据请求的URL来查找Handler
(3)处理器适配器HandlerAdapter
注意:在编写Handler的时候要按照HandlerAdapter要求的规则去编写,这样适配器HandlerAdapter才可以正确的去执行Handler。
(4)处理器Handler(需要程序员开发)
(5)视图解析器 ViewResolver(不需要程序员开发)
作用:进行视图的解析,根据视图逻辑名解析成真正的视图(view)
(6)视图View(需要程序员开发jsp)
View是一个接口, 它的实现类支持不同的视图类型(jsp,freemarker,pdf等等)
38、SpringMVC怎么样设定重定向和转发的?
(1)转发:在返回值前面加"forward:",譬如"forward:user.do?name=method4"
(2)重定向:在返回值前面加"redirect:",譬如"redirect:http://www.baidu.com"
39、SpringMvc的控制器是不是单例模式,如果是,有什么问题,怎么解决?
是单例模式,所以在多线程访问的时候有线程安全问题,不要用同步,会影响性能的,解决方案是在控制器里面不能写成员变量。
40、SpringMVC常用的注解有哪些?
@RequestMapping:用于处理请求 url 映射的注解,可用于类或方法上。用于类上,则表示类中的所有响应请求的方法都是以该地址作为父路径。
@RequestBody:注解实现接收http请求的json数据,将json转换为java对象。
@ResponseBody:注解实现将conreoller方法返回对象转化为json对象响应给客户。