【面试专题】Spring篇②

📃个人主页:个人主页

🔥系列专栏:Java面试专题

目录

1.spring-bean的循环依赖

2.springMVC执行流程

3.Springboot自动配置原理

4.Spring框架常见的注解(Spring,SpringMVC,SpringBoot)


 

1.spring-bean的循环依赖

循环依赖:循环依赖其实就是循环引用 , 也就是两个或两个以上的 bean 互相持
有对方 , 最终形成闭环。比如 A 依赖于 B,B 依赖于 A
循环依赖在 spring 中是允许存在, spring 框架依据三级缓存已经解决了大部
分的循环依赖
一级缓存:单例池,缓存已经经历了完整的生命周期,已经初始化完成的
bean 对象
二级缓存:缓存早期的 bean 对象(生命周期还没走完)
三级缓存:缓存的是 ObjectFactory ,表示对象工厂,用来创建某个对象的

那具体解决流程清楚吗?
  • 第一,先实例A对象,同时会创建ObjectFactory对象存入三级缓存 singletonFactories
  • 第二,A在初始化的时候需要B对象,这个走B的创建的逻辑
  • 第三,B实例化完成,也会创建ObjectFactory对象存入三级缓存 singletonFactories
  • 第四,B需要注入A,通过三级缓存中获取ObjectFactory来生成一个A的对象,同时存入二级缓存,这个是有两种情况,一个是可能是A的普通对象,另外一个是A的代理对象,都可以让ObjectFactory来生产对应的对象,这也是三级缓存的关键
  • 第五,B通过从通过二级缓存earlySingletonObjects 获得到A的对象后可以正常注入,B创建成功,存入一级缓存singletonObjects
  • 第六,回到A对象初始化,因为B对象已经创建完成,则可以直接注入BA创建成功存入一次缓存singletonObjects
  • 第七,二级缓存中的临时对象A清除

构造方法出现了循环依赖怎么解决?
由于 bean 的生命周期中构造函数是第一个执行的, spring 框架并不能解决构造函数的的依赖注入,可以使用@Lazy 懒加载,什么时候需要对象再进行 bean对象的创建。

2.springMVC执行流程

1 、用户发送出请求到前端控制器 DispatcherServlet ,这是一个调度中心
2 DispatcherServlet 收到请求调用 HandlerMapping (处理器映射器)。
3 HandlerMapping 找到具体的处理器 ( 可查找 xml 配置或注解配置 ) ,生成处理器对象及处理器拦截器( 如果有 ) ,再一起返回给 DispatcherServlet
4 DispatcherServlet 调用 HandlerAdapter (处理器适配器)。
5 HandlerAdapter 经过适配调用具体的处理器( Handler/Controller )。
6 Controller 执行完成返回 ModelAndView 对象。
7 HandlerAdapter Controller 执行结果 ModelAndView 返回给DispatcherServlet。
8 DispatcherServlet ModelAndView 传给 ViewReslover (视图解析器)。
9 ViewReslover 解析后返回具体 View (视图)。
10 DispatcherServlet 根据 View 进行渲染视图(即将模型数据填充至视图中)。
11 DispatcherServlet 响应用户。
当然现在的开发,基本都是前后端分离的开发的,并没有视图这些,一般都
handler 中使用 Response 直接结果返回

①用户发送请求到前端控制器DispatcherServlet

DispatcherServlet收到请求调用HandlerMapping(处理器映射器)。

HandlerMapping找到具体的处理器,生成处理器对象及处理器拦截器(如果有),再一起返回给DispatcherServlet

④DispatcherServlet调用HandlerAdapter(处理器适配器)。

⑤HandlerAdapter经过适配调用具体的处理器(Handler/Controller)。

⑥方法上添加@ResponseBody

⑦通过HttpMessageConverter来返回结果转换为JSON并响应

3.Springboot自动配置原理

Spring Boot 项目中的引导类上有一个注解 @SpringBootApplication ,这个
注解是对三个注解进行了封装,分别是:
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
其中 @EnableAutoConfiguration 是实现自动化配置的核心注解。 该注解通过 @Import 注解导入对应的配置选择器。关键的是内部就是读取了该项目和该项目引用的Jar 包的的 classpath 路径下 META- INF/spring.factories 文件中的所配置的类的全类名。
在这些配置类中所定义的 Bean 会根据条件注解所 指定的条件来决定 是否需要
将其导入到 Spring 容器中。
一般条件判断会有像 @ConditionalOnClass 这样的注解,判断是否有对应的class文件,如果有则加载该类,把这个配置类的所有的 Bean 放入 spring 容器中使用。

