0


【Spring面试题】第十期:框架篇之Spring Framework,每周10道,学废拿捏面试官~

每周10道Java面试题~第十期

1️⃣ 各个版本的Spring Framework有哪些主要功能?

图1 Spring Framework Logo

Spring Framework 历经2004年发布的 1.0版本到 2018年的 5.0版本,已经逐步发展成为一个功能强大、灵活多样的开发框架,被广泛应用于企业级Java应用程序的开发。

并且Spring Framework在2022年底还发布了 6.0新版本的相关消息,Spring Framework 6.0将继续推动Spring生态系统的发展,提供更加先进、灵活和高效的开发工具,以满足不断变化的业务需求和技术趋势。

下面是各个版本的Spring Framework的主要功能:

  • 1.x 版本:主要提供了 IoC(Inversion of Control,控制反转)和AOP(Aspect Oriented Programming,面向切面编程)功能,并提供了对JDBC访问和事务管理的支持;
  • 2.x 版本:在1.x版本的基础上,引入了注解支持、Java 5特性支持,增加了对Web应用程序的支持,包括MVC框架和Web服务的支持;
  • 3.x 版本:支持 Java EE 6标准、RESTful风格的Web服务支持、Spring Expression Language(SpEL) 等新功能;
  • 4.x 版本:增加了对Java 8新特性的支持,包括Lambda表达式和Stream API的支持等,提供Groovy语言支持、WebSocket支持 等新功能;
  • 5.x 版本:引入了 响应式编程模型,提供了对 Reactive Streams和 WebFlux的支持,同时也支持Java 9和Java 10的新特性
  • 6.x 版本(即将发布):支持Java 17中的新特性和改进,采用模块化的架构将核心框架和各种扩展模块分离,支持更多的数据访问技术(例如NoSQL数据库、图形数据库等)等。

2️⃣ 什么是Spring Framework?

图2 Spring Framework 核心组件

Spring Framework是一个开源的Java应用程序框架,最初由Rod Johnson在2003年创建。框架旨在通过丰富的特性和功能,帮助开发人员构建高效、灵活、可维护的应用程序。Spring框架提供了许多功能,包括依赖注入、AOP、JDBC集成、事务管理、Web应用程序开发等。

Spring框架的核心部分有:

  • IoC容器:Spring的IoC容器负责管理应用程序中的对象,并处理它们之间的依赖关系。开发人员只需定义对象和它们之间的关系,Spring容器就会自动创建和管理这些对象。这样可以将应用程序的逻辑与对象的创建和管理分离,提高了代码的可重用性和可维护性;
  • 面向切面编程(AOP):通过AOP,可以将横切关注点(如日志记录、事务管理、安全性等)与业务逻辑分离,使得应用程序的代码更加简洁、可读性更高;
  • JDBC集成:Spring框架提供了JDBC模板,简化了JDBC编程,使得开发人员可以更加方便地访问和操作数据库;
  • 事务管理:Spring框架提供了一种统一的事务管理机制,可以管理多个事务资源,如数据库连接、JMS队列等。开发人员可以通过声明式事务管理,将事务管理逻辑与业务逻辑分离;
  • Web应用程序开发:Spring框架提供了一个MVC框架,用于开发Web应用程序。MVC框架提供了控制器、视图、模型等组件,使得开发人员可以更加方便地开发Web应用程序。

除了以上主要特点外,Spring框架还提供了许多其他的功能,如集成测试、缓存、安全性、远程调用等。Spring框架的目标是提供高效、灵活、可重用的代码,使得Java开发人员可以更加方便地开发高质量的应用程序。


3️⃣ Spring Framework有哪些优点?有哪些缺点?

