当前位置: 首页 > news >正文

【Java Spring基本问题】记录面试题宝典中自己不熟悉的Spring问题

文章目录

  • Spring Bean定义装配
  • Spring Bean生命周期
  • Spring Bean容器
  • Spring 循环依赖
  • Spring 事务
  • @Autowired和@Resource

Spring Bean定义装配

参考文章
1. 定义Spring Bean的三种方式
XML文件定义Spring Bean

JavaConfig定义Spring Bean

@Component注解定义SpringBean

2. 装配Spring Bean的四种方式
手动装配 + XML文件

自动装配 + XML文件

手动装配 + JavaConfig文件

自动装配 + 注解

Spring Bean生命周期

参考文章:Bean的生命周期(不要背了记思想)
参考文章:Bean流程非常详细
Bean注册
调用各种BeanDefinitionReader读取各种配置来源信息,并将其转化为BeanDefintion的过程。

Bean实例化
调用Spring Bean的构造器实例化

Bean属性注入
调用postProcessPropertyValues方法,对Spring Bean属性注入
调用一系列Aware接口的实现类,获取Bean的属性(BeanName、BeanFactory等等)

Bean初始化调用的init-method属性指定的初始化方法
调用初始化前方法postProcessBeforeInitialization
调用InitializingBean.afterPropertiesSet属性设置后方法
调用初始化后方法postProcessAfterInitialization

Bean销毁
调用DiposibleBean.destory()

    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {// Instantiate the bean. 实例化beanBeanWrapper instanceWrapper = null;.....if (instanceWrapper == null) {instanceWrapper = createBeanInstance(beanName, mbd, args);}.....boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&isSingletonCurrentlyInCreation(beanName));if (earlySingletonExposure) {if (logger.isDebugEnabled()) {logger.debug("Eagerly caching bean '" + beanName +"' to allow for resolving potential circular references");}//添加到三级缓存中addSingletonFactory(beanName, new ObjectFactory<Object>() {@Overridepublic Object getObject() throws BeansException {return getEarlyBeanReference(beanName, mbd, bean);}});}// Initialize the bean instance.Object exposedObject = bean;try {// 填充属性populateBean(beanName, mbd, instanceWrapper);if (exposedObject != null) {// 初始化BeanexposedObject = initializeBean(beanName, exposedObject, mbd);}}......return exposedObject;}

Spring Bean容器

Spring主要提供了两种类型的容器:BeanFactory和ApplicationContext

1. BeanFactory
使用示例

XmlBeanFactory factory = new XmlBeanFactory (new ClassPathResource("beans.xml")); 
HelloWorld obj = (HelloWorld) factory.getBean("helloWorld");  

2. ApplicationContext
使用示例

ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml"); 
HelloWorld obj = (HelloWorld) context.getBean("helloWorld"); 

3. 两者区别

1. ApplicationContext,继承于BeanFactory,是相对比较高级的容器实现。
2. BeanFactory在启动的时候不会去实例化Bean,ApplicationContext在启动的时候就把所有的Bean全部实例化了

Spring 循环依赖

1. Spring循环依赖的三种情况
构造器的循环依赖:无法处理

非单例Bean循环依赖:无法处理

单例Bean循环依赖:使用三级缓存处理

2. 单例Bean循环依赖的解决
使用三级缓存

// 完成初始化的单例Bean
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);// 完成实例化但是尚未填充属性和初始化的单例Bean
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);// 完成实例化但是尚未填充属性和初始化的单例Bean,并在这里发生AOP后置处理
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

三级缓存解决循环依赖

  1. Spring 创建 bean 主要分为两个步骤,创建原始 bean 对象,接着去填充对象属性和初始化
  2. 每次创建 bean 之前,我们都会从缓存中查下有没有该 bean,因为是单例,只能有一个
  3. 当我们创建 beanA 的原始对象后,并把它放到三级缓存中,接下来就该填充对象属性了,这时候发现依赖了 beanB,接着就又去创建 beanB,同样的流程,创建完 beanB 填充属性时又发现它依赖了 beanA,又是同样的流程,不同的是,这时候可以在三级缓存中查到刚放进去的原始对象 beanA,所以不需要继续创建,用它注入 beanB,完成 beanB 的创建
  4. 既然 beanB 创建好了,所以 beanA 就可以完成填充属性的步骤了,接着执行剩下的逻辑,闭环完成

为什么需要三级缓存呢,二级他也够了呀
三级缓存就是为了后置处理,也就是说你不需要后置处理的话,那就不需要三级缓存,直接二级缓存就可以解决循环依赖。

