Spring:常见的面试题和答案

1、什么是 Spring 框架?Spring 框架有哪些主要模块?

Spring 框架是一个为 Java 应用程序的开发提供了综合、广泛的基础性支持的 Java 平台。

Spring 帮助开发者解决了开发中基础性的问题,使得开发人员可以专注于应用程序的开发。

Spring 框架本身亦是按照设计模式精心打造,这使得我们可以在开发环境中安心的集成 Spring 框

架,不必担心 Spring 是如何在后台进行工作的。

Spring 框架至今已集成了 20 多个模块。这些模块主要被分如下图所示的核心容器、数据访问/集

成,、Web、AOP(面向切面编程)、工具、消息和测试模块。

2、Spring Framework 有哪些不同的功能?

  • 轻量级 - Spring 在代码量和透明度方面都很轻便。
  • IOC - 控制反转AOP - 面向切面编程可以将应用业务逻辑和系统服务分离,以实现高内聚。
  • 容器 - Spring 负责创建和管理对象(Bean)的生命周期和配置。
  • MVC - 对 web 应用提供了高度可配置性,其他框架的集成也十分方便。
  • 事务管理 - 提供了用于事务管理的通用抽象层。Spring 的事务支持也可用于容器较少的环境。
  • JDBC 异常 - Spring 的 JDBC 抽象层提供了一个异常层次结构,简化了错误处理策略。

3、Spring Framework 中有多少个模块,它们分别是什么?

答:Spring 核心容器 -- 该层基本上是 Spring Framework 的核心。它包含以下模块:

  • Spring Core
  • Spring Bean
  • SpEL (Spring Expression Language)
  • SpringContext
  • 数据访问/集成 -- 该层提供与数据库交互的支持。
    它包含以下模块:· JDBC (Java DataBase Connectivity) · ORM (Object Relational Mapping) · OXM (Object XML Mappers) · JMS (Java Messaging Service) · Transaction
  • Web -- 该层提供了创建 Web 应用程序的支持。它包含以下模块:· Web · Web -- Servlet · Web -- Socket · Web -- Portlet
  • AOP · 该层支持面向切面编程
  • Instrumentatio · 该层为类检测和类加载器实现提供支持。
  • Test · 该层为使用 JUnit 和 TestNG 进行测试提供支持。
    几个杂项模块: Messaging -- 该模块为 STOMP 提供支持。它还支持注解编程模型,该模型用于从 WebSocket 客户端路由和处理 STOMP 消息。 Aspects --该模块为与AspectJ的集成提供支持。

4、什么是控制反转(IOC)?什么是依赖注入?

答:控制反转是应用于软件工程领域中的,在运行时被装配器对象来绑定耦合对象的一种编程技巧,对象之间耦合关系在编译时通常是未知的。在传统的编程方式中,业 务逻辑的流程是由应用程序中的早已被设定好关联关系的对象来决定的。

在使用控制反转的情况下,业务逻辑的流程是由对象关系图来决定的,该对象关系图由装配 器负责实例化,这种实现方式还可以将对象之间的关联关系的定义抽

象化。而绑定的过程是通过"依赖注入"实现的。

控制反转是一种以给予应用程序中目标组件更多控制为目的设计范式,并在我们的实际工作中起到了

有效的作用。

依赖注入是在编译阶段尚未知所需的功能是来自哪个的类的情况下,将其他对象所依赖的功能对象实

例化的模式。这就需要一种机制用来激活相应的组件以提供特定的功能,所以依赖注入是控制反转的

基础。否则如果在组件不受框架控制的情况下,框架又怎么知道要创建哪个组件?

在 Java 中依然注入有以下三种实现方式:

  • 构造器注入
  • Setter 方法注入
  • 接口注入

5、反射的基本原理,反射创建类实例的三种方式是什么