👉 作为一款优秀的开发框架,Spring Framework有以下优点:

  • 简化开发工作:提供了丰富的功能和特性,可以简化开发人员的工作,让开发人员可以更加专注于业务逻辑的实现,而不用关注底层的技术细节;
  • 提高代码质量:提供了一系列的最佳实践和设计模式,可以帮助开发人员编写高质量、可维护、可扩展的代码;
  • 提高代码重用性:IoC容器和 AOP机制可以帮助开发人员实现组件的重用,使得代码更易于维护和扩展;
  • 提高程序性能:JDBC模板、缓存、事务管理等功能可以帮助开发人员实现高效的数据访问和数据处理,提高应用程序的性能;
  • 提高程序安全性:提供了一系列的安全性功能,如身份验证、访问控制、加密等,可以帮助开发人员实现应用程序的安全性;
  • 支持集成测试:框架支持集成测试,可以帮助开发人员进行端到端的测试,保证应用程序的质量;
  • 开放源代码:Spring框架是开放源代码的,开发人员不仅可以通过阅读源码学习和了解原理,还可以通过参与Spring社区,获取更多的技术支持和帮助。

📃 当然,凡事都有两面性,即便优秀如Spring Framework 也不例外,它也有以下几个缺点:

  • 学习曲线较陡峭:Spring框架是一个庞大的框架,提供了丰富的功能和特性,学习起来需要花费一定的时间和精力;
  • 运行效率较低:庞大体系结构和强大的功能特性会导致一定的性能损失。如果应用程序对性能要求比较高,可能需要进行优化;
  • 配置较为复杂:Spring框架需要进行大量的配置,包括IoC容器的配置、AOP的配置、数据源的配置等。这些配置需要开发人员具备一定的技术水平,同时也会增加开发时间和成本;
  • 依赖关系较为复杂:Spring框架的各个模块之间存在较为复杂的依赖关系,如果某个模块出现问题,可能会影响到其他模块的正常运行;
  • 版本兼容:Spring框架的版本更新时,新版本可能会带来新的功能和特性,但也会导致一些旧版本的应用程序无法兼容。

4️⃣ Spring Framework中主要有哪些模块,分别提供什么功能?

图3 Spring Framework 核心模块

Spring Framework主要包含以下模块:

  • Spring Core模块:提供 IoC和 DI功能,包括 BeanFactory、ApplicationContext等;
  • Spring AOP模块:提供 AOP功能,包括切面(Aspect)、连接点(Join Point)、通知(Advice)等。
  • Spring Context 模块:向Spring框架提供上下文信息。Spring上下文包括企业服务,如JNDI、EJB、电子邮件、国际化、校验和调度功能;
  • Spring ORM模块:提供ORM(Object-Relational Mapping)功能,包括对Hibernate、JPA等的支持;
  • Spring DAO模块:Spring 中的DAO提供一致的方式访问数据库,不管采用何种持久化技术,Spring都提供一致的编程模型。Spring还对不同的持久层技术提供一致的DAO方式的异常层次结构;
  • Spring Web模块:提供Web开发相关的功能,包括Spring MVC、WebSocket等;
  • Spring Web MVC 模块:Spring的MVC框架提供清晰的角色划分:控制器、验证器、命令对象、表单对象和模型对象、分发器、处理器映射和视图解析器。

这些模块为应用程序开发提供了广泛的支持,使得开发者可以快速地构建高质量、可维护的应用程序。


5️⃣ 什么是Spring配置文件?

Spring配置文件是指在Spring框架中用来配置应用程序组件的XML文件。

applicationContext.xml是Spring的默认配置文件,当容器启动时找不到指定的配置文档时,将会尝试加载这个默认的配置文件。

Spring配置文件通常存储在应用程序的classpath路径下,并由Spring框架在应用程序启动时加载。除了XML格式,Spring还支持其他格式的配置文件,如JavaConfig和GroovyConfig等。

它通常包含了Spring应用程序中各种对象的定义和它们之间的关系,例如 bean的定义、依赖注入、AOP配置、数据源配置等。Spring框架使用这些配置文件来实例化应用程序中的组件,并将它们装配在一起以构建完整的应用程序。

  • Bean定义:定义Spring中的各个组件和对象,包括数据源、事务管理器、服务层、DAO层等。可以通过配置文件中的bean标签进行定义和配置;
  • 属性注入:配置Bean中的属性,包括基本类型、引用类型、集合类型等。可以通过配置文件中的property标签进行配置;
  • 依赖注入:配置Bean之间的依赖关系,包括构造函数注入和setter方法注入两种方式。可以通过配置文件中的 constructor-arg和 property标签进行配置;
  • AOP配置:配置Spring框架中的AOP(面向切面编程)功能,包括切面、切点、通知等。可以通过配置文件中的aop命名空间进行配置;
  • MVC配置:配置Spring框架中的MVC(模型-视图-控制器)功能,包括控制器、视图解析器、视图渲染器等。可以通过配置文件中的mvc命名空间进行配置;
  • 数据源配置:可以配置数据库连接池、数据库驱动、数据库用户名密码等信息。可以通过配置文件中的datasource标签进行配置;
  • 事务配置:可以配置Spring框架中的事务管理器、事务注解等信息。可以通过配置文件中的tx命名空间进行配置。