什么是自动装配

Spring Boot 相比于 Spring 的一个很大进步点在于不用再手动配置一系列配置文件,Spring Boot 提供了配置应用程序和框架所需要的基本配置,这就是自动配置。本节会先通过源码介绍自动装配,并在本节最后给出总结。

Spring Boot 启动器

Spring Boot 中的一系列启动器是自动装配的最佳实践。比如当引入了一个 spring-boot-starter-web 依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>

Spring Boot 框架就会自动引入 web 环境所有的依赖,并且自动配置,Spring Boot 将所有的功能场景,都变成一个个启动器,想要用什么功能,只需要找到对应的启动器就可以了。

Spring Boot 的所有启动器可以在官网 https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-starter 中找到,下图是所有启动器中的一小部分: 

自动装配原理分析

Spring Boot 的主程序也可以称为启动类,这是开启 Spring Boot 项目的入口。查看源代码推荐使用 IDEA。

package com.lanqiaoyun.springbootdemo;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class SpringbootdemoApplication {public static void main(String[] args) {SpringApplication.run(SpringbootdemoApplication.class, args);}
}

@SpringBootApplication 注解标注这个类是一个 SpringBoot 的启动类,这个注解也是自动装配的核心。

@TargetRetentionDocumentedInherited 四个注解是标准的元注解,核心在于@SpringBootConfiguration@EnableAutoConfiguration这两个注解。

通过继续进入注解内部,可以将@SpringBootConfiguration@EnableAutoConfiguration这两个注解的结构表示出来:

  • @SpringBootConfiguration : Spring Boot 的配置
    • @Configuration : Spring 配置类
      • @Component : Spring 的组件
  • @EnableAutoConfiguration : 自动配置
    • @AutoConfigurationPackage : 自动配置包
      • @Import({Registrar.class}) : 自动配置包注册
      • @Import({AutoConfigurationImportSelector.class}) : 导入选择器

@SpringBootConfiguration 声明了这个类为 SpringBoot 的组件,@EnableAutoConfiguration 是自动配置的核心,其中@AutoConfigurationPackage 对配置包进行了注册,AutoConfigurationImportSelector 类来进行自动装配。

继续来看看 AutoConfigurationImportSelector 这个类。

  1. 引入环境。
  2. 引入 bean 加载器。
  3. 引入资源加载器。
  4. 配置导入。

继续向下看,selectImports 中 的getAutoConfigurationEntry 方法第 86 行代码将所有的配置通过 getCandidateConfigurations 方法放进一个 List 集合中。

继续进入 getCandidateConfigurations 方法,这个配置获取的路径是 EnableAutoConfiguration.class,也就是@SpringBootApplication 所依赖的两个重要注解的其中一个。这段代码最终想表达的意思是将启动类下的所有配置都导入。 

进入 LoadFactoryNames 或者就从 Assert.notEmpty 的信息中,可以发现这些配置来自于 META-INF/spring.factories 中,从 jar 包中可以查看到具体的目录结构。

 在 spring.factories 文件中存在大量 xxxAutoConfiguration,这个文件记录了所有 starter 的自动装配类,就是这些类在容器中导入了场景需要的所有组件;并通过 @Configuration 自动配置。

通过一张图来总结一下自动装配的原理,通过上面对源码的分析,可以看出 SpringBoot 所有的自动配置都在启动类中被扫描和加载。所有的自动配置类都在 spring.properties 中。 

@ConditionalOnClass 这样的注解,判断是否有对应的class文件,如果有则加载该类,把这个配置类的所有的Bean放入spring容器中使用。

自动装配总结起来可以分为以下几步:

  1. Spring Boot 在启动的时候,从类路径下/META-INF/spring.factories 获取指定的值;
  2. 将这些自动配置的类导入容器,自动配置就会生效,进行自动配置!
  3. 以前我们需要自动配置的东西,现在 Spring Boot 帮我们做了
  4. 自动配置的东西都在 spring-boot-autoconfigure.jar 这个包下
  5. 它会把所有需要导入的组件,以类名的方式返回,这些组件就会被添加到容器;
  6. 容器中也会存在非常多的 xxxAutoConfiguration 的类(@Bean),就是这些类给容器中导入了这个场景需要的所有组件;并通过@Configuration 自动配置。
  7. 有了自动配置类,免去了我们手动编写配置文件的步骤。

4.Spring框架常见的注解(Spring,SpringMVC,SpringBoot)