答:反射机制就是使 Java 程序在运行时具有自省(introsp ect) 的能力,通过反射我们可以直接操作类 和对象,比如获取某个类的定义,获取类的属性和方法 构造方法等。创建类实例的三种方式是

  • 对象实例.getClass();
  • 通过 ClassforName()创建
  • 对象实例.newInstance)方法创建

6、 什么是 spring bean?

答:它们是构成用户应用程序主干的对象。

  • Bean 由 Spring IoC 容器管理。
  • 它们由 Spring IoC 容器实例化,配置,装配和管理。
  • Bean 是基于用户提供给容器的配置元数据创建。

7、 BeanFactory 和 ApplicationContext有什么区别?

答:

BeanFactory 可以理解为含有bean集合的工厂类。

BeanFactory 包含了种bean的定义,以便在接收到客户端请求时将对应的bean实例化。

BeanFactory还能在实例化对象的时生成协作类之间的关系。此举将bean自身与bean客户端的配置中解放出来。

BeanFactory还包含了bean生命周期的控制,调用客户端的初始化方法(initialization methods)和销毁方法(destruction methods)。

从表面上看,ApplicationContext如同BeanFactory 一样具有bean定义、bean关联关系的设置,根据请求分发bean的功能。但ApplicationContext在此基础上还提供了其他的功能。

  • 提供了支持国际化的文本消息
  • 统一的资源文件读取方式
  • 已在监听器中注册的bean的事件

8、解释Spring支持的几种bean的作用域

Spring框架支持以下五种bean的作用域:

  • singleton : bean在每个Spring ioc 容器中只有一个实例。
  • prototype:一个bean的定义可以有多个实例。
  • request:每次http请求都会创建一个bean,该作用域仅在基于web的Spring ApplicationContext情形下有效。
  • session:在一个HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。
  • global-session:在一个全局的HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。

注意: 缺省的Spring bean 的作用域是Singleton。使用 prototype 作用域需要慎重的思考,因为频繁创建和销毁 bean 会带来很大的性能开销。

Bash 复制代码
@Component
@Scope("prototype")
public class MyBean {
    // ...
}

9、什么是AOP? 有哪些AOP的概念?

答:AOP(Aspect-Oriented Programming)是一种编程思想,它通过将应用程序分解成多个切面,来实现对应用程序进行横向切割的目的,从而实现代码的复用和系统的解耦。

AOP的核心思想是将与业务逻辑无关的代码,如日志、事务、异常处理等,从业务逻辑代码中分离出来,形成独立的模块,以便于复用和维护。AOP的一些概念如下:

  • 切面(Aspect):切面是一个模块化的横切关注点,它通过对某个点进行拦截,来实现对目标对象的增强。

  • 连接点(Join Point):连接点是在应用程序执行过程中能够插入切面的点,例如方法调用或异常处理等。

  • 切入点(Pointcut):切入点是一组连接点的集合,它定义了在哪些连接点处应用切面。

  • 通知(Advice):通知是切面在连接点上执行的操作,例如在方法调用前、方法调用后、方法返回时或方法抛出异常时执行的操作。

  • 织入(Weaving):织入是将切面应用到目标对象并创建新的代理对象的过程。织入可以在编译时、类加载时或运行时进行。

  • 目标对象(Target Object):目标对象是应用程序中需要被增强的对象。

  • 代理对象(Proxy Object):代理对象是一个中间件对象,它拦截对目标对象的访问并调用切面提供的通知。

通过AOP的概念,我们可以将应用程序按照不同的横向关注点进行切割,并将与业务逻辑无关的代码分离出来,从而提高应用程序的可维护性和可扩展性。常见的AOP框架有Spring AOP和AspectJ。

10、AOP 有哪些应用场景?

