面试集中营—Spring篇

2024-05-06 17:52
文章标签 java 面试 spring 集中营

本文主要是介绍面试集中营—Spring篇,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Spring 框架的好处

        1、轻量:spring是轻量的,基本的版本大约2MB;

        2、IOC:控制反转,Spring的IOC机制使得对象之间的依赖不再需要我们自己来控制了,而是由容易来控制,一个字:爽;

        3、AOP:切面编程,Spring提供的AOP技术可以把应用逻辑和系统服务分来,编码更灵活,更方便;

        4、MVC框架:如果使用过Struts2的同学,使用springmvc就会觉得非常的舒适,spring提供的mvc框架是一个非常优秀的Web框架;

        5、全局事务管理:Spring提供一个持续的事务管理接口,可以扩展到上至本地事务下至全局事务;

        6、统一异常处理:

Autowired 和 Resource 注解的区别

        共同点:都是做bean注入时使用的,都可以写在字段或者setter方法上面;

        不同点:

        1、包归属不同,@Autowired是Spring提供的注解,@Resource是javax提供的注解;

        2、寻找bean的方式不同,@Resource默认是优先根据名称查找bean,而@Autowired默认是优先根据类型查找bean

SpringMVC的运行机制

        这个问题已经很古老的,很多面试官也不会问,因为大家的侧重点都是在分布式高并发还有场景问题上。SpringMVC的处理请求过程或者说运行机制吧,大家可以通过设计模式的方式来去学习。

MVC模式

        MVC分别代表了Model、View、Controller三个处理节点

        C:控制器层,用于接受请求,调用业务类,最后派发页面;

        M:数据模型层(包含service、dao、entity)主要是处理业务数据并返回处理结果;

        V:视图渲染层,主要为了渲染页面。

        在当前前后端分离已经成为了一个常态的情况下,V已经逐渐淡化了,但是在5年前前后端分离还没有那么的成熟,如果回到2016年,当时主流前端线下课都还没有vue2的课程存在,就是三大框架+jquery;那么mvc这个模式就是老子天下第一;

工作原理 

        springmvc主要通过中央处理器(DispatcherServlet)来统一调度。如下图所示

Bean的生命周期 

        经典的问题。提到生命周期,我们应该想到的是spring能够IOC其实就是保存了一个bean的实例池,所以生命周期的前期一定是实例化和初始化,实例化就是把对象在内存空间中分配出来,初始化就是给对象的属性赋值。当一个bean完成了使命后就要面临销毁,就会有一个销毁的过程。

        只不过为了方便扩展,spring把实例化和初始化的过程进行了多重封装,方便开发者去介入bean的实例化过程。具体如下:

        1、实例化 Bean

        对于 BeanFactory 容器,当客户向容器请求一个尚未初始化的 bean 时,或初始化 bean 的时候需要 注 入 另 一 个 尚 未 初 始 化 的 依 赖 时 , 容 器 就 会 调 用 createBean 进 行 实 例 化 。 对于 ApplicationContext容器,当容器启动结束后,通过获取 BeanDefinition 对象中的信息,实例 化所有的 bean

       2、设置对象属性(依赖注入):

       实例化后的对象被封装在 BeanWrapper 对象中,紧接着, Spring 根据 BeanDefinition 中的信