那为什么二级缓存中不可以进行后置处理
假设我们现在是二级缓存架构,创建 A 的时候,我们不知道有没有循环依赖,所以放入二级缓存提前暴露,接着创建 B,也是放入二级缓存,这时候发现又循环依赖了 A,就去二级缓存找,是有,但是如果此时还有 AOP 代理呢,我们要的是代理对象可不是原始对象,这怎么办,只能改逻辑,在第一步的时候,不管3721,所有 Bean 统统去完成 AOP 代理,如果是这样的话,就不需要三级缓存了,但是这样不仅没有必要,而且违背了 Spring 在结合 AOP 跟 Bean 的生命周期的设计。

3. 无法解决循环依赖的场景
1. 构造器的循环依赖
将已经实例化但未完成属性填充的Bean放在三级缓存中,可以解决循环依赖的问题,但是如果是构造器的循环依赖,那么Bean连第一步的实例化都无法完成,即构造器无法执行。

2. 非单例Bean的循环依赖
因为 Spring 容器不进行缓存 prototype 作用域的 bean ,因此无法提前暴露一个创建中的bean 。

Spring 事务

1. 声明式事务和编程式事务
声明式事务就是通过注解即配置的方式进行事务的管理
编程式事务就是自己在业务逻辑种编写代码来管理事务

2. 7种事务传播行为
参考文章:事务传播行为

@Transactional(propagation = Propagation.REQUIRES_NEW)

在这里插入图片描述

@Autowired和@Resource

1. @Autowired和@Qualifier

public class Pepole {private String name;
//1. 通过名字装配@Autowired@Qualifier("books1")private Books books;
//2. 通过类型装配@Autowiredprivate Hobbies hobbies;
}

在这里插入图片描述
2. @Resource

// @Resource指定按type自动装配@Resource(type = Books.class)private Books books;// @Resource指定按name自动装配@Resource(name = books)private Books books;

在这里插入图片描述

相关文章:

【Java Spring基本问题】记录面试题宝典中自己不熟悉的Spring问题

文章目录Spring Bean定义装配Spring Bean生命周期Spring Bean容器Spring 循环依赖Spring 事务Autowired和ResourceSpring Bean定义装配 参考文章 1. 定义Spring Bean的三种方式 XML文件定义Spring Bean JavaConfig定义Spring Bean Component注解定义SpringBean 2. 装配Spri…...

I2C协议简介 Verilog实现

I2C协议 IIC 协议是三种最常用的串行通信协议&#xff08;I2C&#xff0c;SPI&#xff0c;UART&#xff09;之一&#xff0c;接口包含 SDA&#xff08;串行数据线&#xff09;和 SCL&#xff08;串行时钟线&#xff09;&#xff0c;均为双向端口。I2C 仅使用两根信号线&#xf…...

服务器被DDoS攻击,怎么破?

文章目录前言网站受到DDoS的症状判断是否被攻击查看网络带宽占用查看网络连接TCP连接攻击SYN洪水攻击防御措施TCP/IP内核参数优化iptables 防火墙预防防止同步包洪水&#xff08;Sync Flood&#xff09;Ping洪水攻击&#xff08;Ping of Death&#xff09;控制单个IP的最大并发…...

实现完全二叉树

文章目录1、树概念及结构2、孩子兄弟表示法3、二叉树3.1、二叉树的概念3.2、特殊的二叉树3.3、二叉树的存储4、堆的性质5、数组结构实现完全二叉树1、结构体的定义2、初始化堆3、销毁堆4、交换函数5、向上调整函数6、插入数据7、向下调整函数8、删除堆顶数据函数9、判断是否空堆…...

【独家】华为OD机试 - 矩阵最值(C 语言解题)

最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为od机试,独家整理 已参加机试人员的实战技巧本期题目:矩阵最值 题目 给定一个仅包…...

C++模板(进阶)

文章目录非类型模板参数类模板的特化类模板的概念函数模板特化类模板的特化全特化偏特化参数的进一步限制模板的分离编译模板的优缺点非类型模板参数 模板参数分类型形参与非类型形参. 类型形参: 出现在模板参数列表中,跟在class,typename之类的参数类型名称. 非类型形参: 就是…...

【数据分析之道(二)】列表

文章目录专栏导读1、列表介绍2、访问列表中的值3、列表增加和修改4、删除元素5、列表函数6、列表方法专栏导读 ✍ 作者简介&#xff1a;i阿极&#xff0c;CSDN Python领域新星创作者&#xff0c;专注于分享python领域知识。 ✍ 本文录入于《数据分析之道》&#xff0c;本专栏针…...

架构师必须要掌握的大小端问题

一、什么是大端和小端 所谓的大端模式,就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。 所谓的小端模式,就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。 简单来说:大端——高尾端,小端——低尾端 举个例子,比如数字 0x12 34 56 78…...

2023年ACM竞赛班 2023.3.20题解