答:AOP(Aspect-Oriented Programming)可以在许多场景下被应用。以下是一些AOP的应用场景:

  • 日志记录:在方法调用前后记录日志,用于排查错误和分析系统性能。

  • 安全性控制:控制用户对系统中某些资源或方法的访问权限,确保系统安全。

  • 事务管理:在方法调用前后开启、提交或回滚事务,确保数据的一致性和完整性。

  • 缓存管理:通过在方法调用前检查缓存中是否有目标对象的缓存结果,减少系统的响应时间和网络开销。

  • 性能监控:记录方法调用的时间、次数和异常等信息,以便于分析系统性能。

  • 异常处理:在方法调用过程中捕获异常并记录或通知开发人员,以便于及时处理异常情况。

  • 数据验证:在方法调用前对输入参数进行验证,确保输入数据的正确性和合法性。

  • 代码复用:将与业务逻辑无关的代码抽离出来,以便于复用和维护。

11、Spring 中有哪些设计模式?

  • 单例模式: Spring 的 Bean 默认是单例模式,即一个 Bean 对象只会被创建一次并在整个应用中共享。这种方式可以提高性能和资源利用率。

  • 工厂模式: Spring 使用工厂模式来创建和管理 Bean 对象,即通过 BeanFactory 或 ApplicationContext 等容器来创建和管理 Bean 对象。这种方式可以将对象的创建和管理解耦,并且可以灵活地配置和管理对象。

  • 代理模式:Spring 使用代理模式来实现 AOP(面向切面编程),即通过代理对象来增强原始对象的功能。这种方式可以实现横切关注点的复用,并且可以在不修改原始对象的情况下实现功能增强。

  • 观察者模式:Spring 使用观察者模式来实现事件驱动编程,即通过事件监听机制来处理事件。这种方式可以实现松耦合,使得对象之间的交互更加灵活。

  • 模板方法模式:Spring 使用模板方法模式来实现 JdbcTemplate、HibernateTemplate 等模板类,即将相同的操作封装在模板方法中,而将不同的操作交给子类来实现。这种方式可以减少重复代码,提高代码的复用性。

  • 适配器模式:Spring 使用适配器模式来实现不同接口之间的适配,如 Spring MVC 中的 HandlerAdapter 接口,可以将不同类型的 Controller 适配为统一的处理器。

  • 策略模式:Spring 使用策略模式来实现不同的算法或行为,如 Spring Security 中的 AuthenticationStrategy 接口,可以根据不同的认证策略来进行认证。

  • 装饰器模式:Spring 使用装饰器模式来动态地增加对象的功能,如 Spring MVC 中的 HandlerInterceptor 接口,可以在处理器执行前后添加额外的逻辑。

  • 组合模式:Spring 使用组合模式来实现复杂的对象结构,如 Spring MVC 中的 HandlerMapping 接口,可以将多个 HandlerMapping 组合成一个 HandlerMapping 链。

  • 迭代器模式:Spring 使用迭代器模式来访问集合对象中的元素,如 Spring 的 BeanFactory 和 ApplicationContext 等容器都提供了迭代器来访问其中的 Bean 对象。

  • 注册表模式:Spring 使用注册表模式来管理对象的注册和查找,如 Spring 的 BeanDefinitionRegistry 接口可以用来注册和管理 Bean 对象的定义。

  • 委托模式:Spring 使用委托模式来实现不同对象之间的消息传递,如 Spring 的 ApplicationEventMulticaster 接口可以将事件委托给不同的监听器进行处理。

  • 状态模式:Spring 使用状态模式来管理对象的状态,如 Spring 的 TransactionSynchronizationManager 类可以根据不同的事务状态来进行处理。

  • 解释器模式:Spring 使用解释器模式来解析和处理一些复杂的表达式和规则,如 Spring Security 中的表达式语言可以用来实现访问控制。

  • 桥接模式:Spring 使用桥接模式来将抽象和实现分离,如 Spring JDBC 中的 DataSource 接口可以与不同的数据库实现进行桥接。

12、@Autowired和@Resource之间的区别

  • @Autowired可用于:构造函数、成员变量、Setter方法
  • @Autowired和@Resource之间的区别
  • @Autowired默认是按照类型装配注入的,默认情况下它要求依赖对象必须存在(可以设置它required属性为false)。
  • @Resource默认是按照名称来装配注入的,只有当找不到与名称匹配的bean才会按照类型来装配注入。

