【面试专题】Spring篇②

news2024/11/26 10:47:28

📃个人主页:个人主页

🔥系列专栏: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.coloradmin.cn/o/993200.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Ubuntu编译运行socket.io

本篇文章记录一下自己在ubuntu上编译运行socket.io的过程&#xff0c;客户端选用的是socket.io的c的库&#xff0c;编译起来倒不难&#xff0c;但是说到运行的话&#xff0c;对我来说确实是花了点功夫。毕竟程序要能运行起来才能更方便地去熟悉代码&#xff0c;因此今天我就记录…

MySQL——日志

日志的作用 1.用来排错 2.用来做数据分析 3.了解程序的运行情况&#xff0c;是否健康--》了解MySQL的性能&#xff0c;运行情况 分类 mysql很多有类型的日志&#xff0c;按照组件划分的话&#xff0c;可以分为 服务层日志 和 存储引擎层日志 &#xff1a; - 服务层…

数据治理-数据建模和设计

是什么&#xff1f; 数据建模是发现、分析和确定数据需求的过程&#xff0c;用一种称为数据模型的精确形式表示和传递这些数据需求。数据建模是数据管理的一个重要组成部分。建模过程中要求组织发现并记录数据组合的方式。 数据可以采用多种不同的模式来表示&#xff0c;其中最…

【广州华锐互动】电厂三维数字孪生大屏的功能和优势

在工业互联网的背景下&#xff0c;电厂三维数字孪生大屏系统正在逐渐成为电力行业的重要技术。通过创建电厂的虚拟模型&#xff0c;这个数字孪生系统可以实现对实际电厂的实时监控&#xff0c;预测维护需求&#xff0c;优化运营效率&#xff0c;甚至在某些情况下&#xff0c;能…

CrossEntropyLoss() 和 nn.BCEWithLogitsLoss() 举例说明区别

CrossEntropyLoss() 通常用于多分类任务&#xff0c;它接受一个包含类别标签的张量作为目标值&#xff0c;并且假设每个样本只属于一个类别。在多分类任务中&#xff0c;模型的最后一层输出是一个概率分布&#xff0c;表示每个类别的概率。CrossEntropyLoss() 计算模型输出与目…

微信“刷掌支付”上线,扫手就可以付款!你知道怎么开通了吗?

不用扫码&#xff01;不用刷卡&#xff01;隔空感应&#xff01; 刷掌就能支付 没错&#xff01; 新科技来咯~ 刷 掌 早在今年5月&#xff0c;微信刷掌支付正式面世&#xff0c;目前已应用于交通、健身、校园、零售、餐饮、办公、共享充电等多个场景&#xff0c;如北京地铁…

vue3+ts项目打包后的本地访问

注意&#xff1a;打包之后不可直接点击html访问&#xff0c;需要给项目安装本地服务&#xff01; 1、安装servenpm i -g serve 2、打包项目npm run build 生成dist文件夹 3、本地访问serve dist 运行service dist之后的控制台 可复制下方的地址运行打包后的项目&#xff0c;运行…

Spring系列文章:Spring中的设计模式

一、简单⼯⼚模式 BeanFactory的getBean()⽅法&#xff0c;通过唯⼀标识来获取Bean对象。是典型的简单⼯⼚模式&#xff08;静态⼯⼚模 式&#xff09;&#xff1b; 二、⼯⼚⽅法模式 FactoryBean是典型的⼯⼚⽅法模式。在配置⽂件中通过factory-method属性来指定⼯⼚⽅法&a…

英语单词(二)

1.int:整形 2.char:字符型 3.scanner:接受输入,扫描器 4.integer:整数,整形 5.type:类型 6.string:字符串类型 7.double:双精度浮点型

OpenRoads地形模型添加(增补)地形点

创建三维点&#xff0c;将创建的点对象添加到现有地形模型。 在ORD建模工作流&#xff1a; 地形、分析、点、分析点&#xff0c;在需要添加点的位置读出地模的高程&#xff08;图1&#xff09;&#xff1b; 图1 几何、平面、点添加高程点&#xff0c;特征设为地形随机点、高…