Spring配置文件的编写需要遵循一定的规则和约定,可以通过Spring容器来读取和解析配置文件,并创建相应的Bean对象和组件。配置文件的正确性和合理性对于Spring应用程序的正常运行和性能表现至关重要。

🔍 关于spring的配置文件的更详细的各项配置的详情,可以参考这篇文章:
spring配置文件详解


6️⃣ 详细讲一下Spring IOC及其实现原理?

图4 Spring IOC 工作流程

Spring IOC(Inversion of Control,控制反转)是Spring框架的核心思想,它的实现手段是通过依赖注入(DI,Dependency Injection) 的方式来实现。

在传统的应用程序中,对象之间的依赖关系是由程序代码在对象内部通过new关键字等方式硬编码而成。而在Spring框架中,对象之间的依赖关系是由Spring容器在运行期间动态地通过反射机制等技术来进行注入 的。对于Spring而言,就是由Spring来控制对象的生命周期和对象之间的关系。

具体来说,Spring IOC的实现原理包括以下几个步骤:

  • 配置Bean:在Spring配置文件中配置Bean的定义和属性,包括类名、属性、依赖关系等;
  • 加载配置文件:Spring容器在启动时读取配置文件,解析配置文件中的Bean定义和属性;
  • 创建Bean实例:根据配置文件中的Bean定义,Spring容器使用Java反射机制创建Bean实例;
  • 注入属性:Spring容器根据Bean定义中的属性信息,使用Java反射机制将Bean需要依赖的其他Bean实例注入到当前Bean实例中;
  • 容器管理Bean实例:Spring容器管理Bean实例的生命周期,包括创建、初始化、使用、销毁等。

通过IOC和DI的方式,Spring框架实现了应用程序中各个组件之间的解耦,使得应用程序更加灵活和易于扩展。


7️⃣ 什么是Spring IOC容器?

Spring 容器是 Spring 框架的核心。容器创建对象,将它们装配在一起,配置它们并管理它们的完整生命周期。

Spring 容器使用依赖注入来管理组成应用程序的组件。容器通过读取提供的配置元数据来接收对象进行实例化,配置和组装的指令。该元数据可以通过 XML,Java 注解或 Java 代码提供。

在Spring中IOC容器的主要表现形式是 BeanFactory和 ApplicationContext这两个接口。这两个接口的具体实现类就可以看成是IOC容器在Spring中的具体体现。

BeanFactory提供了最基本的IOC和依赖注入功能,ApplicationContext继承了BeanFactory,在BeanFactory的基础上添加了很多新功能,主要包括国际化、事件分发机制(ApplicationEvent)、资源访问(Resource)等功能。在实际的开发过程中,一般都会选择ApplicationContext系列的容器实现。

图5 容器之 BeanFactory

图6 容器之 ApplicationContext


8️⃣ 依赖注入(DI)是什么?有哪些方式完成依赖注入?优缺点是什么?

依赖注入(DI,Dependency Injection)是 spring 框架核心 IoC 的具体实现手段或方式。所谓依赖注入,即在运行期由容器将依赖关系注入到组件之中。

就是在运行期,由Spring根据配置文件,将其他对象的引用通过组件的提供的setter方法进行设定。
Spring 大量引入了Java 的Reflection机制,通过动态调用的方式避免硬编码方式的约束,并在此基础上建立了其核心组件BeanFactory,以此作为其依赖注入机制的实现基础。