13、 Spring事务的实现方式和实现原理

答:Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的。真正的数据库层的事务提交和回滚是通过binlog或者redo log实现的。

14、Spring 支持哪些 ORM 框架

  • Hibernate
  • iBatis
  • JPA
  • JDO
  • OJB

15、AOP 有哪些实现方式?

答:实现 AOP 的技术,主要分为两大类:静态代理 指使用 AOP 框架提供的命令进行编译,从而在编译阶段就可生成AOP代理类,因此也称为编译时增强;

  • 编译时编织(特殊编译器实现)
  • 类加载时编织(特殊的类加载器实现)。

动态代理 在运行时在内存中"临时"生成 AOP 动态代理类,因此也被称为运行时增强。

  • JDK 动态代理
  • CGLIB

16、Spring AOP and AspectJ AOP 有什么区别?

答:Spring AOP 基于动态代理方式实现;AspectJ 基于静态代理方式实现。

SpringAOP仅支持方法级别的 PointCut;提供了完全的 AOP 支持,它还支持属性级别的PointCut。

17、ApplicationContext 通常的实现是什么?

  • FileSystemXmlApplicationContext :此容器从一个 XML 文件中加载beans的定义,XML Bean 配置文件的全路径名必须提供给它的构造函数。
  • ClassPathXmlApplicationContext:此容器也从一个 XML 文件中加载beans的定义,这里,你需要正确设置 classpath 因为这个容器将在 classpath 里找bean配置。
  • WebXmlApplicationContext:此容器加载一个 XML 文件,此文件定义了一个WEB应用的 所有 bean。

18、Spring 框架中的单例 Bean 是线程安全的吗?

答:不,Spring 框架中的单例 bean 不是线程安全的。

19、使用 Spring 通过什么方式访问 Hibernate?

答:在 Spring 中 有 两 种 方 式 访 问 Hibernate :

  • 控 制 反 转 Hibernate Template 和 Callback。
  • 继承 HibernateDAOSupport 提供一个 AOP 拦截器。

20、 什么是SpringBoot?

SpringBoot是 Spring 开源组织下的子项目,是Spring组件一站式解决方案,主要是简化了使用Spring的难度,简略了繁重的配置,提供了各种启动器,开发者能快速上手。

21、SpringBoot有哪些优点?

  • 减少开发,减少测试时间。

  • 使用JavaConfig有助于避免使用XML。

  • 避免大量的Maven导入和各种版本冲突。

  • 提供意见发展方法。

  • 通过提供默认值快速开始开发。

22、Spring Boot 中的监视器是什么?

答:Spring boot actuator 是 spring 启动框架中的重要功能之一。Spring boot 监视器可帮助您访问生产环境中正在运行的应用程序的当前状态。有几个指标必须在生产环境中进行检查和监控。即使一些外部应用程序可能正在使用这些服务来向相关人员触发警报消息。监视器模块公开了一组可直接作为 HTTP URL 访问的REST 端点来检查状态。

23、Spring Boot项目中可以替换Tomcat服务器吗?

答:是的。如果需要,我们可以通过在 POM 中添加 maven 排除来删除 Tomcat 服务器。实际上,Web 服务器捆绑在started-web Spring Boot starter 依赖项中。应该添加排除。

bash 复制代码
<dependency> 
  <groupId>org.springframework.boot</groupId> 
  <artifactId>spring-boot-starter-web</artifactId> 
  <exclusions> 
    <exclusion> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId> spring-boot-starter-tomcat</artifactId> 
    </exclusion> 
  </exclusions> 
</dependency>

然后我们必须将任何其他服务器(如 Jetty)添加到 POM。无论如何,我们必须在删除 tomcat 后添加一个 Web 服务器。