Spring 的常见注解有哪些?
第一类是:声明 bean ,有 @Component @Service @Repository 、 @Controller
第二类是:依赖注入相关的,有 @Autowired @Qualifier @Resourse
第三类是:设置作用域 @Scope
第四类是: spring 配置相关的,比如 @Configuration @ComponentScan 和 @Bean
第五类是:跟 aop 相关做增强的注解 @Aspect @Before @After ,@Around, @Pointcut
SpringMVC常见的注解有哪些?
@RequestMapping :用于映射请求路径;
@RequestBody :注解实现接收 http 请求的 json 数据,将 json 转换为 java 对象;
@RequestParam :指定请求参数的名称;
@PathViriable :从请求路径下中获取请求参数 (/user/{id}) ,传递给方法的形式参数;@ResponseBody :注解实现将 controller 方法返回对象转化为 json对象响应给客户端。@RequestHeader :获取指定的请求头数据,还有像@PostMapping、 @GetMapping 这些。
@RestController:@Controller+@ResponseBody
Springboot常见注解有哪些?
Spring Boot 的核心注解是 @SpringBootApplication , 他由几个注解组成 :
@SpringBootConfiguration : 组合了- @Configuration 注解,实现配置文件的功能;
@EnableAutoConfiguration :打开自动配置的功能,也可以关闭某个自动配置的选项
@ComponentScan Spring 组件扫描

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/126693.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

qsort 函数的使用

一、qsort 函数的形式 1.1使用 qsort 函数包含的库 1.2qsort 函数的参数 qsort&#xff1a;对数组的元素进行排序 1.3参数中的 compar 函数 struct stu {char name[20];//姓名int age;//年龄double grade;//成绩 }; int cmp_name(void* p1, void* p2) {//如果按照姓名排序ret…

开机性能-如何抓取开机systrace

一、理论 1.背景 抓取开机 trace 需要使用 userdebug 版本&#xff0c;而我们测试开机性能问题时都要求使用 user 版本&#xff0c;否则会有性能损耗问题。因此想要在抓取开机性能trace 时&#xff0c;需要在 user 版本上打开 atrace 功能之后才能抓取 trace&#xff0c;默认 …

SpringMVC文件上传、文件下载多文件上传及jrebel的使用与配置

一.文件上传 1.导入依赖 <dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.3.3</version> </dependency> 2.配置文件上传解析器 在spring-mvc.xml文件中添加文件…

蓝牙方案|伦茨科技最新ESL蓝牙电子价签方案

随着电子货架标签市场无线标准的发布&#xff0c;蓝牙技术将协助零售业进行下一阶段的数字化转型&#xff0c;为商店和购物者提供更好的消费体验。电子货架标签提供了精准的自动定价&#xff0c;并增加了对实时促销和产品信息的访问&#xff0c;提供更令人满意且整合的全渠道体…

Mqtt学习笔记--交叉编译移植(1)

简述 Mqtt目前在物联网行业的应用比较多&#xff0c;mqtt属于应用层的一个中间件&#xff0c;这个中间件实现消息的订阅发布机制。网上介绍Mqtt的实现原来的比较多&#xff0c;这里不细介绍。 其实在我们之前的产品中&#xff0c;自己也开发的有类似的中间件&#xff0c;除了具…

uni-app:重置表单数据

效果 代码 <template><form><input type"text" v-model"inputValue" placeholder"请输入信息"/><input type"text" v-model"inputValue1" placeholder"请输入信息"/><input type&quo…

万里路,咫尺间:汽车与芯片的智能之遇

目前阶段&#xff0c;汽车产业有两个最闪耀的关键词&#xff0c;就是智能与低碳。 在践行双碳目标与产业智能化的大背景下&#xff0c;汽车已经成为了能源技术、交通技术、先进制造以及通信、数字化、智能化技术的融合体。汽车的产品形态与产业生态都在发生着前所未有的巨大变革…

2023国赛数学建模B题思路代码 - 多波束测线问题

# 1 赛题 B 题 多波束测线问题 单波束测深是利用声波在水中的传播特性来测量水体深度的技术。声波在均匀介质中作匀 速直线传播&#xff0c; 在不同界面上产生反射&#xff0c; 利用这一原理&#xff0c;从测量船换能器垂直向海底发射声波信 号&#xff0c;并记录从声波发射到…

【sgCreateAPI】自定义小工具:敏捷开发→自动化生成API接口脚本(接口代码生成工具)

<template><div :class"$options.name"><div class"sg-head">接口代码生成工具</div><div class"sg-container"><div class"sg-start "><div style"margin-bottom: 10px;">接口地…