息以及通过 BeanWrapper 提供的设置属性的接口完成依赖注入。
      

       3、处理 Aware 接口:

        接着,Spring 会检测该对象是否实现了 xxxAware 接口,并将相关的 xxxAware 实例注入 Bean

  • 如果这个 Bean 已经实现了 BeanNameAware 接口,会调用它实现的 setBeanName(String beanId)方法,此处传递的就是 Spring 配置文件中 Bean id 值;
  • 如果这个 Bean 已经实现了 BeanFactoryAware 接口,会调用它实现的 setBeanFactory()方法,传递的是 Spring 工厂自身。
  • 如果这个 Bean 已经实现了 ApplicationContextAware 接口,会调用setApplicationContext (ApplicationContext)方法,传入Spring上下文;

        4、BeanPostProcessor:

        如果想对 Bean 进行一些自定义的处理,那么可以让 Bean 实现了 BeanPostProcessor 接口,那将会调用 postProcessBeforeInitialization(Object obj, Strings方法。

        5、InitializingBean 与 init-method

        如果 Bean 在 Spring 配置文件中配置了 init-method 属性,则会自动调用其配置的初始化方法

        6、 如果这个Bean实现了BeanPostProcessor 接口,将会调用postProcessAfterInitialization (Object obj, Strings)方法;由于这个方法是在 Bean 初始化结束时调用的,所以可以被应用于内存或缓存技术;

       7、DisposableBean

        当 Bean 不再需要时,会经过清理阶段,如果 Bean 实现了 DisposableBean 这个接口,会调用其实现 的 destroy(方法;

      8、destroy-method

       最后,如果这个 Bean 的 Spring 配置中配置了 destroy-method 属性,会自动调用其配置的销 毁方法。

spring框架中都用到了哪些设计模式

1、简单工厂模式 Spring 中的 BeanFactory 就是简单工厂模式的体现。根据传入一个唯一的标识来获得Bean 对象,但是在传入参数后创建还是传入参数前创建,要根据具体情况来定。

2、工厂模式 Spring 中的 FactoryBean 就是典型的工厂方法模式,实现了 FactoryBean 接口的
bean 是一类叫做 factory bean 。其特点是, spring 在使用 getBean() 调用获得该 bean 时,
会自动调 用该 bean getObject() 方法,所以返回的不是 factory 这个 bean ,而是这个
bean.getOjbect() 方法的返回值。
3、单例模式 :在 spring 中用到的单例模式有:scope="singleton" ,注册式单例模式, bean 存放
Map 中。 bean name 当做 key bean 当做 value
4、原型模式 :在 spring 中用到的原型模式有:scope="prototype" ,每次获取的是通过克隆生成的新实例,对其进行修改时对原有实例对象不造成任何影响。
5、代理模式 Spring 中经典的 AOP ,就是使用动态代理实现的,分 JDK CGlib 动态代理。
6、适配器模式 Spring 中的 AOP AdvisorAdapter 类,它有三个实现:
MethodBeforAdviceAdapter AfterReturnningAdviceAdapter ThrowsAdviceAdapter Spring
会根据不同的 AOP 配置来使用对应的 Advice ,与策略模式不同的是,一个方法可以同时拥有多
个 Advice。 Spring 存在很多以 Adapter 结尾的,大多数都是适配器模式。
7、观察者模式 Spring 中的 Event Listener spring 事件: ApplicationEvent ,该抽象类继
承了 EventObject 类, JDK 建议所有的事件都应该继承自 EventObject spring 事件监听器:
ApplicationListener ,该接口继承了 EventListener 接口, JDK 建议所有的事件监听器都应该
继承 EventListener
8、模板模式 Spring 中的 org.springframework.jdbc.core.JdbcTemplate 就是非常经典的模板模
式的应用,里面的 execute 方法,把整个算法步骤都定义好了。

Spring是怎么解决循环依赖的?

       一句话就是spring是通过三级缓存来解决循环依赖的,所以如果有人问spring的三级缓存是干什么的,也是一样的,是解决循环依赖问题的。具体来说,就是A依赖B,B依赖C,C又依赖了A,产生了循环。spring在实例化Bean的过程中,当发现有一个属性是对象,就会尝试去获取这个对象的bean,递归调用又调用回来了,发现自身还在创建中,那么说明发生了循环依赖。解决流程如下:

        1、A先初始化第一步提前把自己暴露出来,(通过一个对象工厂的方式存在三级缓存中),

当发现依赖对象B时,就尝试获取B的bean;

         2、B没有创建,走创建流程,发现自己依赖的C也没有创建;

         3、C走创建流程,发现依赖A,此时A在三级缓存中,通过 ObjectFactory#getObject() 方法来拿到 A 对象,此时C顺利完成初始化,并将自己添加到一级缓存中;

         4、B拿到了C的bean,也完成了初始化,将自己添加到一级缓存中;

         5、A又拿到了B的bean,完成了初始化,将自己添加到一级缓存中;

Spring事务传播级别

        Spring 事务定义了 7 种传播机制:

        1. PROPAGATION_REQUIRED:默认的 Spring 事务传播级别,若当前存在事务,则加入该事务,若不存在事务,则新建一个事务。

        2. PAOPAGATION_REQUIRE_NEW:若当前没有事务,则新建一个事务。若当前存在事务,则新建一个事务,新老事务相互独立。外部事务抛出异常回滚不会影响内部事务的正常提交。

        3. PROPAGATION_NESTED:如果当前存在事务,则嵌套在当前事务中执行。如果当前没有事务,则新建一个事务,类似于 REQUIRE_NEW

        4. PROPAGATION_SUPPORTS:支持当前事务,若当前不存在事务,以非事务的方式执行。

        5. PROPAGATION_NOT_SUPPORTED:以非事务的方式执行,若当前存在事务,则把当前事务挂起。

        6. PROPAGATION_MANDATORY:强制事务执行,若当前不存在事务,则抛出异常.

        7. PROPAGATION_NEVER:以非事务的方式执行,如果当前存在事务,则抛出异常。

       

       

这篇关于面试集中营—Spring篇的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/964961

相关文章

Java实现检查多个时间段是否有重合

《Java实现检查多个时间段是否有重合》这篇文章主要为大家详细介绍了如何使用Java实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作

Java中String字符串使用避坑指南

《Java中String字符串使用避坑指南》Java中的String字符串是我们日常编程中用得最多的类之一,看似简单的String使用,却隐藏着不少“坑”,如果不注意,可能会导致性能问题、意外的错误容... 目录8个避坑点如下:1. 字符串的不可变性:每次修改都创建新对象2. 使用 == 比较字符串,陷阱满

Java判断多个时间段是否重合的方法小结

《Java判断多个时间段是否重合的方法小结》这篇文章主要为大家详细介绍了Java中判断多个时间段是否重合的方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录判断多个时间段是否有间隔判断时间段集合是否与某时间段重合判断多个时间段是否有间隔实体类内容public class D

IDEA编译报错“java: 常量字符串过长”的原因及解决方法

《IDEA编译报错“java:常量字符串过长”的原因及解决方法》今天在开发过程中,由于尝试将一个文件的Base64字符串设置为常量,结果导致IDEA编译的时候出现了如下报错java:常量字符串过长,... 目录一、问题描述二、问题原因2.1 理论角度2.2 源码角度三、解决方案解决方案①:StringBui

Java覆盖第三方jar包中的某一个类的实现方法

《Java覆盖第三方jar包中的某一个类的实现方法》在我们日常的开发中,经常需要使用第三方的jar包,有时候我们会发现第三方的jar包中的某一个类有问题,或者我们需要定制化修改其中的逻辑,那么应该如何... 目录一、需求描述二、示例描述三、操作步骤四、验证结果五、实现原理一、需求描述需求描述如下:需要在

Java中ArrayList和LinkedList有什么区别举例详解

《Java中ArrayList和LinkedList有什么区别举例详解》:本文主要介绍Java中ArrayList和LinkedList区别的相关资料,包括数据结构特性、核心操作性能、内存与GC影... 目录一、底层数据结构二、核心操作性能对比三、内存与 GC 影响四、扩容机制五、线程安全与并发方案六、工程

JavaScript中的reduce方法执行过程、使用场景及进阶用法

《JavaScript中的reduce方法执行过程、使用场景及进阶用法》:本文主要介绍JavaScript中的reduce方法执行过程、使用场景及进阶用法的相关资料,reduce是JavaScri... 目录1. 什么是reduce2. reduce语法2.1 语法2.2 参数说明3. reduce执行过程

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

Java调用DeepSeek API的最佳实践及详细代码示例

《Java调用DeepSeekAPI的最佳实践及详细代码示例》:本文主要介绍如何使用Java调用DeepSeekAPI,包括获取API密钥、添加HTTP客户端依赖、创建HTTP请求、处理响应、... 目录1. 获取API密钥2. 添加HTTP客户端依赖3. 创建HTTP请求4. 处理响应5. 错误处理6.

Spring AI集成DeepSeek的详细步骤

《SpringAI集成DeepSeek的详细步骤》DeepSeek作为一款卓越的国产AI模型,越来越多的公司考虑在自己的应用中集成,对于Java应用来说,我们可以借助SpringAI集成DeepSe... 目录DeepSeek 介绍Spring AI 是什么?1、环境准备2、构建项目2.1、pom依赖2.2