bash 复制代码
<dependency> 
 <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<dependency> 
  <groupId>org.springframework.boot</groupId> 
  <artifactId>spring-boot-starter-jetty</artifactId> 
</dependency>

您现在将看到 Jetty 服务器日志,而不是 Tomcat。

24、Spring Boot的核心注解是哪些?

答:Spring Boot 的核心注解主要包括:

  • @SpringBootApplication:一个复合注解,包括了@Configuration、@EnableAutoConfiguration 和 @ComponentScan 三个注解,用于标识 Spring Boot 应用的主类。

  • @Configuration:表明该类是一个 Java 配置类,用于定义 Spring Bean 的配置信息。

  • @EnableAutoConfiguration:自动配置注解,用于开启 Spring Boot 的自动配置功能。

  • @ComponentScan:用于自动扫描和注册 Spring Bean。

除此之外,还有一些常用的注解,如:

  • @RestController:用于定义 RESTful 接口,相当于 @Controller 和 @ResponseBody 的组合。

  • @RequestMapping:用于定义 HTTP 请求的映射,用于处理 HTTP 请求。

  • @Autowired:自动注入注解,用于自动装配 Spring Bean。

  • @Value:属性注入注解,用于注入配置文件中的属性值。

这些注解共同组成了 Spring Boot 应用的核心框架。

25、什么是Spring Boot Starter?有哪些常用的?

答:Spring Boot Starter是一种特殊的依赖关系,它是为了方便Spring Boot应用程序的快速启动和集成而设计的。一个Starter通常会包含多个相关的依赖库,以及自动配置和其他必要的配置文件,使得我们只需引入一个Starter依赖,即可快速地集成相关的技术或库。

常用的Spring Boot Starter包括:

  • spring-boot-starter-web:适用于开发Web应用程序的Starter,包含Spring MVC、Tomcat和Spring Boot Web自动配置等。

  • spring-boot-starter-data-jpa:适用于使用JPA的Starter,包含Hibernate、Spring Data JPA、Spring ORM等依赖。

  • spring-boot-starter-data-redis:适用于使用Redis的Starter,包含Jedis客户端和Spring Data Redis等依赖。

  • spring-boot-starter-test:适用于测试的Starter,包含JUnit、Mockito、Hamcrest、Spring Test等依赖。

  • spring-boot-starter-actuator:适用于监控和管理Spring Boot应用程序的Starter,包含Spring Boot Actuator和Spring Boot Web等依赖。

通过使用Spring Boot Starter,我们可以非常方便地集成常用的技术和库,大大提高了开发效率和便捷性。

相关推荐
武子康7 分钟前
大数据-258 离线数仓 - Griffin架构 配置安装 Livy 架构设计 解压配置 Hadoop Hive
java·大数据·数据仓库·hive·hadoop·架构
豪宇刘1 小时前
MyBatis的面试题以及详细解答二
java·servlet·tomcat
秋恬意1 小时前
Mybatis能执行一对一、一对多的关联查询吗?都有哪些实现方式,以及它们之间的区别
java·数据库·mybatis
刘大辉在路上1 小时前
突发!!!GitLab停止为中国大陆、港澳地区提供服务,60天内需迁移账号否则将被删除
git·后端·gitlab·版本管理·源代码管理
FF在路上2 小时前
Knife4j调试实体类传参扁平化模式修改:default-flat-param-object: true
java·开发语言
真的很上进2 小时前
如何借助 Babel+TS+ESLint 构建现代 JS 工程环境?
java·前端·javascript·css·react.js·vue·html
众拾达人3 小时前
Android自动化测试实战 Java篇 主流工具 框架 脚本
android·java·开发语言
皓木.3 小时前
Mybatis-Plus
java·开发语言
不良人天码星3 小时前
lombok插件不生效
java·开发语言·intellij-idea
守护者1703 小时前
JAVA学习-练习试用Java实现“使用Arrays.toString方法将数组转换为字符串并打印出来”
java·学习