目录 瞎编乱造第一题 瞎编乱造第二题 瞎编乱造第三题 瞎编乱造第四题 瞎编乱造第五题 不是很想编了但还是得编的第六题 不是很想编了但还是得编的第七题 还差三道题就编完了的第八题 还差两道题就编完了的第九题 太好啦终于编完了 为啥一周六天早八阿 瞎编乱造第一题…...

什么是语法糖?Java中有哪些语法糖?

本文从 Java 编译原理角度&#xff0c;深入字节码及 class 文件&#xff0c;抽丝剥茧&#xff0c;了解 Java 中的语法糖原理及用法&#xff0c;帮助大家在学会如何使用 Java 语法糖的同时&#xff0c;了解这些语法糖背后的原理1 语法糖语法糖&#xff08;Syntactic Sugar&#…...

STM32学习(五)

GPIO General Purpose Input Output&#xff0c;通用输入输出端口&#xff0c;简称GPIO。 作用&#xff1a; 采集外部器件的信息&#xff08;输入&#xff09;控制外部器件的工作&#xff08;输出&#xff09; GPIO特点 1&#xff0c;不同型号&#xff0c;IO口数量可能不一样…...

STM32的CAN总线调试经验分享

相关文章 CAN总线简易入门教程 CAN总线显性电平和隐性电平详解 STM32的CAN总线调试经验分享 文章目录相关文章背景CAN总线CAN控制器CAN收发器调试过程硬件排查CAN分析仪芯片CAN控制器调试总结背景 最近负责的一个项目用的主控芯片是STM32F407IGT6&#xff0c;需要和几个电机控…...

深度剖析自定义类型(结构体、枚举、联合)——“C”

各位CSDN的uu们你们好呀&#xff0c;今天&#xff0c;小雅兰的内容是心心念念的结构体啦&#xff0c;其实在此之前&#xff0c;我也写过结构体的知识点&#xff0c;只是并没有很深入&#xff0c;那么&#xff0c;今天我会仔细来学习自定义类型的知识点&#xff0c;下面&#xf…...

《水经注地图服务》发布的全球影像数据在水经微图中调用

&#xff08;本文首发于“水经注GIS”公号&#xff0c;订阅“水经注GIS”公号&#xff0c;为你分享更多GIS技术 &#xff09;1、引言古人云&#xff1a;“工欲善其事&#xff0c;必先利其器。”意思是说&#xff1a;工匠想要使他的工作做好&#xff0c;一定要先让工具锋利&…...

MyBatis --- 缓存、逆向工程、分页插件

一、MyBatis的缓存 1.1、MyBatis的一级缓存 一级缓存是SqlSession级别的&#xff0c;通过同一个SqlSession查询的数据会被缓存&#xff0c;下次查询相同的数据&#xff0c;就会从缓存中直接获取&#xff0c;不会从数据库重新访问 使一级缓存失效的四种情况&#xff1a; 1、…...

vue3自定义svg图标组件

可参考&#xff1a; 未来必热&#xff1a;SVG Sprites技术介绍 懒人神器&#xff1a;svg-sprite-loader实现自己的Icon组件 在Vue3项目中使用svg-sprite-loader 前置知识 在页面中&#xff0c;虽然可以通过如下的方式使用img标签&#xff0c;来引入svg图标。但是&#xff0c;…...

智能火焰与烟雾检测系统(Python+YOLOv5深度学习模型+清新界面)

摘要&#xff1a;智能火焰与烟雾检测系统用于智能日常火灾检测报警&#xff0c;利用摄像头画面实时识别火焰与烟雾&#xff0c;另外支持图片、视频火焰检测并进行结果可视化。本文详细介绍基于智能火焰与烟雾检测系统&#xff0c;在介绍算法原理的同时&#xff0c;给出Python的…...

Java实习生------JUC并发编程(多线程)10道面试题打卡⭐⭐⭐

目录 并行和并发有什么区别&#xff1f; 线程和进程有什么区别&#xff1f; 创建线程有哪几种方式&#xff1f; runnable和callable有什么区别&#xff1f; 线程的状态及转换&#xff1f; sleep()和wait()的区别&#xff1f; run()和start()有什么区别&#xff1f; 在…...

ChatGPT和百度文心一言写用例,谁更强?

文心一言发布的第一时间&#xff0c;就排队申请了邀请码&#xff0c;昨晚看了下&#xff0c;邀请码已经到手&#xff0c;索性就拿一个例子试了一下&#xff0c;看看哪个能够真正意义上的提高生产力&#xff0c;最简单的录制了个GIF动画如下&#xff1a;问题&#xff1a;你是一个…...

设计模式总结

