Spring Framework 最初由 Rod Johnson 于 2003 年开发。开发它的目的是为了让开发人员更快、更轻松、更安全地开发 Java 应用程序。Spring Framework 是一个开源的、轻量级的、易于构建的框架,它也可以被认为是一个框架框架,因为它包含了各种框架,如依赖注入、Spring MVC、Spring JDBC、Spring Hibernate、Spring AOP、EJB、JSF等。Spring 的一个关键元素是应用程序的基础设施支持特性。Spring 专注于提供企业级应用程序的“管道”,并确保开发人员可以完全专注于应用程序级业务逻辑,而无需与特定部署环境产生不必要的联系。在 Spring 中开发的应用程序更可靠、可扩展,并且构建和维护非常简单。Spring 的开发目的是帮助开发人员管理应用程序的业务对象。由于其丰富的特性和灵活性,Spring 成为开发企业级基于 Java 的应用程序最受欢迎的框架。在下一节中,我们将看到Spring常见面试题和答案合集,以便为基于 Spring 的面试做好准备。
Spring、Spring Core、Spring IoC 面试题
1.什么是Spring框架?
- Spring 是一个强大的开源、松散耦合、轻量级的Java 框架,旨在降低开发企业级应用程序的复杂性。该框架也被称为“框架的框架”,因为 spring 为各种其他重要的框架提供支持,如 JSF、Hibernate、Structs、EJB 等。
- 大约有 20 个模块,它们概括为以下类型:
- 核心容器
- 数据访问/集成
- 网络
- AOP(面向方面编程)
- 仪表
- 消息传递
- 测试
Spring 处理所有与基础设施相关的方面,这让程序员可以主要专注于应用程序开发。
2. Spring常见面试题有哪些:Spring Framework 有哪些特点?
- Spring 框架遵循分层架构模式,有助于选择必要的组件,同时为 J2EE 应用程序开发提供一个健壮且内聚的框架。
- Spring 的 AOP(面向方面编程)部分通过确保将应用程序的业务逻辑与其他系统服务分离来支持统一开发。
- Spring 提供了高度可配置的MVC Web 应用程序框架,可以轻松切换到其他框架。
- 提供配置的创建和管理以及定义应用程序对象的生命周期。
- Spring 有一个特殊的设计原则,称为 IoC(控制反转),它支持对象提供它们的依赖关系,而不是寻找创建依赖对象。
- Spring 是一个轻量级的、基于 Java 的、松散耦合的框架。
- Spring为事务管理提供了通用抽象层,这对于无容器环境也非常有用。
- Spring 提供了一个方便的 API 来将特定于技术的异常(由 JDBC、Hibernate 或其他框架抛出)转换为一致的、未经检查的异常。这引入了抽象并大大简化了异常处理。
3、什么是Spring配置文件?
Spring面试题解析:Spring 配置文件基本上是一个 XML 文件,主要包含类信息并描述这些类是如何配置和相互链接的。XML 配置文件详细而清晰。
4、IoC(控制反转)容器是什么意思?
Spring 容器构成了 Spring 框架的核心。Spring 容器使用依赖注入 (DI) 通过创建对象、将它们连接在一起以及配置和管理它们的整个生命周期来管理应用程序组件。可以通过 XML 配置、Java 注释或 Java 代码提供 Spring 容器执行任务的说明。
5、你怎么理解依赖注入?
依赖注入的主要思想是你不必创建你的对象,而你只需要描述它们应该如何创建。
- 组件和服务不需要我们直接在代码中连接。我们必须在配置文件中描述哪些组件需要哪些服务。Spring 中的 IoC 容器会将它们连接在一起。
- 在 Java 中,实现依赖注入的两种主要方式是:
- 构造函数注入:在这里,IoC 容器使用多个参数调用类构造函数,其中每个参数代表对另一个类的依赖。
- Setter 注入:这里,spring 容器在调用无参数静态工厂方法或默认构造函数实例化 bean 后调用 bean 上的 setter 方法。
6.解释构造函数和setter注入的区别?
- 在构造函数注入中,部分注入是不允许的,而在 setter 注入中是允许的。
- 构造函数注入不会覆盖 setter 属性,而 setter 注入则不然。
- 如果进行了任何修改,构造函数注入会创建一个新实例。在 setter 注入中无法创建新实例。
- 如果 bean 具有许多属性,则首选构造函数注入。如果它的属性很少,则首选 setter 注入。
7. 什么是 Spring Bean?
- 它们是构成用户应用程序主干的对象,由 Spring IoC 容器管理。
- Spring bean 由 IoC 容器实例化、配置、连接和管理。
- Bean 是使用用户提供给容器的配置元数据创建的(通过 XML 或 Java 注释配置)。
8、配置元数据是如何提供给spring容器的?
有 3 种方式提供配置元数据。它们如下:
- 基于 XML 的配置: bean 配置及其依赖项在 XML 配置文件中指定。这从一个 bean 标记开始,如下所示:
<bean id="interviewBitBean" class="org.intervuewBit.firstSpring.InterviewBitBean">
<property name="name" value="InterviewBit"></property>
</bean>
- 基于注解的配置:代替 XML 方法,可以通过在相关类、方法或字段声明上使用注解将 bean 配置到组件类本身中。
- 默认情况下,注解连接在 Spring 容器中处于非活动状态。这必须在 Spring XML 配置文件中启用,如下所示
<beans>
<context:annotation-config/>
<!-- bean definitions go here -->
</beans>
- 基于 Java 的配置: Spring Framework 引入了关键特性作为新的 Java 配置支持的一部分。这利用了@Configuration注释类和@Bean注释方法。注意:
- @Bean 注释与 <bean/> 元素具有相同的作用。
- 用@Configuration 注释的类允许通过简单地调用同一类中的其他@Bean 方法来定义 bean 间的依赖关系。
9. Spring 有哪些 bean 作用域?
Spring 框架有五个范围支持。他们是:
- 单例:使用此方法时 bean 定义的范围将是每个 IoC 容器的单个实例。
- 原型:这里,单个 bean 定义的范围可以是任意数量的对象实例。
- 请求: bean 定义的范围是一个 HTTP 请求。
- Session:这里bean定义的范围是HTTP-session。
- Global-session:这里bean定义的范围是一个Global HTTP session。
注意:仅当用户使用 Web 感知 ApplicationContext 容器时,最后三个范围才可用。
10.解释Spring Bean Factory Container中的Bean生命周期。
Bean生命周期如下:
- IoC 容器根据 XML 文件中 bean 的定义实例化 bean。
- 然后,Spring 使用 bean 定义中指定的依赖项注入来填充所有属性。
setBeanName()
获取 bean ID 和相应 bean的 bean 工厂容器调用必须实现BeanNameAware
接口。- 然后工厂
setBeanFactory()
通过传递自身的实例进行调用(如果在 bean 中实现了 BeanFactoryAware 接口)。 - 如果
BeanPostProcessors
与 bean 相关联,则preProcessBeforeInitialization()
调用这些方法。 - 如果指定了 init-method,则将调用它。
- 最后,
postProcessAfterInitialization()
如果有任何 BeanPostProcessor 与需要在创建后运行的 bean 相关联,则将调用方法。
11.你对Bean Wiring的理解是什么。
- 当 bean 在 Spring 容器内组合在一起时,它们被称为被连接或这种现象称为 bean 连接。
- Spring 容器应该知道需要哪些 bean 以及在连接 bean 时这些 bean 如何相互依赖。这是通过基于 XML/注释/Java 代码的配置给出的。
12. 什么是自动装配及其不同模式的名称?
IoC 容器自动装配应用程序 bean 之间的关系。Spring 允许协作者通过检查 BeanFactory 的内容来确定哪些 bean 必须自动连接。
这个过程的不同模式是:
- no:这意味着没有自动装配并且是默认设置。应使用显式 bean 引用进行接线。
- byName:根据bean的名称注入bean依赖。这将其属性与根据配置定义的相同名称的 bean 进行匹配和连接。
- byType:这会根据类型注入 bean 依赖项。
- 构造函数:在这里,它通过调用类的构造函数来注入 bean 依赖项。它有大量的参数。
- autodetect:首先,容器尝试通过构造函数使用自动装配进行连接,如果不可能,则尝试通过 byType 进行自动装配。
13. 自动装配有哪些限制?
- 重写可能性:依赖使用指定
<constructor-arg>
和<property>
设置,覆盖自动装配。 - 数据类型限制:原始数据类型、字符串和类不能自动装配。
Spring Boot 面试题
14.你对“Spring Boot”一词的理解是什么?
Spring Boot 是一个开源的、基于 Java 的框架,它为快速应用程序开发提供支持,并为开发独立和生产就绪的 Spring 应用程序提供了一个平台,只需要很少的配置。
15. 解释使用 Spring Boot 进行应用程序开发的优势。
- Spring Boot 有助于创建可以使用 java.jar 启动的独立应用程序(不需要配置 WAR 文件)。
- Spring Boot 还为 Maven 配置提供了精确的“启动”POM。
- 可以直接嵌入 Undertow、Tomcat、Jetty 或其他 Web 服务器。
- 自动配置:提供一种根据类路径上存在的依赖关系自动配置应用程序的方法。
- Spring Boot 的开发旨在减少代码行。
- 它提供生产就绪的支持,例如监控和使用 spring boot 开发的应用程序更容易启动。
16. 区分 Spring 和 Spring Boot。
- Spring Framework 提供了多种特性,如依赖注入、数据绑定、面向方面的编程 (AOP)、数据访问等,有助于更轻松地开发 Web 应用程序,而 Spring Boot 通过简化或管理各种松散耦合的 Spring 块,它们很乏味并且有可能变得混乱。
- Spring boot 简化了常用的 spring 依赖项,并直接从命令行运行应用程序。它还不需要应用程序容器,它有助于监视多个组件并在外部配置它们。
17、Spring Boot有哪些特点?
- Spring Boot CLI – 这允许你使用 Groovy / Maven 编写 Spring Boot 应用程序并避免样板代码。
- Starter Dependency – 借助该特性,Spring Boot 将常见的依赖聚合在一起,最终提高生产力并减轻
- Spring Initializer – 这是一个 Web 应用程序,可帮助开发人员创建内部项目结构。开发者在使用此功能时无需手动设置项目的结构。
- 自动配置- 这有助于根据你正在处理的项目加载默认配置。这样,可以避免不必要的 WAR 文件。
- Spring Actuator – Spring Boot 使用执行器提供“管理端点”,帮助开发人员检查应用程序内部、指标等。
- 日志记录和安全性——这确保所有使用 Spring Boot 制作的应用程序都得到适当的保护,没有任何麻烦。
18、Spring常见面试题和答案合集:@SpringBootApplication注解在内部有什么作用?
根据 Spring Boot 文档,@SpringBootApplication 注释是使用 @Configuration、@EnableAutoConfiguration 和 @ComponentScan 注释及其默认属性的一点替代。
这使开发人员能够使用单个注释而不是使用多个注释,从而减少代码行数。但是,Spring 提供了松散耦合的特性,这就是我们可以根据项目需要使用这些注解的原因。
19. 将 Spring Boot 应用程序作为“Java 应用程序”运行有什么影响?
- 一旦发现我们正在运行一个 Web 应用程序,该应用程序就会自动启动 tomcat 服务器。
20、什么是Spring Boot依赖管理系统?
- 它基本上用于自动管理依赖项和配置,而无需为任何依赖项指定版本。
21. 外部配置的可能来源有哪些?
- Spring Boot 利用其外部配置的特性,允许开发人员在不同的环境中运行相同的应用程序。这使用环境变量、属性文件、命令行参数、YAML 文件和系统属性来提及其相应环境所需的配置属性。以下是外部配置的来源:
- 命令行属性——Spring Boot 提供对命令行参数的支持,并将这些参数转换为属性,然后将它们添加到环境属性集中。
- 应用程序属性——默认情况下,Spring Boot 在应用程序的当前目录、类路径根目录或 config 目录中搜索应用程序属性文件或其 YAML 文件来加载属性。
- 特定于配置文件的属性- 从
application-{profile}.properties file
YAML 文件或它的 YAML 文件加载属性。此文件与非特定属性文件位于同一位置,{profile} 占位符指的是活动配置文件或环境。
22、Spring boot中可以更改内嵌Tomcat服务器的默认端口吗?
- 是的,我们可以通过使用应用程序属性文件来更改它,方法是添加一个属性
server.port
并将其分配给你希望的任何端口。 - 比如你想让端口是8081,那你就得提
server.port=8081
. 一旦提到端口号,Spring Boot 将自动加载应用程序属性文件,并将指定的配置应用于应用程序。
23. 你能说出如何在不使用 basePackages 过滤器的情况下排除任何包吗?
我们可以exclude
在使用注解的同时使用属性@SpringBootApplication
,如下所示:
@SpringBootApplication(exclude= {Student.class})
public class InterviewBitAppConfiguration {}
24.如何禁用特定的自动配置类?
- 为此,你可以使用 的
exclude
属性,@EnableAutoConfiguration
如下所示:
@EnableAutoConfiguration(exclude = {InterviewBitAutoConfiguration.class})
如果类路径上未指定类,我们可以指定完全限定名称作为excludeName
.
//By using "excludeName"
@EnableAutoConfiguration(excludeName={Foo.class})
- 你可以添加到 application.properties 中,并且可以通过保持逗号分隔来添加多个类。
25、Spring常见面试题有哪些:Spring Boot应用中的默认web服务器可以禁用吗?
是的!application.properties
用于配置 Web 应用程序类型,提及spring.main.web-application-type=none
.
26、Spring Boot中@RequestMapping和@RestController注解有什么用?
- @RequestMapping:
- 这提供了路由信息并通知 Spring 任何与 URL 匹配的 HTTP 请求都必须映射到相应的方法。
org.springframework.web.bind.annotation.RequestMapping
必须导入才能使用此注释。
- @RestController:
- 这应用于类以将其标记为请求处理程序,从而使用 Spring MVC 创建 RESTful Web 服务。此批注向类添加了@ResponseBody 和@Controller 批注。
org.springframework.web.bind.annotation.RestController
必须导入才能使用此注释。
在此处查看有关 Spring Boot 的更多面试问题。
Spring AOP、Spring JDBC、Spring Hibernate面试题
27.什么是Spring AOP?
- Spring AOP(面向方面编程)类似于 OOP(面向对象编程),因为它也提供模块化。
- 在 AOP 中,关键单元是方面或关注点,它们只不过是应用程序中的独立模块。有些方面有集中的代码,但其他方面可能是分散或混乱的代码,例如在日志记录或事务的情况下。这些分散的方面称为横切关注点。
- 事务管理、身份验证、日志记录、安全性等跨领域关注点可能会影响整个应用程序,为了安全性和模块化目的,应尽可能将其集中在代码中的一个位置。
- AOP 提供了平台,通过使用简单的可插拔配置,在实际逻辑之前、之后或周围动态添加这些横切关注点。
- 这导致代码易于维护。只需修改配置文件即可添加或删除关注点,因此无需重新编译完整的源代码。
- 有两种类型的 Spring AOP 实现:
- 使用 XML 配置文件
- 使用 AspectJ 注释样式
28.什么是advice?解释它在Spring的类型。
Spring面试题解析:一个建议是横切关注点的实现可以应用于 spring 应用程序的其他模块。建议主要有5种类型:
- Before:
- 这个通知在连接点之前执行,但它没有能力阻止执行流继续到连接点(除非它抛出异常)。
- 要使用它,请使用 @Before 注释。
- AfterReturning:
- 该建议将在连接点正常完成后执行,即如果方法返回而没有抛出异常。
- 要使用它,请使用 @AfterReturning 注释。
- AfterThrowing:
- 如果方法通过抛出异常退出,则将执行此建议。
- 要使用它,请使用 @AfterThrowing 注释。
- After:
- 无论连接点以何种方式退出(正常返回或遇到异常),都将执行此建议。
- 要使用它,请使用 @After 注释。
- Around:
- 这是围绕连接点(例如方法调用)的最强大的建议。
- 要使用它,请使用 @Around 注释。
29、什么是Spring AOP代理模式?
- 代理模式是一种很好用的设计模式,其中代理是一个看起来像另一个对象但在幕后为其添加特殊功能的对象。
- Spring AOP 遵循基于代理的模式,这是由 AOP 框架创建的,用于在运行时实现方面契约。
- 标准的 JDK 动态代理是默认的 AOP 代理,它允许代理任何接口。Spring AOP 还可以使用代理类而不是接口所需的 CGLIB 代理。如果业务对象未实现接口,则默认使用 CGLIB 代理。
30. Spring JDBC API 有哪些类?
- 以下是课程
- 数据库模板
- 简单的Jdbc模板
- 命名参数Jdbc模板
- 简单的Jdbc插入
- 简单的JdbcCall
- 最常用的一种是 JdbcTemplate。这内部使用JDBC API,优点是我们不需要创建连接、语句、启动事务、提交事务和关闭连接来执行不同的查询。所有这些都由 JdbcTemplate 自己处理。开发人员可以专注于直接执行查询。
31. Spring JdbcTemplate 如何获取记录?
这可以通过使用 JdbcTemplate 的查询方法来完成。有两个接口可以帮助做到这一点:
- 结果集提取器:
- 它只定义了一个
extractData
接受ResultSet
实例作为参数并返回列表的方法。 - 句法:
- 它只定义了一个
public T extractData(ResultSet rs) throws SQLException,DataAccessException;
- 行映射器:
- 这是 ResultSetExtractor 的增强版本,可以节省大量代码。
- 它允许将一行关系与用户定义的类的实例进行映射。
- 它在内部迭代 ResultSet 并将其添加到结果集合中,从而节省了大量获取记录的代码。
32.什么是Hibernate ORM框架?
- 对象关系映射 (ORM) 是将应用程序域模型对象映射到关系数据库表,反之亦然的现象。
- Hibernate 是最常用的基于 Java 的 ORM 框架。
33.使用Spring访问Hibernate的两种方式是什么?
- 使用 Hibernate 模板和回调的控制反转方法。
- 扩展
HibernateDAOSupport
和应用 AOP 拦截器节点。
34. 什么是 Hibernate 验证器框架?
- 数据验证是任何应用程序的关键部分。我们可以在以下位置找到数据验证:
- 将对象发送到服务器之前的 UI 层
- 在服务器端处理之前
- 在将数据持久化到数据库之前
- 验证是一个跨领域的关注点/任务,因此作为一种好的做法,我们应该尽量将它与我们的业务逻辑分开。JSR303 和 JSR349 通过使用注解提供了 bean 验证的规范。
- 该框架提供了 JSR303 和 JSR349 规范的参考实现。
35.什么是HibernateTemplate类?
- 在 Hibernate 3.0.1 之前,Spring 提供了 2 个类,即:
HibernateDaoSupport
从 Hibernate 获取 Session 和HibernateTemplate
用于 Spring 事务管理目的。 - 但是,从 Hibernate 3.0.1 开始,通过使用
HibernateTemplate
类,我们可以使用SessionFactory getCurrentSession()
方法来获取当前会话,然后使用它来获得事务管理的好处。 HibernateTemplate
具有异常转换的好处,但可以通过将 @Repository 注释与服务类一起使用来轻松实现。
Spring MVC 面试题
36、什么是Spring MVC框架?
- Spring MVC 是请求驱动的框架,是 Spring 框架的核心组件之一。
- 它带有随时可用的松散耦合组件和元素,极大地帮助开发人员构建灵活和健壮的 Web 应用程序。
- MVC(模型 - 视图 - 控制器)架构在应用程序的不同方面——输入逻辑(模型)、业务逻辑(控制器)和 UI 逻辑(视图)之间分离并提供松散耦合。
37. Spring MVC 框架相对于其他 MVC 框架有什么好处?
- 明确的角色分离——每个角色都有一个专门的专用对象。
- 可重用的业务代码逻辑——使用 Spring MVC,无需复制代码。现有对象可以用作命令而不是复制它们以扩展特定框架基类。
- Spring MVC 框架提供了可定制的绑定和验证。
- 还提供可定制的语言环境和主题分辨率。
- Spring MVC 也支持可定制的处理程序映射和视图解析。
38. Spring MVC中的DispatcherServlet是什么?换句话说,你能解释一下 Spring MVC 的架构吗?
Spring MVC 框架围绕一个名为 DispatcherServlet 的中央 servlet 构建,该 servlet 处理所有 HTTP 请求和响应。DispatcherServlet 做的远不止这些:
- 它与 IoC 容器无缝集成,并允许你以更简单的方式使用 Spring 的每个功能。
- DispatcherServlet 联系 HandlerMapping 以调用适当的控制器来处理接收到的请求。然后,控制器调用适当的服务方法来设置或处理模型数据。该服务处理数据并将视图名称返回给 DispatcherServlet。DispatcherServlet 然后在 ViewResolver 的帮助下获取请求的定义视图。一旦确定了视图,DispatcherServlet 将模型数据传递给视图,最终在浏览器上呈现它。
39.什么是View Resolver模式并解释它在Spring MVC中的意义?
- 它是一种 J2EE 模式,允许应用程序动态选择在浏览器(视图)上呈现数据的技术。
- 任何技术,如 HTML、JSP、XSLT、JSF 或任何其他此类技术都可以用作视图。
- 视图解析器具有不同视图的信息。Controller返回View的名称,然后由DispatcherServlet传递给View Resolver选择合适的View技术,然后显示数据。
- Spring MVC 中使用的默认 ViewResolver 是
InternalResourceViewResolver
.
40.@Controller注解是干什么用的?
- @Controller 是用于定义控制器的构造型 Spring MVC 注释。
41. 可以不使用@Controller 或@RestController 注解来创建控制器吗?
- 是的!你可以通过使用注释对 Spring MVC 控制器类进行
@Component
注释来创建没有 @Controller 或 @RestController 注释的控制器。在这种情况下,请求映射到处理程序方法的真正工作是使用 @RequestMapping 注释完成的。
42.什么是ContextLoaderListener,它有什么作用?
- ContextLoaderListener 加载并创建 ApplicationContext,因此开发人员无需编写显式代码来创建它。简而言之,它是一个有助于引导 Spring MVC 的侦听器。
- 应用程序上下文是 Spring bean 所在的地方。对于 Web 应用程序,有一个名为 WebAppliationContext 的子类。
- ApplicationContext 的生命周期通过使用 ContextLoaderListener 绑定到 ServletContext 的生命周期。可以使用 getServletContext() 方法获取来自 WebApplicationContext 的 ServletContext。
43.Spring常见面试题和答案合集:@RequestParam 和@PathVariable 注解的区别是什么?
- 尽管这两个注释都用于从 URL 中提取一些数据,但它们之间存在关键区别。
- @RequestParam 用于提取“?”之后的查询参数。在网址中。
- @PathVariable 用于提取作为 URI 本身的一部分存在的数据。]
- 例如,如果给定的 URL 是 http://localhost:8080/InterviewBit/Spring/SpringMVC/?format=json,那么你可以使用 @RequestParam 注释和 /Spring/{type} 访问查询参数“格式” @PathVariable,它将为你提供 SpringMVC。
@RequestMapping("/Spring/{type}")
public void getQuestions(@PathVariable("type") String type,
@RequestParam(value = "format", required = false) String format){
/* Some code */
}
44. Spring MVC中的Model是什么?
- 模型是具有渲染数据的参考。
- 它总是在 Spring MVC 中创建并传递给视图。如果映射的控制器方法将 Model 作为参数,则该模型实例会自动注入该方法。
- 在注入模型上设置的任何属性都将被保留并传递给视图。
45.@Autowired注解有什么用?
@Autowired
注释用于通过 bean 的类型以及方法和字段注入 bean。这有助于 Spring 框架通过将 bean 注入和协作到另一个 bean 来解决依赖关系。例如,考虑以下代码片段:
import org.Springframework.beans.factory.annotation.Autowired;
import java.util.*;
public class InterviewBit {
// Autowiring/Injecting FormatterUtil as dependency to InterviewBit class
@Autowired
private FormatterUtil formatterUtil;
public Date something( String value ){
Date dateFormatted = formatterUtil.formatDate(value);
return dateFormatted
}
}
/**
* Util class to format any string value to valid date format
*/
public class FormatterUtil {
public Date formatDate(String value){
//code to format date
}
}
46.@ModelAttribute注解的作用是什么?
注释在将方法参数绑定到对应于模型的各个属性中起着非常重要的作用。然后它在演示文稿页面上反映了相同的内容。注释的作用还取决于开发人员使用它的目的。如果在方法级别使用它,则该方法负责向其添加属性。在参数级别使用时,它表示该参数值旨在从模型层检索。
47、web.xml在Spring MVC中的重要性是什么?
web.xml
也称为部署描述符,它定义了 servlet 及其映射、过滤器和生命周期侦听器。它还用于配置 ContextLoaderListener。每当部署应用程序时,Servlet 容器都会创建一个 ContextLoaderListener 实例,这会导致加载 WebApplicationContext。
48. Spring MVC 依赖注入有哪些类型?
DI(依赖注入)有两种类型:
- 基于构造器:
- 这种类型的 DI 是在 Spring IoC(控制反转)容器调用依赖于其他类的参数化构造函数时完成的。
- 这不能部分实例化值并确保完全完成依赖注入。
- 有两种可能的方法来实现这一点:
注解配置:这种方法使用 POJO 对象和注解进行配置。例如,考虑以下代码片段:
@Configuration
@ComponentScan("com.interviewbit.constructordi")
public class SpringAppConfig {
@Bean
public Shape shapes() {
return new Shapes("Rectangle");
}
@Bean
public Dimension dimensions() {
return new Dimension(4,3);
}
}
这里的注解是用来通知Spring运行时@Bean
注解指定的类是bean的提供者,需要com.interviewbit.constructordi
通过@ComponentScan
注解的方式对包进行上下文扫描的过程。接下来,我们将定义一个 Figure 类组件,如下所示:
@Component
public class Figure {
private Shape shape;
private Dimension dimension;
@Autowired
public Figure(Shape shape, Dimension dimension) {
this.shape = shape;
this.dimension = dimension;
}
}
Spring 在执行上下文扫描时遇到这个 Figure 类,它通过调用注释的构造函数来初始化这个类的实例@Autowired
。形状和尺寸实例通过调用带有注释的方法获得@Bean
的SpringAppConfig
类。Engine和Transmission的实例将通过调用Config类的@Bean注解方法获得。最后,我们需要使用我们的 POJO 配置来引导一个 ApplicationContext:
ApplicationContext context = new AnnotationConfigApplicationContext(SpringAppConfig.class);
Figure figure = context.getBean(Figure.class);
XML 配置:这是使用 XML 配置文件配置 Spring 运行时的另一种方式。例如,考虑 springAppConfig.xml 文件中的以下代码片段:
<bean id="toyota" class="com.interviewbit.constructordi.Figure">
<constructor-arg index="0" ref="shape"/>
<constructor-arg index="1" ref="dimension"/>
</bean>
<bean id="shape" class="com.interviewbit.constructordi.Shape">
<constructor-arg index="0" value="Rectangle"/>
</bean>
<bean id="dimension" class="com.interviewbit.constructordi.Dimension">
<constructor-arg index="0" value="4"/>
<constructor-arg index="1" value="3"/>
</bean>
该constructor-arg
标签可以接受文字值或其他bean的基准和明确的指标和类型。索引和类型参数用于解决歧义情况下的冲突。
在引导这个类时,SpringApplicationContext
需要使用ClassPathXmlApplicationContext
如下所示:
ApplicationContext context = new ClassPathXmlApplicationContext("springAppConfig.xml");
Figure figure = context.getBean(Figure.class);
- 基于setter:
- 这种形式的 DI 是在调用非参数化构造函数执行 bean 实例化后,Spring IoC 容器调用 bean 的 setter 方法时实现的。
- 可以使用 setter 注入来实现循环依赖。
- 为了实现这种类型的DI,我们需要通过
<property>
标签下的配置文件进行配置。例如,考虑一个InterviewBit
设置属性的类,articles
如下所示:
package com.interviewbit.model;
import com.interviewbit.model.Article;
public class InterviewBit {
// Object of the Article interface
Article article;
public void setArticle(Article article)
{
this.article = article;
}
}
在 bean 配置文件中,我们将设置如下:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="InterviewBit" class="com.interviewbit.model.InterviewBit">
<property name="article">
<ref bean="JsonArticle" />
</property>
</bean>
<bean id="JsonArticle" class="com.interviewbit.bean.JsonArticle" />
</beans>
'JsonArticle' bean 通过该setArticle
方法注入到InterviewBit 类对象中。
在使用两种类型的依赖项的情况下,考虑到特殊性,setter 依赖项注入具有更多的偏好。
49. 会话范围的重要性是什么?
Spring面试题解析:会话范围用于为 HTTP 会话创建 bean 实例。这意味着单个 bean 可用于服务多个 HTTP 请求。bean 的作用域可以通过使用 scope 属性或使用 @Scope 或 @SessionScope 注释来定义。
- 使用范围属性:
<bean id="userBean" class="com.interviewbit.UserBean" scope="session"/>
- 使用@Scope 注解:
@Component
@Scope("session")
public class UserBean {
//some methods and properties
}
- 使用@SessionScope:
@Component
@SessionScope
public class UserBean {
//some methods and properties
}
50.@Required注解的重要性是什么?
注释用于指示应该在配置时通过自动装配或在 bean 定义期间的任何显式值填充 bean 的属性。例如,考虑下面的代码片段,其中我们需要具有年龄和姓名的值:
import org.Springframework.beans.factory.annotation.Required;
public class User {
private int age;
private String name;
@Required
public void setAge(int age) {
this.age = age;
}
public Integer getAge() {
return this.age;
}
@Required
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
}
51. Spring常见面试题有哪些:区分@Autowired 和@Inject 注释。
@Autowired | @Inject |
---|---|
这个注解是 Spring 框架的一部分。 | 该注解是 Java CDI 的一部分。 |
具有必需的属性。 | 没有必需的属性。 |
Singleton 是自动装配 bean 的默认范围。 | Prototype 是注入 bean 的默认范围。 |
如果有歧义,则使用@Qualifier 注释。 | 如果出现歧义,则需要使用@Named 限定符。 |
由于这个注解是由 Spring 框架提供的,如果你转移到另一个依赖注入框架,将需要大量的重构。 | 由于此注释是 Java CDI 的一部分,因此它不依赖于框架,因此在发生框架更改时较少的代码重构。 |
52. 单例 bean 线程安全吗?
不,单例 bean 不是线程安全的,因为线程安全的概念本质上是处理程序的执行,而单例只是一种用于创建对象的设计模式。bean 的线程安全性质取决于其实现的性质。
53.如何在bean中实现线程安全?
线程安全可以通过将 bean 的范围更改为请求、会话或原型来实现,但以性能为代价。这纯粹是基于项目要求。
54、@Repository注解有什么意义?
@Repository 注释表明组件用作存储库,作为存储、搜索或检索数据的手段。这些可以添加到 DAO 类中。
55. dispatcher servlet 是如何实例化的?
调度程序 servlet 是通过 Tomcat 等 servlet 容器实例化的。DispatcherServlet 应该在 web.xml 中定义 DispatcherServlet 由 Tomcat 等 Servlet 容器实例化。Dispatcher Servlet 可以在 web.xml 中定义,如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- Define Dispatcher Servlet -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>InterviewBitServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
在这里,load-on-startup 标记是 1,这表明只要 Spring MVC 应用程序到 servlet 容器,就会实例化 DispatcherServlet。在此过程中,它会查找 servlet-name-context.xml 文件并初始化文件中定义的 bean。
56. Spring MVC中的根应用上下文是如何加载的?
使用属于整个应用程序的 ContextLoaderListener 加载根应用程序上下文。Spring MVC 允许实例化多个 DispatcherServlet 并且每个 DispatcherServlet 都有多个特定于它们的上下文。它们也可以具有相同的根上下文。
57. Spring MVC 的流程是怎样的?换句话说,当有传入的 Spring MVC 请求时,DispatcherServlet 如何知道需要调用什么 Controller?
Dispatcher Servlet 通过处理程序映射知道要调用哪个控制器。这些映射具有控制器和请求之间的映射。BeanNameUrlHandlerMapping
和SimpleUrlHandlerMapping
是两个最常用的处理程序映射。
- BeanNameUrlHandlerMapping:当URL请求与bean名称匹配时,bean定义对应的类就是负责处理请求的实际控制器。
- SimpleUrlHandlerMapping:这里的映射非常明确。可以在此处指定 URL 的数量,并且每个 URL 都与一个控制器显式关联。
如果 Spring MVC 是使用注解配置的,那么@RequestMapping 注解就是用于这个目的。@RequestMapping 注解是通过使用 URI 路径、HTTP 方法、查询参数和 HTTP 标头来配置的。
58.视图对模型的访问从何而来?
视图需要访问模型才能呈现输出,因为模型包含用于呈现所需的数据。模型与处理客户端请求的控制器相关联,最终将响应封装到模型对象中。
59. 为什么我们需要 BindingResults?
BindingResults 是org.Springframework.validation
包内的一个重要的 Spring 接口。这个接口有一个非常简单和容易的调用过程,在检测提交的表单中的错误方面起着至关重要的作用。但是,开发人员必须注意在需要验证的对象之后使用 BindingResult 参数。例如:
@PostMapping("/interviewbit")
public String registerCourse(@Valid RegisterUser registerUser,
BindingResult bindingResult, Model model) {
if (bindingResult.hasErrors()) {
return "home";
}
model.addAttribute("message", "Valid inputs");
return "home";
}
Spring 将通过检查参数上的 @Valid 注释来理解找到相应的验证器。
60. 什么是Spring拦截器?
Spring Interceptor 用于对 Spring MVC 中由 Spring Controller 处理的 Web 请求进行预处理和后处理。这可以通过HandlerInterceptor
接口来实现。这些处理程序用于操作传递给控制器或视图的模型属性。
可以为特定的 URL 映射注册 Spring 处理程序拦截器,以便它只能拦截那些请求。自定义处理程序拦截器必须实现HandlerInterceptor
具有 3 个可以实现的回调方法的接口:
- preHandle()
- postHandle()
- afterCompletion()
该接口的唯一问题是该接口的所有方法都需要实现,而不管其要求如何。如果我们的处理程序类扩展HandlerInterceptorAdapter
内部实现HandlerInterceptor
接口的类并提供默认的空白实现,则可以避免这种情况。
61. 是否需要在类路径上保留spring-mvc.jar 或者它是否已经作为spring-core 的一部分存在?
该spring-mv.jar
不属于Spring的核心。这意味着如果我们必须在我们的项目中使用 Spring MVC 框架,那么 jar 必须包含在项目的类路径中。对于 Java 应用程序,spring-mvc.jar
位于/WEB-INF/lib
文件夹内。
62. <context:annotation-config> 和 <context:component-scan> 标签有什么区别?
<context:annotation-config>
用于在应用程序上下文中激活预注册 bean 中的应用注解。它还注册配置文件中定义的 bean,并扫描 bean 中的注释并激活它们。
该<context:component-scan>
标签做的任务<context:annotation-config>
与扫描包,并在应用程序上下文注册豆一起。
<context:annotation-config>
= 扫描并激活预注册 bean 中的注释。<context:component-scan>
= 注册 Bean + 扫描并激活包中的注释。
63、Spring Web MVC框架中的表单数据验证是怎么做的?
Spring MVC 使用实现了 Validator 接口的验证器对象来完成数据验证的任务。在我们创建的自定义验证器类中,我们可以使用 ValidationUtils 类的实用方法,例如rejectIfEmptyOrWhitespace()
或rejectIfEmpty()
来执行表单字段的验证。
@Component
public class UserValidator implements Validator
{
public boolean supports(Class clazz) {
return UserVO.class.isAssignableFrom(clazz);
}
public void validate(Object target, Errors errors)
{
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", "error.name", "Name is required.");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "age", "error.age", "Age is required.");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "phone", "error.phone", "Phone is required.");
}
}
在需要验证的字段中,如果出现错误,验证器方法将创建字段错误并将其绑定到该字段。
要将自定义验证器激活为 spring bean,然后:
- 我们必须在自定义验证器类上添加 @Component 注释,并通过添加以下更改来启动对包含验证器声明的包的组件扫描:
<context:component-scan base-package="com.interviewbit.validators"/>
或者
验证器类可以直接在上下文文件中注册为 bean,如下所示:
<bean id="userValidator" class="com.interviewbit.validators.UserValidator" />
64、如何在spring bean中获取ServletConfig和ServletContext对象?
这可以通过实现弹簧感知接口或使用@Autowired 注释来完成。
@Autowired
private ServletContext servletContext;
@Autowired
private ServletConfig servletConfig;
65. Spring常见面试题和答案合集:区分 Bean Factory 和应用程序上下文。
BeanFactory 和 ApplicationContext 都是 Java 接口。不同之处在于 ApplicationContext 扩展了 BeanFactory。BeanFactory 提供 IoC 和 DI 基本功能,而 ApplicationContext 提供更高级的功能。以下是这两者之间的区别:
类别 | BeanFactory | ApplicationContext |
---|---|---|
国际化 (i18n) | 不提供对 i18n 的支持。 | 提供对 i18n 的支持。 |
事件发布 | 通过使用 ContextStartedEvent 和 ContextStoppedEvent 分别在启动和停止时发布上下文,提供将事件发布到侦听器 bean 的能力。 | ApplicationContext 通过 ApplicationListener 接口和 ApplicationEvent 类支持事件处理。 |
实现 | XMLBeanFactory 是 BeanFactory 的流行实现。 | ClassPathXmlApplicationContext 是 ApplicationContext 的流行实现。此外,Java 使用 WebApplicationContext 扩展接口并添加 getServletContext() 方法。 |
自动装配 | 对于自动装配,bean 必须在 AutoWiredBeanPostProcessor API 中注册。 | 在这里,可以通过 XML 配置来实现自动装配。 |
66. Spring MVC 是如何支持 i18n 和本地化的?
Spring MVCLocaleResolver
支持 i18n 和本地化。支持国际化和本地化。需要在应用程序中配置以下bean:
- SessionLocaleResolver:这个 bean 在从用户会话中的预定义属性中获取和解析语言环境方面起着至关重要的作用。
句法:
<bean id="localeResolver"class="org.Springframework.web.servlet.i18n.SessionLocaleResolver">
<property name="defaultLocale" value="en" />
</bean>
- LocaleChangeInterceptor:此 bean 可用于解析传入请求中的参数。
句法:
<bean id="localeChangeInterceptor"class="org.Springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang" />
</bean>
- DefaultAnnotationHandlerMapping:这是指 HandlerMapping 接口实现,它根据 @RequestMapping 在类型或方法级别指定的 HTTP 路径映射处理程序/拦截器。
句法:
<bean class="org.Springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors">
<list>
<ref bean="localeChangeInterceptor" />
</list>
</property>
</bean>
67、你对MultipartResolver的理解是什么?
Spring面试题解析:MultipartResolver 用于处理 Spring Web 应用程序中的文件上传场景。Spring中有2个具体实现,它们是:
- CommonsMultipartResolver 用于 Jakarta Commons FileUpload
- StandardServletMultipartResolver 用于 Servlet 3.0 Part API
为了实现这一点,我们需要在 DispatcherServlet 的应用程序上下文中创建一个 id="multipartResolver" 的 bean。这样做可以确保 DispatcherServlet 处理的所有请求在检测到多部分请求时都应用此解析器。如果 DispatcherServlet 检测到多部分请求,它会通过已配置的 MultipartResolver 解析请求,并将请求作为包装/抽象的 HttpServletRequest 传递。控制器然后将此请求转换为MultipartHttpServletRequest
访问 Multipart 文件的接口。下图清楚地说明了流程:
68、Spring常见面试题有哪些:如何在Spring应用中使用Tomcat JNDI DataSource?
要使用在 JNDI(Java 命名和目录接口)数据源中配置的 servlet 容器,必须在 spring bean 配置文件中配置数据源 bean,然后将其作为依赖项注入到 bean 中。在此之后,DataSource bean 可用于通过 JdbcTemplate 执行数据库操作。注册 MySQL DataSource bean 的语法:
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/MySQLDB"/>
</bean>
69.如果用户先勾选checkbox,在其他字段中得到验证错误,然后在得到错误后取消勾选checkbox,那么checkbox输入的选择状态是什么?
验证通常在 HTTP POST 请求期间执行。在 HTTP 请求期间,如果复选框的状态未选中,则 HTTP 包含复选框的请求参数,从而不会选择更新的选择。这可以通过使用_
以 Spring MVC开头的隐藏表单字段来解决。
结论:
在本文中,我们看到了面试中最常被问到的 Spring 面试问题。Spring 是一个非常强大的框架,允许构建企业级 Web 应用程序。使用 Spring 开发的应用程序通常快速、可扩展且透明。因此,Spring 已被庞大的 Java 开发人员社区所接受,从而使其成为任何 Java 开发人员工作角色中不可避免的一部分。了解 Spring 可确保开发人员在其职业生涯中也能稳步发展,这是一个额外的优势。