大规模 Spring Cloud 微服务无损上下线探索与实践

文章目录 什么是无损上下线&#xff1f;大规模 Spring Cloud 微服务架构实现无损上下线的挑战无损上下线的实践1. 使用负载均衡器2. 使用数据库迁移工具3. 动态配置管理4. 错误处理和回滚 未来的趋势1. 容器编排2. 服务网格3. 自动化测试和验证 结论 &#x1f389;欢迎来到云原…

wires hark抓包内容解析

1.Frame 22001&#xff1a;这是该数据包的序号&#xff0c;表示wires hark已经捕获并显示了22001个数据包&#xff1b; 2.225 bytes on wire (1800 bits)&#xff1a;该数据的原始大小、以字节和比特显示&#xff1b; 3.225 bytes captured (1800 bits)&#xff1a;wires har…

经管博士科研基础【19】齐次线性方程组

1. 线性方程组 2. 非线性方程组 非线性方程,就是因变量与自变量之间的关系不是线性的关系,这类方程很多,例如平方关系、对数关系、指数关系、三角函数关系等等。求解此类方程往往很难得到精确解,经常需要求近似解问题。相应的求近似解的方法也逐渐得到大家的重视。 3. 线…

【C++ • STL • 力扣】详解string相关OJ

文章目录 1、仅仅翻转字母2、字符串中的第一个唯一字符3、字符串里最后一个单词的长度4、验证一个字符串是否是回文5、字符串相加总结 ヾ(๑╹◡╹)&#xff89;" 人总要为过去的懒惰而付出代价 ヾ(๑╹◡╹)&#xff89;" 1、仅仅翻转字母 力扣链接 代码1展示&…

【 OpenGauss源码学习 —— 列存储(analyze)(四)】

列存储&#xff08;analyze&#xff09; AcquireSampleCStoreRows 函数es_get_attnums_to_analyze 函数CStoreRelGetCUNumByNow 函数CStore::GetLivedRowNumbers 函数InitGetValFunc 函数CStoreGetfstColIdx 函数CStore::GetCUDesc 函数CStore::IsTheWholeCuDeleted 函数CStore…

Android扫码连接WIFI实现

0&#xff0c;目标 APP中实现扫WIFI分享码自动连接WIFI功能 1&#xff0c;前提条件 设备需要有个扫码器&#xff08;摄像头拍照识别也行&#xff09;&#xff0c;APP调用扫码器读取WIFI连接分享码。 2&#xff0c;增加权限 在AndroidManifest.xml中增加权限 <uses-permissi…

机器学习笔记 - 使用具有triplet loss的孪生网络进行图像相似度估计

一、简述 孪生网络是一种网络架构,包含两个或多个相同的子网络,用于为每个输入生成特征向量并进行比较。 孪生网络可以应用于不同的场景,例如检测重复项、发现异常和人脸识别。 此示例使用具有三个相同子网的孪生网络。我们将向模型提供三张图像,其中两张是相似的(锚点和正…

redis持久化、主从和哨兵架构

一、redis持久化 1、RDB快照&#xff08;snapshot&#xff09; redis配置RDB存储模式&#xff0c;修改redis.conf文件如下配置&#xff1a; # 在300s内有100个或者以上的key被修改就会把redis中的数据持久化到dump.rdb文件中 # save 300 100# 配置数据存放目录&#xff08;现…

算法通关村十四关:青铜-堆结构

青铜挑战-堆结构 堆结构&#xff1a;重要的基础数据结构 明确什么类型的题目可以用堆&#xff0c;以及如何用堆来解决 堆的构造和维护过程都非常复杂 1.堆的概念与特征 1.1基本概念 堆&#xff1a;是将一组数据按照 完全二叉树 的存储顺序&#xff0c;将数据存储在一个一…

【前端】在Vue页面中引入其它vue页面 数据传输 相互调用方法等

主页面 home 从页面 headView 需求 在 home.vue 中引用 headView.Vue 方案: home.vue 代码: 只需要在home.vue 想要的地方添加 <headView></headView> <script>//聊天页面 import headView /view/headView.vueexport default {components: {headView},…

CSDN每日一练 |『括号上色』『严查枪火』『数组排序』2023-09-09

CSDN每日一练 |『括号上色』『严查枪火』『数组排序』2023-09-09 一、题目名称:括号上色二、题目名称:严查枪火三、题目名称:数组排序一、题目名称:括号上色 时间限制:1000ms内存限制:256M 题目描述: 小艺酱又得到了一堆括号。 括号是严格匹配的。 现在给括号进行上色。…