设计模式的六大原则 开放-封闭原则(OCP) (总原则) Open-Close Principle&#xff1a;该对扩展开放&#xff0c;对修改关闭。 目的就是保证程序的扩展性好&#xff0c;易于维护和升级。 开放-封闭原则是面向对象设计的核心所在, 开闭原则是Java世界里最基础的设计原则。 开闭…...

Power BI 网页数据抓取实战:以新浪外汇为例,教你5分钟搞定动态表格导入与清洗

Power BI 网页数据抓取实战&#xff1a;新浪外汇动态表格导入与清洗全流程解析 外汇市场瞬息万变&#xff0c;作为业务分析师&#xff0c;每天手动记录汇率数据既耗时又容易出错。今天我们就以新浪财经外汇数据为例&#xff0c;手把手教你用Power BI实现5分钟自动化抓取清洗的完…...

忍者像素绘卷入门必看:Z-Image-Turbo模型结构精简与推理速度提升原理

忍者像素绘卷入门必看&#xff1a;Z-Image-Turbo模型结构精简与推理速度提升原理 1. 项目概述 忍者像素绘卷是一款基于Z-Image-Turbo深度优化的图像生成工作站&#xff0c;专为16-Bit复古游戏美学风格设计。它采用明亮的"云端"视觉设计&#xff0c;为用户提供清爽且…...

别再手动点啦!用Android无障碍服务+讯飞语音,5分钟实现App语音操控(保姆级教程)

用Android无障碍服务打造语音操控神器&#xff1a;5分钟实现"可见即可说" 你是否厌倦了在手机上反复点击屏幕的操作&#xff1f;想象一下&#xff0c;只需对着手机说出"打开微信"、"点击朋友圈"、"返回主页"&#xff0c;设备就能自动完…...

如何彻底解决文献格式混乱?Zotero格式规范化处理工具的创新方案

如何彻底解决文献格式混乱&#xff1f;Zotero格式规范化处理工具的创新方案 【免费下载链接】zotero-format-metadata Linter for Zotero. A plugin for Zotero to format item metadata. Shortcut to set title rich text; set journal abbreviations, university places, and…...

数据转换的艺术:用DataTransformer优化表单处理

引言 在处理复杂的表单数据时,如何将多个字段的数据有效地转换成一个可存储的字符串是一个常见的问题。在本文中,我们将探讨如何使用Symfony框架中的DataTransformer来解决这个问题,结合一个实际的案例来展示其实现过程。 案例背景 假设我们有一个名为EffectType的自定义…...

深度学习驱动的光谱超分辨率:技术演进与应用前景

1. 光谱超分辨率技术的前世今生 我第一次接触光谱超分辨率技术是在2015年&#xff0c;当时还在用传统的线性插值方法处理遥感图像。记得有次为了获取一片农田的高光谱数据&#xff0c;团队不得不动用昂贵的机载传感器&#xff0c;结果因为天气原因导致数据质量极差。正是这次经…...

掌握TegraRcmGUI:从入门到精通的Switch注入实践指南

掌握TegraRcmGUI&#xff1a;从入门到精通的Switch注入实践指南 【免费下载链接】TegraRcmGUI C GUI for TegraRcmSmash (Fuse Gele exploit for Nintendo Switch) 项目地址: https://gitcode.com/gh_mirrors/te/TegraRcmGUI TegraRcmGUI是一款基于C开发的图形化界面工具…...

深度解析Windows设备指纹伪装技术:EASY-HWID-SPOOFER内核级硬件隐私保护实现

深度解析Windows设备指纹伪装技术&#xff1a;EASY-HWID-SPOOFER内核级硬件隐私保护实现 【免费下载链接】EASY-HWID-SPOOFER 基于内核模式的硬件信息欺骗工具 项目地址: https://gitcode.com/gh_mirrors/ea/EASY-HWID-SPOOFER 在数字化时代&#xff0c;硬件隐私保护已成…...

Phi-3-mini-4k-instruct-gguf多场景:覆盖个人提效、团队协作、客户支持全链路

Phi-3-mini-4k-instruct-gguf多场景&#xff1a;覆盖个人提效、团队协作、客户支持全链路 1. 认识Phi-3-mini-4k-instruct-gguf Phi-3-mini-4k-instruct-gguf是微软Phi-3系列中的轻量级文本生成模型GGUF版本。这个开箱即用的工具特别适合处理日常工作中的文本任务&#xff0c…...

5分钟搞定AutoHotkey脚本转EXE:Ahk2Exe终极编译指南

5分钟搞定AutoHotkey脚本转EXE&#xff1a;Ahk2Exe终极编译指南 【免费下载链接】Ahk2Exe Official AutoHotkey script compiler - written itself in AutoHotkey 项目地址: https://gitcode.com/gh_mirrors/ah/Ahk2Exe 想要将AutoHotkey脚本快速转换为独立的可执行文件…...