双线性插值以及计算

参考视频&#xff1a;图像处理-双线性插值_哔哩哔哩_bilibili 双线性插值 双线性插值是一种常用的图像处理和计算机图形学技术&#xff0c;用于在离散像素网格上平滑地估算介于两个相邻像素之间的数值。这种插值方法通常用于图像放大、旋转和变换等操作&#xff0c;以改善图像…

操作系统 第二章 进程管理:进程与线程、处理机调度

目录 1.进程与线程 1.1进程的概念、组成、特征 1.1.1概念 1.1.2组成 进程控制块&#xff08;PCB&#xff09; 程序段 数据段 1.1.3特征 1.2进程的状态与转换 1.2.1进程的五种状态 1.2.2进程的状态转换 1.3进程控制 1.3.1如何实现原语的“原子性” 1.3.2进程的创建…

intellij debug模式提示 : Method breakpoints may dramatically slow down debugging

最近在搞一个搭建一个项目 , 项目搭建完之后发现启动不了 , 一直都是正在加载中 并且提示Method breakpoints may dramatically slow down debugging&#xff0c;百度之后才知道是打了方法断点的原因 , 之前不小心打了一个断点 解决办法 : 点击如下图所示的按钮 然后把有断点…

15:00面试,15:06就出来了,问的问题有点变态。。。

从小厂出来&#xff0c;没想到在另一家公司又寄了。 到这家公司开始上班&#xff0c;加班是每天必不可少的&#xff0c;看在钱给的比较多的份上&#xff0c;就不太计较了。没想到8月一纸通知&#xff0c;所有人不准加班&#xff0c;加班费不仅没有了&#xff0c;薪资还要降40%,…

matlab之cell数组的详细用法

一、cell数组是什么&#xff1f; 在MATLAB中&#xff0c;Cell数组是一种特殊的数据结构&#xff0c;它可以存储不同类型的数据&#xff0c;包括数字、字符串、数组、结构体等。Cell数组是一种灵活的数据容器&#xff0c;可以方便地存储和处理不同类型的数据。 二、怎么使用ce…

算法通关村第十八关:白银挑战-回溯热门问题

白银挑战-回溯热门问题 回溯主要解决一些暴力枚举也搞不定的问题zh&#xff0c;例如组合、分割、子集、排列、棋盘等。 1. 组合总和问题 LeetCode39 https://leetcode.cn/problems/combination-sum/ 思路分析 如果不考虑重复&#xff0c;跟题目 LeetCode 113 类似 考虑重复…

Autowired members must be defined in valid Spring bean (@Component|@Service|…)

报错如下&#xff1a; 自动注入对象必须定义在有效的spring bean内&#xff0c;也就是说只有本身作为bean的类才能注入其他对象。 修正方法&#xff1a;在BookTest上加上Component注解

基于STM32F103 实现按键状态机

文章目录 开发板开发环境前言按键消抖按键硬件原理图软件延时实现思路 实验目的代码按键状态按键信息按键相关定义按键底层配置及状态获取 总结 开发板 正点原子STM32F103ZET6战舰 开发环境 stm32cubeMX Clion 前言 在单片机使用按键时&#xff0c;为了消除按键的抖动&…

【随想】每日两题Day.3(实则一题)

题目&#xff1a;59.螺旋矩阵|| 给你一个正整数 n &#xff0c;生成一个包含 1 到 n2 所有元素&#xff0c;且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。 示例 1&#xff1a; 输入&#xff1a;n 3 输出&#xff1a;[[1,2,3],[8,9,4],[7,6,5]]示例 2&#xff1a; …

Python进阶方法-Decorator装饰器

前言 在Python中&#xff0c;decorator&#xff08;装饰器&#xff09;是一种特殊的函数&#xff0c;主要用于修改或增强其他函数的功能。它可以在不修改原函数代码的情况下&#xff0c;通过在原函数的定义之前使用语法糖来对其进行修饰。 Decorator装饰器的作用 Decorator的…