在Spring框架中,可以通过以下方式实现依赖注入:

  • 构造器注入(Constructor Injection):通过构造方法来完成对依赖的注入。 通过添加@Component 或@Service 等注解使 bean受Spring容器管理,再将依赖以参数形式传递给构造函数。@ServicepublicclassUserServiceImplimplementsUserService{privatefinal UserMapper userMapper;@AutowiredpublicUserServiceImpl(UserMapper userMapper){this.userMapper = userMapper;}}
  • Setter方法注入(Setter Injection):在bean中创建setter方法,并在该方法上使用@Autowired、@Resource等注解,Spring会自动调用这些setter方法并注入需要的依赖项;@ServicepublicclassUserServiceImplimplementsUserService{private UserMapper userMapper;@AutowiredpublicvoidsetUserMapper(UserMapper userMapper){this.userMapper = userMapper;}}
  • 属性注入(Field Injection,也叫字段注入或变量注入):在bean中定义成员变量并将其标记为@Autowired或@Resource等注解,Spring会自动将相应的依赖对象注入到这些字段上;@ServicepublicclassUserServiceImplimplementsUserService{@Autowiredprivate UserMapper userMapper;//...}

以上就是各种依赖注入的实现方式。其优势及缺点如下:
实现方式优点缺点属性注入方式简单,代码简洁注入对象不能用final修饰;
可能会导致循环依赖,启动不报错,使用时才报错;
存在潜在隐患,不调用将无法发现 NullPointException异常;构造器注入注入对象可以使用final修饰;
若存在循环依赖,spring项目启动的时候就会报错;
通过强制指明依赖注入来保证这个类的运行,防止NullPointerException;当有多个对象需要注入时,构造函数的代码臃肿;Setter方法注入依赖注入中使用的依赖是可选的,注入的依赖可以为 null;
允许在类构造完成后重新注入;注入对象不能使用final修饰;
其中,建议使用构造方法注入和setter方法注入,因为它更为清晰明了且不会导致循环依赖问题。而属性注入则容易引发一些设计和测试问题。


9️⃣ Spring Bean有哪几种作用域?有什么区别?

在Spring框架中,Bean作用域(scope)指的是在不同环境下创建和管理Bean时的生命周期。
一个Bean实例会有自己的作用域,而总共有以下5种的作用域情况:

  • Singleton(单例):一个IoC容器中只能存在一个实例,不同容器之间可以有不同的实例。这种bean范围是默认的,这种范围下不管接受到多少个请求,每个容器中只会有一个bean的实例;
  • Prototype(原型):每个请求都会创建一个新的实例,每次调用getBean()都会返回一个新的对象。这意味着每个客户端将获得一个新的原型实例,并且与之前连接的客户端没有关系;
  • Request(请求):仅适用于WebApplicationContext上下文中,表示为每个HTTP请求创建一个新的Bean实例。因此,对于同一次HTTP请求而言,任何对Bean的请求都将返回同一个Bean实例。然而,不同的HTTP请求将产生不同的Bean实例;
  • Session(会话)也仅适用于WebApplicationContext上下文中,表示为每个HTTP会话创建一个新的Bean实例。同一会话中的多个请求将共享同一个Bean实例;
  • GlobalSession(全局会话):仅适用于web应用程序,表示为每个全局HTTP会话创建一个新的Bean实例,通常只在使用Spring Portlet MVC时才使用。如果部署在Servlet环境下,该作用域没有区别于Session。

在实际应用中,正确选择和使用适当的作用域很重要。在大多数情况下,Singleton是最合适和高效的选项,也是默认作用域,它创建一个对象并在容器内共享该对象。Prototype每次请求都会创建一个新的实例,因此它可以防止线程安全问题。Request和Session将实例的作用域限制在HTTP请求/会话期间。GlobalSession作用域基本不使用,只适用于特殊的portlet场景。


🔟 详细讲一下Spring AOP及其实现原理?

Spring AOP(面向切面编程)是Spring框架的一个核心功能,它允许将不同但相关的业务逻辑组件解耦,从而提高了应用程序的可维护性和可重用性。

通过使用Spring AOP,我们可以将与业务逻辑无关的各种横向关注点(如日志记录、事务管理、安全性、缓存等)从业务逻辑中分离出来,避免代码重复,并使得代码更加清晰易懂。

在Spring AOP中,切面(Aspect)是对横向关注点的抽象。切面包含了具体的切点(Pointcut)和通知(Advice),其中切点定义了何时织入通知,而通知则定义了何种行为需要执行。

其工作流程具体如下:

  • 定义切入点:我们需要定义一个或多个切入点以便确定哪些方法需要被拦截处理。切入点指定的是方法的名称和任意参数类型;
  • 编写通知(增强):在Spring AOP中,通知(Advice)是应用在切入点之前或者之后执行的一种代码块。Spring AOP支持以下5种通知类型:- 前置通知(Before advice):在目标方法执行前执行;- 后置通知(After advice):在目标方法执行后执行;- 返回通知(After returning advice):在目标方法执行完并返回结果之后执行;- 异常通知(After throwing advice):在目标方法抛出异常后执行;- 环绕通知(Around advice):包围目标方法的通知,可以在目标方法执行前、执行后、执行返回或抛出异常时执行。
  • 创建代理对象:在运行期间,Spring AOP会为目标对象创建一个代理对象。代理对象通过Spring容器返回给客户端;
  • 执行拦截:在调用代理对象的方法时,Spring AOP自动检查方法是否需要拦截(即是否匹配切入点),如果匹配,则执行相应的通知代码块,然后再调用原始的目标方法。

而从原理上来说,Spring AOP是基于动态代理的实现方式来实现切面编程的。针对不同类型的bean,Spring使用JDK动态代理或CGLIB(Code Generation Library)字节码生成技术来创建代理对象。

其中,如果目标对象实现了至少一个接口,则Spring AOP将使用JDK动态代理。基本原理是利用 Java 的反射机制生成目标对象的代理对象,通过调用代理对象之前调用“前置通知”拦截方法,进行切面编程。

如果目标对象没有实现任何接口,则 Spring AOP 将使用CGLIB(Code Generation Library)库来实现代理。基本原理是在内存中构建出目标对象子类的字节码并载入 JVM 中,生成目标对象的代理对象,也通过调用代理对象之前调用“前置通知”拦截方法,同样可以实现切面编程。

Spring AOP 使用 BeanPostProcessor 在应用中动态创建和织入切面。BeanPostProcessor 拦截容器创建的对象,如果该对象匹配被代理的对象,则会根据上面的两种方式其一,来创建一个新的代理对象并返回。通过使用 BeanPostProcessor,AOP 识别它需要拦截的 bean,并且将切面编织到相应的代码中。

因此,在 Spring AOP 中,BeanPostProcessor 扮演着非常重要的角色。它提供了一种机制,使开发人员可以对 Spring IOC 容器创建的每个 bean 进行定制化处理,进而进行 AOP 代理的创建和织入。


图片来源:
Spring Framework 官网
Spring、SpringBoot全家桶技术栈知识点汇总(欢迎收藏)
Spring系列(一)、Spring入门及七大模块
springboot分析-spring IOC原理拆解和spring MVC模块分析


🎁 小山赠书活动

图7 小山赠书第一期

书籍详情可以去某当、某宝、某东各个网站搜索书籍名称查看~
没有自己中意的可以自选噢,自选规则查看下文

🍻 朋友们,千粉福利来啦!
《小山劝学第1期》 👏 👏 👏
赠书说明:图示图书中任选一本或者不限制(¥100内的书籍自主选择,可以是 非软件行业的书噢,但只限一本噢
参与方式:关注+点赞+收藏,评论区评论 “勤能补拙,IT之路,共同进步!”(记得不要漏掉噢,否则抽奖无效

开奖时间:2023-06-16 12:00:00
开奖名额:3名
通知方式:开奖后我会向中奖用户发起私信并把结果公布在评论区,不弄虚作假哈~

标签: spring java 后端

本文转载自: https://blog.csdn.net/LVSONGTAO1225/article/details/131167292
版权归原作者 小山code 所有, 如有侵权,请联系我们删除。

“【Spring面试题】第十期:框架篇之Spring Framework,每周10道,学废拿捏面试官~”的评论:

还没有评论