我发了很多帖春季教程最近。这篇文章将帮助您解决 Spring 面试问题,详细解释核心概念。
Spring框架是最流行的 Web 应用程序 Java EE 框架之一。依赖注入面向方面编程是 Spring 框架的核心。如果你擅长 Spring 框架,那么在 Java 面试中被选中的机会就会非常高。
Pro Tip: 核心Java是任何基于 Java 的框架的基础,因此如果您正在准备面试,请阅读核心 Java 面试问题 and Java面试题文章。
在这里我提供了近50个春季面试问题及其答案。它已更新至 Spring 5,因此涵盖了所有最新功能,例如用于反应式编程的 Spring WebFlux.
Spring 是使用最广泛的 Java EE 框架之一。 Spring框架的核心概念是“依赖注入”和“面向方面编程”。
Spring框架可以用在普通的java应用程序中,也可以通过实现依赖注入来实现不同组件之间的松耦合。我们可以使用 spring 支持面向方面的编程来执行横切任务,例如日志记录和身份验证。
我喜欢 Spring,因为它为特定任务提供了很多功能和不同的模块,例如 Spring MVC 和 Spring JDBC。由于它是一个开源框架,拥有大量在线资源和活跃的社区成员,因此使用 Spring 框架既简单又有趣。
推荐阅读: Spring框架
Spring框架构建在两个设计概念之上——依赖注入和面向方面编程。
Spring框架的一些特性是:
- 使用框架进行开发的轻量级且开销很小。
- 依赖注入或控制反转来编写彼此独立的组件,Spring 容器负责将它们连接在一起以实现我们的工作。
- Spring IoC 容器管理 Spring Bean 生命周期和特定于项目的配置,例如 JNDI 查找。
- Spring MVC 框架可用于创建 Web 应用程序以及能够返回 XML 和 JSON 响应的静态 Web 服务。
- 通过使用注解或 spring bean 配置文件,只需很少的配置即可支持事务管理、JDBC 操作、文件上传、异常处理等。
使用 Spring 框架的一些优点是:
- 减少应用程序不同组件之间的直接依赖关系。 Spring IoC容器负责初始化资源或bean并将它们作为依赖项注入。
- 在 Spring 框架中编写单元测试用例很容易,因为我们的业务逻辑与实际的资源实现类没有直接依赖关系。我们可以轻松编写测试配置并注入模拟 bean 以进行测试。
- 减少样板代码的数量,例如初始化对象、打开/关闭资源。我非常喜欢 JdbcTemplate 类,因为它可以帮助我们删除 JDBC 编程附带的所有样板代码。
- Spring框架分为几个模块,它帮助我们保持应用程序的轻量级。例如,如果我们不需要 Spring 事务管理功能,则不需要将该依赖项添加到我们的项目中。
- Spring 框架支持大多数 Java EE 功能,甚至更多。它总是走在新技术之上,例如,Android 有一个 Spring 项目,可以帮助我们为原生 Android 应用程序编写更好的代码。这使得spring框架成为一个完整的封装,我们不需要为不同的需求而照顾不同的框架。
Spring 5 是 Spring 4 的重大改进。一些重要的功能包括:
- 支持Java 8及更高版本,因此我们可以使用lambda表达式。
- 支持 Java EE7 和 Servlet 4.0 规范。
- 文件操作现在通过 NIO 2 流执行,如果您的应用程序进行大量文件处理,这是一个巨大的改进。
- 引入 spring-jcl 来简化日志记录,之前由于没有单点用于日志记录,所以情况很混乱。
- 支持 Kotlin、Lombok、Reactor 3.1Flux, and Mono以及 RxJava。
- Spring WebFlux 为 Spring 带来了响应式编程。
- 支持 JUnit 5
- 支持通过索引文件“META-INF/spring.components”提供 spring 组件信息,而不是类路径扫描。
请通过Spring 5 特性以获得此版本的详细概述。
Spring WebFlux 是 Spring 5 中引入的新模块。Spring WebFlux 是 spring 框架中向响应式编程模型迈出的第一步。
Spring WebFlux 是 Spring MVC 模块的替代品。 Spring WebFlux 用于创建基于事件循环执行模型的完全异步和非阻塞应用程序。
您可以在以下位置阅读更多相关信息:Spring WebFlux 教程.
依赖注入设计模式允许我们删除硬编码的依赖关系,并使我们的应用程序松散耦合、可扩展和可维护。我们可以实现依赖注入模式,将依赖解析从编译时转移到运行时。
使用依赖注入的一些好处是关注点分离、样板代码减少、可配置组件和简单的单元测试。
阅读更多内容依赖注入教程。我们还可以使用用于依赖注入的 Google Guice自动化依赖注入过程。但在大多数情况下,我们寻求的不仅仅是依赖注入,而这正是 Spring 的用武之地。
我们可以使用基于 Spring XML 以及基于注解的配置来在 Spring 应用程序中实现 DI。为了更好的理解,请阅读Spring依赖注入您可以通过 JUnit 测试用例学习这两种方法的示例。这篇文章还包含一个示例项目 zip 文件,您可以下载并试用该文件以了解更多信息。
我们可以在Eclipse中安装插件来获得Spring Tool Suite的所有功能。然而,STS 随 Eclipse 一起提供了一些其他重要的功能,例如 Maven 支持、用于创建不同类型 Spring 项目的模板以及用于提高 Spring 应用程序性能的 tc 服务器。
我喜欢 STS,因为它突出显示了 Spring 组件,如果您使用 AOP 切入点和建议,那么它会清楚地显示哪些方法将位于特定切入点下。因此,在开发基于 Spring 的应用程序时,我更喜欢使用 STS,而不是自己安装所有东西。
一些重要的 Spring 框架模块是:
- Spring Context – 用于依赖注入。
- Spring AOP – 用于面向方面的编程。
- Spring DAO – 使用 DAO 模式进行数据库操作
- Spring JDBC – 用于 JDBC 和 DataSource 支持。
- Spring ORM – 用于 ORM 工具支持,例如 Hibernate
- Spring Web 模块 – 用于创建 Web 应用程序。
- Spring MVC – 用于创建 Web 应用程序、Web 服务等的模型-视图-控制器实现。
企业应用程序有一些常见的横切关注点,适用于不同类型的对象和应用程序模块,例如日志记录、事务管理、数据验证、身份验证等。应用程序的模块化是通过面向对象编程中的类来实现的。在 AOP 中,应用程序模块化是通过方面实现的,并且它们被配置为跨越不同的类方法。
AOP 消除了类中横切任务的直接依赖,这在普通的面向对象编程中是不可能的。例如,我们可以有一个单独的类用于日志记录,但其他类必须调用这些方法。但是,在 AOP 中,我们配置方面并且方法执行会自动发生。阅读有关 Spring AOP 支持的更多信息,请访问Spring AOP 示例.
Aspect:Aspect是一个实现横切关注点的类,比如事务管理。方面可以是配置好的普通类,然后在 Spring Bean 配置文件中配置,或者我们可以使用 Spring AspectJ 支持将类声明为方面@Aspect
注解。
Advice:建议是针对特定连接点采取的操作。就编程而言,它们是当应用程序中到达具有匹配切入点的特定连接点时执行的方法。您可以将建议视为弹簧拦截器 or 小服务程序过滤器.
Pointcut:切入点是与连接点匹配的正则表达式,以确定是否需要执行通知。切入点使用与连接点匹配的不同类型的表达式。 Spring 框架使用 AspectJ 切入点表达式语言来确定将应用通知方法的连接点。
连接点:连接点是应用程序中的特定点,例如方法执行、异常处理、更改对象变量值等。在 Spring AOP 中,连接点始终是方法的执行。
建议论点:我们可以在通知方法中传递参数。我们可以在切入点中使用 args() 表达式来应用于与参数模式匹配的任何方法。如果我们使用它,那么我们需要在确定参数类型的通知方法中使用相同的名称。
这些概念乍一看似乎令人困惑,但如果你仔细阅读Spring方面,建议示例那么你就可以轻松地与他们建立联系。
AspectJ 是面向方面编程的行业标准实现,而 Spring 在某些情况下实现了 AOP。 Spring AOP 和 AspectJ 之间的主要区别是:
- Spring AOP 比 AspectJ 使用起来更简单,因为我们不需要担心编织过程。
- Spring AOP 支持 AspectJ 注释,因此如果您熟悉 AspectJ,那么使用 Spring AOP 会更容易。
- Spring AOP仅支持基于代理的AOP,因此它只能应用于方法执行连接点。 AspectJ 支持各种切入点。
- Spring AOP 的缺点之一是它只能应用于通过 Spring Context 创建的 bean。
控制反转(IoC)是实现对象依赖关系之间松耦合的机制。为了在运行时实现对象的松耦合和动态绑定,对象定义了由其他汇编器对象注入的依赖关系。 Spring IoC 容器是将依赖项注入到对象中并使其可供我们使用的程序。
Spring框架IoC容器类是org.springframework.beans
and org.springframework.context
打包并为我们提供了不同的方法来解耦对象依赖关系。
我们使用的一些有用的 ApplicationContext 实现是:
- AnnotationConfigApplicationContext:适用于使用基于注释的配置的独立 java 应用程序。
- ClassPathXmlApplicationContext:适用于使用基于 XML 的配置的独立 java 应用程序。
- FileSystemXmlApplicationContext:与 ClassPathXmlApplicationContext 类似,不同之处在于 XML 配置文件可以从文件系统中的任何位置加载。
- 用于 Web 应用程序的 AnnotationConfigWebApplicationContext 和 XmlWebApplicationContext。
任何由 Spring IoC 容器初始化的普通 java 类都称为 Spring Bean。我们使用SpringApplicationContext
获取 Spring Bean 实例。
Spring IoC 容器管理 Spring Bean 的生命周期、bean 范围以及在 bean 中注入任何所需的依赖项。
我们使用 Spring Bean 配置文件来定义将由 Spring Context 初始化的所有 bean。当我们创建 Spring ApplicationContext 的实例时,它会读取 spring bean XML 文件并初始化所有这些文件。一旦上下文被初始化,我们就可以使用它来获取不同的 bean 实例。
除了 Spring Bean 配置之外,该文件还包含 spring MVC 拦截器、视图解析器和其他支持基于注释的配置的元素。
配置 Spring Bean 有三种不同的方法。
XML配置:这是最流行的配置,我们可以使用上下文文件中的 bean 元素来配置 Spring Bean。例如:
<bean name="myBean" class="com.journaldev.spring.beans.MyBean"></bean>
基于Java的配置:如果您仅使用注释,则可以使用以下命令配置 Spring bean@Bean
注解。该注释与@Configuration
配置 spring bean 的类。示例配置为:
@Configuration
@ComponentScan(value="com.journaldev.spring.main")
public class MyConfiguration {
@Bean
public MyService getService(){
return new MyService();
}
}
为了从 spring 上下文中获取这个 bean,我们必须使用以下代码片段:
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
MyConfiguration.class);
MyService service = ctx.getBean(MyService.class);
基于注释的配置: 我们还可以使用@成分, @Service, @存储库 and @控制器带有类的注释将它们配置为 spring bean。对于这些,我们需要提供基本包位置来扫描这些类。例如:
<context:component-scan base-package="com.journaldev.spring" />
为 Spring Bean 定义了五个范围。
-
单例:每个容器只会创建一个 bean 实例。这是 spring bean 的默认范围。使用此作用域时,请确保 spring bean 没有共享实例变量,否则可能会导致数据不一致问题,因为它不是线程安全的。
- 原型:每次请求 bean 时都会创建一个新实例。
- request:这与原型范围相同,但是,它旨在用于 Web 应用程序。将为每个 HTTP 请求创建一个新的 bean 实例。
-
session:容器将为每个 HTTP 会话创建一个新的 bean。
-
全球会议:这用于为 Portlet 应用程序创建全局会话 Bean。
Spring框架是可扩展的,我们也可以创建自己的范围。但大多数时候我们都擅长框架提供的范围。要设置 Spring bean 范围,我们可以使用 bean 元素中的“scope”属性或@Scope基于注释的配置的注释。
Spring Bean 由 Spring 容器初始化,并且所有依赖项也被注入。当上下文被销毁时,它也会销毁所有已初始化的 bean。这在大多数情况下效果很好,但有时我们希望在让我们的 bean 可供使用之前初始化其他资源或进行一些验证。 Spring框架提供了对Spring bean中的后初始化和预销毁方法的支持。
我们可以通过两种方式做到这一点——通过实施InitializingBean
and DisposableBean
接口或使用初始化方法 and 销毁方法spring bean 配置中的属性。欲了解更多详情,请阅读Spring Bean 生命周期方法.
有两种方法可以在 spring bean 中获取 Container 特定对象。
- 实现 Spring *Aware 接口,对于这些 ServletContextAware 和 ServletConfigAware 接口,有关这些感知接口的完整示例,请阅读Spring 感知接口.
- Using
@Autowired
带有 bean 变量类型的注释ServletContext
and ServletConfig
。它们只能在特定于 servlet 容器的环境中工作。
@Autowired
ServletContext servletContext;
初始化时注入Spring Bean依赖的过程称为Spring Bean Wiring。
通常,最佳实践是对所有 bean 依赖项进行显式连接,但 spring 框架也支持自动连接。我们可以用@Autowired
带有字段或方法的注释按类型自动装配。为了让这个注解发挥作用,我们还需要在 spring bean 配置文件中启用基于注解的配置。这可以通过以下方式完成上下文:注释配置元素。
有关更多详细信息@Autowired
注释,请阅读弹簧自动装配示例.
Spring框架中有四种自动装配类型。
- 按名称自动装配
- 按类型自动装配
- 通过构造函数自动装配
- 自动装配@Autowired and @预选赛注释
在 Spring 3.1 之前,通过自动检测自动装配还支持类似于通过构造函数或通过类型自动装配的功能。有关这些选项的更多详细信息,请阅读Spring Bean 自动装配.
Spring bean 的默认范围是单例,因此每个上下文只有一个实例。这意味着任何线程都可以更新的所有类级别变量都会导致数据不一致。因此在默认模式下 spring bean 不是线程安全的。
但是,我们可以将 spring bean 作用域更改为 request、prototype 或 session,以牺牲性能为代价来实现线程安全。这是一个基于项目要求的设计决策。
就像 MVC 设计模式一样,Controller 是负责处理所有客户端请求并将它们发送到配置的资源来处理它们的类。在 Spring MVC 中,调度程序Servlet是根据 spring bean 配置初始化上下文的前端控制器类。
控制器类负责根据请求映射处理不同类型的客户端请求。我们可以使用以下方法创建一个控制器类@控制器注解。通常,它与@RequestMapping用于定义特定 URI 映射的处理程序方法的注释。
24. 两者有什么区别@成分, @控制器, @存储库 & @ServiceSpring中的注解?
@成分用于表明类是一个组件。这些类用于自动检测,并在使用基于注释的配置时配置为 bean。
@控制器是一种特定类型的组件,在 MVC 应用程序中使用,并且主要与 RequestMapping 注释一起使用。
@存储库注释用于指示组件用作存储库和存储/检索/搜索数据的机制。我们可以将此注释应用于 DAO 模式实现类。
@Service用于表明一个类是一个服务。通常,提供某些服务的业务门面类都用此注解。
我们可以对类使用上述任何注释来进行自动检测,但提供了不同的类型,以便您可以轻松区分注释类的用途。
DispatcherServlet是Spring MVC应用程序中的前端控制器,它加载spring bean配置文件并初始化所有配置的bean。如果启用了注释,它还会扫描包并配置带有注释的任何 bean@成分, @控制器, @存储库, or @Service注释。
ContextLoaderListener 是启动和关闭 Spring 的根 WebApplicationContext 的监听器。它的重要功能是将 ApplicationContext 的生命周期与 ServletContext 的生命周期联系起来,并自动创建 ApplicationContext。我们可以使用它来定义可以在不同 spring 上下文中使用的共享 bean。
ViewResolver 实现用于按名称解析视图页面。我们在spring bean配置文件中进行配置。例如:
<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
InternalResourceViewResolver 是 ViewResolver 接口的实现之一,我们通过 bean 属性提供视图页面目录和后缀位置。因此,如果控制器处理程序方法返回“home”,视图解析器将使用位于 /WEB-INF/views/home.jsp 的视图页面。
MultipartResolver接口用于上传文件——CommonsMultipartResolver和StandardServletMultipartResolver是spring框架提供的两个用于文件上传的实现。默认情况下,没有配置多部分解析器,但要使用它们上传文件,我们需要在 Spring bean 配置中定义一个名为“multipartResolver”、类型为 MultipartResolver 的 bean。
配置完成后,任何多部分请求都将由配置的 MultipartResolver 解析并传递包装的 HttpServletRequest。然后在控制器类中使用它来获取文件并处理它。如需完整示例,请阅读Spring MVC 文件上传示例.
Spring MVC框架提供了以下方法来帮助我们实现健壮的异常处理。
基于控制器– 我们可以在控制器类中定义异常处理程序方法。我们需要做的就是用注释来注释这些方法@ExceptionHandler注解。
全局异常处理程序– 异常处理是一个跨领域的问题,Spring 提供了@ControllerAdvice我们可以将其与任何类一起使用来定义全局异常处理程序。
HandlerExceptionResolver 实现– 对于一般例外,大多数时候我们提供静态页面。 Spring框架提供了一个HandlerExceptionResolver接口,我们可以实现它来创建全局异常处理程序。这种定义全局异常处理程序的附加方法背后的原因是 Spring 框架还提供了默认实现类,我们可以在 spring bean 配置文件中定义这些类,以获得 spring 框架异常处理的好处。
如需完整示例,请阅读Spring异常处理示例.
在独立的java程序中创建spring上下文有以下几种方法。
-
注解配置应用上下文:如果我们在独立的Java应用程序中使用Spring并使用配置注解,那么我们可以使用它来初始化容器并获取bean对象。
-
类路径XmlApplicationContext:如果我们在独立应用程序中有一个 spring bean 配置 XML 文件,那么我们可以使用此类来加载该文件并获取容器对象。
-
文件系统Xml应用程序上下文:这与 ClassPathXmlApplicationContext 类似,只是 XML 配置文件可以从文件系统中的任何位置加载。
对于Spring MVC应用程序,我们可以通过contextConfigLocation定义多个spring上下文配置文件。该位置字符串可以由多个位置组成,并用任意数量的逗号和空格分隔。例如;
<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,/WEB-INF/spring/appServlet/servlet-jdbc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
我们还可以定义多个根级 spring 配置并通过 context-param 加载它。例如;
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml /WEB-INF/spring/root-security.xml</param-value>
</context-param>
另一种选择是使用上下文配置文件中的 import 元素来导入其他配置,例如:
<beans:import resource="spring-jdbc.xml"/>
ContextLoaderListener 是用于加载根上下文并定义对所有其他上下文可见的 spring bean 配置的侦听器类。它在 web.xml 文件中配置为:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
为了创建一个简单的 Spring MVC 应用程序,我们需要执行以下任务。
- Add
spring-context
and spring-webmvc
项目中的依赖项。
- 配置
DispatcherServlet
在 web.xml 文件中通过 spring 容器处理请求。
- Spring bean配置文件来定义bean,如果使用注解则必须在这里配置。此外,我们需要为视图页面配置视图解析器。
- 定义了请求映射的控制器类来处理客户端请求。
上述步骤应该足以创建一个简单的 Spring MVC Hello World 应用程序。
顾名思义,Spring MVC 构建于模型-视图-控制器建筑学。DispatcherServlet
是 Spring MVC 应用程序中的前端控制器,负责处理所有传入请求并将它们委托给不同的控制器处理程序方法。
该模型可以是 Spring 框架中的任何 Java Bean,就像任何其他 MVC 框架一样,Spring 提供表单数据到 Java Bean 的自动绑定。我们可以将模型 bean 设置为要在视图页面中使用的属性。
视图页面可以是 JSP、静态 HTML 等,视图解析器负责查找正确的视图页面。一旦识别出视图页面,控制权就会交还给 DispatcherServlet 控制器。 DispatcherServlet 负责渲染视图并将最终响应返回给客户端。
Spring 通过资源包为本地化或 i18n 提供了出色的支持。使我们的应用程序本地化所需的基本步骤是:
- 为不同语言环境创建消息资源包,例如 messages_en.properties、messages_fr.properties 等。
- 定义消息源Spring bean 配置文件中的 bean 类型为 ResourceBundleMessageSource 或 ReloadableResourceBundleMessageSource。
- 要更改区域设置支持,请定义语言环境解析器CookieLocaleResolver 类型的 bean 并配置 LocaleChangeInterceptor 拦截器。配置示例如下:
<beans:bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<beans:property name="basename" value="classpath:messages" />
<beans:property name="defaultEncoding" value="UTF-8" />
</beans:bean>
<beans:bean id="localeResolver"
class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<beans:property name="defaultLocale" value="en" />
<beans:property name="cookieName" value="myAppLocaleCookie"></beans:property>
<beans:property name="cookieMaxAge" value="3600"></beans:property>
</beans:bean>
<interceptors>
<beans:bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<beans:property name="paramName" value="locale" />
</beans:bean>
</interceptors>
- Use
spring:message
具有键名称的视图页面中的元素,DispatcherServlet 选择相应的值并以相应的语言环境呈现页面并作为响应返回。
如需完整示例,请阅读Spring 本地化示例.
我们可以使用 Spring 框架创建返回 JSON 数据的 Restful Web 服务。 Spring 提供了与 Jackson JSON API 的集成,我们可以使用它在 Restful Web 服务中发送 JSON 响应。
我们需要执行以下步骤来配置 Spring MVC 应用程序以发送 JSON 响应。
1. 添加 Jackson JSON 依赖项,如果您使用 Maven,可以使用以下代码完成:
<!-- Jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.databind-version}</version>
</dependency>
2. 在 Spring bean 配置文件中配置 RequestMappingHandlerAdapter bean,并将消息转换器属性设置为 MappingJackson2HttpMessageConverter bean。示例配置为:
<!-- Configure to plugin JSON as request and response in method handler -->
<beans:bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<beans:property name="messageConverters">
<beans:list>
<beans:ref bean="jsonMessageConverter"/>
</beans:list>
</beans:property>
</beans:bean>
<!-- Configure bean to convert JSON to POJO and vice versa -->
<beans:bean id="jsonMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
</beans:bean>
3. 在控制器处理程序方法中,使用以下方法返回对象作为响应@ResponseBody
注解。示例代码:
@RequestMapping(value = EmpRestURIConstants.GET_EMP, method = RequestMethod.GET)
public @ResponseBody Employee getEmployee(@PathVariable("id") int empId) {
logger.info("Start getEmployee. ID="+empId);
return empData.get(empId);
}
4.您可以通过任何API调用rest服务,但如果您想使用Spring,那么您可以使用RestTemplate类轻松完成。
如需完整示例,请阅读Spring Restful Web 服务示例.
我在项目中使用的一些 Spring 注释是:
-
@控制器– 用于 Spring MVC 项目中的控制器类。
-
@RequestMapping– 用于在控制器处理程序方法中配置 URI 映射。这是一个非常重要的注释,因此您应该仔细阅读Spring MVC RequestMapping 注解示例
-
@ResponseBody– 用于发送对象作为响应,通常用于发送 XML 或 JSON 数据作为响应。
-
@路径变量– 用于将动态值从 URI 映射到处理程序方法参数。
-
@Autowired– 用于 spring bean 中的自动装配依赖关系。
-
@预选赛 – with @Autowired注释以避免存在多个 bean 类型实例时出现混淆。
-
@Service– 用于服务等级。
-
@Scope– 用于配置 spring bean 的范围。
-
@配置, @ComponentScan, and @Bean– 用于基于 java 的配置。
- 用于配置方面和建议的 AspectJ 注释,@Aspect, @Before, @After, @Around, @切入点, etc.
是的,我们可以,使用@ResponseBody注解。这就是我们在 Restful Web 服务中发送基于 JSON 或 XML 的响应的方式。
Spring 提供了对通过以下方式上传文件的内置支持多部分解析器接口实现。它非常易于使用,只需更改配置即可运行。我们需要编写控制器处理程序方法来处理传入的文件并处理它。完整的例子请参考Spring文件上传示例.
Spring 支持 JSR-303 基于注释的验证,并提供了一个 Validator 接口,我们可以实现该接口来创建我们自己的自定义验证器。为了使用基于 JSR-303 的验证,我们需要使用所需的验证来注释 bean 变量。
对于自定义验证器实现,我们需要在控制器类中配置它。如需完整示例,请阅读Spring MVC 表单验证示例.
Spring MVC 拦截器类似于 Servlet 过滤器,允许我们拦截客户端请求并处理它们。我们可以在三个地方拦截客户端请求 –预处理, 后句柄, and 完成后.
我们可以通过实现HandlerInterceptor接口或者扩展抽象类来创建Spring拦截器处理程序拦截器适配器.
我们需要在spring bean配置文件中配置拦截器。我们可以定义一个拦截器来拦截所有客户端请求,也可以将其配置为特定的 URI 映射。详细示例请参考Spring MVC 拦截器示例.
Spring Framework 提供了与 JDBC API 的出色集成,并提供了 JdbcTemplate 实用程序类,我们可以使用它来避免数据库操作逻辑(例如打开/关闭连接、ResultSet、PreparedStatement 等)中的 bolier-plate 代码。
JdbcTemplate示例请参考Spring JDBC 示例.
为了使用servlet容器配置的JNDI DataSource,我们需要在spring bean配置文件中配置它,然后将其作为依赖项注入到spring bean中。然后我们可以使用它JdbcTemplate
来执行数据库操作。
<beans:bean id="dbDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<beans:property name="jndiName" value="java:comp/env/jdbc/MyLocalDB"/>
</beans:bean>
完整示例请参考Spring Tomcat JNDI 示例.
Spring框架通过声明式事务管理和编程式事务管理提供事务管理支持。声明式事务管理使用最广泛,因为它易于使用并且适用于大多数情况。
我们使用注释方法@Transactional
声明式事务管理的注释。我们需要在 spring bean 配置文件中为 DataSource 配置事务管理器。
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
提供 Spring DAO 支持,以便以一致且简单的方式使用 JDBC、Hibernate 等数据访问技术。例如,我们有针对各自技术的 JdbcDaoSupport、HibernateDaoSupport、JdoDaoSupport 和 JpaDaoSupport。
Spring DAO 还提供了异常层次结构的一致性,我们不需要捕获特定的异常。
我们可以使用 Spring ORM 模块来集成 Spring 和 Hibernate 框架,如果您使用 Hibernate 3+,其中 SessionFactory 提供当前会话,那么您应该避免使用 HibernateTemplate 或 HibernateDaoSupport 类,最好使用带有依赖注入的 DAO 模式进行集成。
Spring ORM 提供对使用 Spring 声明式事务管理的支持,因此您应该利用它而不是使用 Hibernate 样板代码进行事务管理。
为了更好地理解,您应该阅读以下教程:
- Spring Hibernate 集成示例
- Spring MVC Hibernate 集成示例
Spring安全框架专注于在java应用程序中提供身份验证和授权。它还可以解决大多数常见的安全漏洞,例如 CSRF 攻击。
通过使用注释,在 Web 应用程序中使用 Spring 安全性非常有益且简单@EnableWebSecurity
。您应该阅读以下文章来了解如何使用 Spring Security 框架。
- Servlet Web 应用程序中的 Spring Security
- Spring MVC 和 Spring Security 集成示例
我们必须定义 propertyConfigurer bean,它将从给定的属性文件加载属性。然后我们可以使用 Spring EL 支持将属性注入到其他 bean 依赖项中。例如:
<bean id="propertyConfigurer"
class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<property name="location" value="/WEB-INF/application.properties" />
</bean>
<bean class="com.journaldev.spring.EmployeeDaoImpl">
<property name="maxReadResults" value="${results.read.max}"/>
</bean>
如果您使用注释来配置 spring bean,那么您可以像下面这样注入属性。
@Value("${maxReadResults}")
private int maxReadResults;
Spring框架使用了很多设计模式,一些常见的有:
-
单例模式:创建具有默认范围的bean。
-
工厂模式:Bean工厂类
-
原型模式:Bean 范围
-
适配器模式:Spring Web 和 Spring MVC
-
代理模式:Spring 面向方面编程支持
-
模板方法模式:JdbcTemplate、HibernateTemplate等
- 前端控制器:Spring MVC DispatcherServlet
-
数据访问对象: Spring DAO 支持
- 依赖注入和面向方面的编程
Spring 框架的一些最佳实践是:
- 避免在架构引用中使用版本号,以确保我们拥有最新的配置。
- 根据关注点划分 spring bean 配置,例如 spring-jdbc.xml、spring-security.xml。
- 对于在 Spring MVC 中的多个上下文中使用的 spring bean,请在根上下文中创建它们并使用侦听器进行初始化。
- 尽可能配置bean依赖,尽量避免自动装配。
- 对于应用程序级属性,最好的方法是创建一个属性文件并在 spring bean 配置文件中读取它。
- 对于较小的应用程序,注释很有用,但对于较大的应用程序,注释可能会变得很痛苦。如果我们将所有配置都保存在 XML 文件中,维护起来会更容易。
- 为组件使用正确的注释,以便轻松理解其用途。用于服务用途@Service以及 DAO beans 使用@存储库.
- Spring框架有很多模块,按需使用即可。删除通过 Spring Tool Suite 模板创建项目时通常添加的所有额外依赖项。
- 如果您正在使用方面,请确保连接点尽可能窄,以避免建议不需要的方法。考虑使用更易于使用并避免任何问题的自定义注释。
- 当有实际好处时使用依赖注入,只是为了松散耦合而不使用它,因为它更难维护。
Spring Boot 使得 spring 框架独一无二。它为我们提供了一种简单的方法来创建不同类型的 Java 应用程序并将它们附加到 servlet 容器运行时环境。这样我们就得到了一个可以运行来执行项目的 JAR 文件。这为我们节省了大量时间,可以非常快速地获得可用于产品部署的框架项目。这样我们就可以更多地关注业务逻辑,而不是经历构建代码然后将其部署到 servlet 容器上的常见过程。由于这是一个非常广泛的主题,我建议您仔细阅读Spring Boot 面试问题.
这就是 Spring 框架面试问题的全部内容。希望这些问题对您接下来的 Java EE 面试有所帮助。一旦发现更多问题,我将继续添加到列表中。如果您知道更多应该包含在列表中的问题,请务必为其添加评论,我会将其包含在内。