【Spring面试】二、BeanFactory与IoC容器的加载
文章目录
- Q1、BeanFactory的作用是什么?
- Q2、BeanDefinition的作用是什么?
- Q3、BeanFactory和ApplicationContext有什么区别?
- Q4、BeanFactory和FactoryBean有什么区别?
- Q5、说下Spring IoC容器的加载过程(※)
- Q6、Spring Ioc有哪些扩展点,在什么时候调用?
Q1、BeanFactory的作用是什么?
答案:
- BeanFactory是Spring中非常核心的一个
顶层接口
(顶层即无父接口) - 它是Bean的工厂,
主要职责就是生产Bean
- 实现了简单
工厂的设计模式
,即通过调用getBean传入标识来生产一个
Bean - 它有非常多的
实现类
,每个工厂都有不同的职责(单一职责功能),最强大的是DefaultListableBeanFactory
,Spring底层就是使用该实现工厂来生产Bean的
Q2、BeanDefinition的作用是什么?
答案:
它主要负责存储Bean的定义信息
,决定Bean的生产方式。如spring.xml:
<bean class="com.llg.User " id="user" scope="singleton" lazy="false" abstract="false" autowire="none" ><property name="username" value="9527">
</bean>
把以上Bean的这些定义信息,拿到并赋值给BeanDefinition(的实现类)的属性,然后交给BeanFactory来生产:
以汽车为例来对比:
Q3、BeanFactory和ApplicationContext有什么区别?
答案:
-
ApplicationContext即Spring的上下文,其实现了BeanFactory接口。
-
FactoryBean的getBean方法用于生产Bean,但ApplicationContext不生产Bean,而是通知FactoryBean来干活儿(即调用)
,它的getBean方法其实是个门面方法,底层在调BeanFactory的getBean方法 -
它们都可以做为Spring容器,因为它们都可以来管理Bean的声明周期
-
ApplicationContext在开发中打交道最多,是因为它做了更多的事情,如自动把我们配置的Bean(如@Component)注册进来、加载环境变量、实现事件监听等
-
ApplicationContext和BeanFactory,
就像4S店和汽车厂的关系
,它虽然不造车,从车厂拿车,但它会做销售、保养、上牌等一系列事儿
Q4、BeanFactory和FactoryBean有什么区别?
答案:
-
BeanFactory是一个工厂,也是一个容器,用来管理和生产Bean的
-
FactoryBean则只是一个Bean,
特殊的Bean
,所以也是由BeanFactory来管理的 -
FactoryBean是一个接口,必须被另一个Bean去实现,此时这个
被寄生的Bean则不再是是它自身,而是FactoryBean接口中getObject方法返回的那个Bean
,getObject方法返回的这个Bean,可以是被寄生的Bean的子类,也可以是和被寄生的Bean的这个类毫无关系的类 -
如果想
获得原来的Bean实例,可加&
-
FactoryBean创建Bean的方式是懒加载的,使用Bean的时候才会调用getObject方法并把对象添加到容器
代码演示:
@Component
public class UserMapper{public UserMapper(){System.out.println("UerMapper对象加载");}public void query(){System.out.println("query");}
}
@Configuration
@ComponentScan //扫不到时自己调整包路径
public class MainConfig{
}
public class Run{public static void main(String[] args){AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);UserMapper userMapper = (USerMapper) context.getBean("userMapper");userMapper.query();}}
此时运行一切正常:
UserMapper再去实现FactoryBean这个接口,此时getBean得到的userMapper对象就是重写的getObject方法返回的对象。
@Component
public class UserMapper implements FactoryBean{public UserMapper(){System.out.println("UerMapper对象加载");}public void query(){System.out.println("query");}@Overridepublic Object getObject() throws Exception{return "code9527"; //直接返回一个不相干的String对象}@Overridepublic Class<?> getObjectType(){return String.class;}
}
此时,getBean得到的userMapper就是一个String对象,那自然会类转换异常:
想获得原Bean,则加&:
UserMapper userMapper = (USerMapper) context.getBean("userMapper");
且此时创建Bean的方式是懒加载的
,使用Bean的时候才会调用getObject方法并把对象添加到容器。修改下getObject:
此时断点,执行完new AnnotationConfigApplication(),即容器创建完成、Bean加载完成,控制台仍未输出"getObject调用===",即并未执行getObject()方法,直到getBean时才输出:
Q5、说下Spring IoC容器的加载过程(※)
图片链接:https://www.processon.com/view/link/5f15341b07912906d9ae8642
答案:
对照上图:
- 实例化一个ApplicationContext对象(此时Bean还只是代码里的简单定义,即
概念态的Bea
n) - 调用Bean工厂的后置处理器完成扫描
- 循环解析扫描出来的类信息,看是否有@Component注解
- 有则实例化一个BeanDefinition对象来存储接续出来的信息
- 把实例化好的beanDefinition对象put到beanDefinitionMap中缓存起来,以便后面实例化bean
(定义态的Bean)
- 再次调用其他bean工厂的后置处理器
- 当然spring还会干很多事情,比如国际化,比如注册BeanPostProcessor
- 实例化Bean则是spring调用finishBeanFactorylnitialization方法来实例化单例的bean,实例化之前spring要做验证,需要遍历所有扫描出来的类,依次判断这个bean是否Lazy,是否prototype,是否abstract等
- 如果验证完成spring在实例化一个bean之前需要推断构造方法,因为spring实例化对象是通过构造方法反射,故而需要知道用哪个构造方法
- 推断完构造方法之后spring调用构造射实例代个对象,注意我这里说的是对象、对象、对象,这个时候对象已经实例化出来了,但是并不是一个完整的bean,最简单的体现是这个时候实例化出来的对象属性是没有注入的,所以不是一个完整的bean
(纯净态的Bean)
- Spring处理合并后的beanDefinition
- 判断是否需要完成属性注入,如果需要,则注入
- 判断Bean的类型,回调Aware接口
- 调用生命周期回调方法
- 如果需要代理则完成代理
- put到单例池,bean创建完成,存到Spring容器中,IoC容器加载完成。(
成熟态的Bean
)
Q6、Spring Ioc有哪些扩展点,在什么时候调用?
问题分析:
扩展点,即Spring Ioc在加载的过程中,其底层会对外提供很多的扩展接口或者一些钩子方法,当我们自己去实现这些接口时,Spring就会在特定的点,帮我们调用钩子方法,从而实现对Spring底层的扩展。
Spring有非常多的扩展接口,重点有:
A1: 执行BeanFactoryPostProcessor的postProcessBeanFactory方法
Spring提供了对BeanFactory进行操作的处理器BeanFactoryProcessor,简单来说就是获取容器BeanFactory,这样就可以在真正初始化bean之前对bean做一些处理操作。bean工厂的bean属性处理容器,说通俗一些就是可以管理我们的bean工厂内所有的beandefinition(未实例化)数据,可以随心所欲的修改属性。
简单来说就是在工厂里所有的bean被加载进来后但是还没初始化前,对所有bean的属性进行修改也可以add属性值。
/*** 作用: 在注册BeanDefinition的可以对beanFactory进行扩展* 调用时机: Ioc加载时注册BeanDefinition的时候会调用* 看接口的参数,看它把啥给你了,比如这里给了BeanFactory对象*/
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {@Overridepublic void postprocessBeanFactory(ConfigurableListableBeanFactory beanFactor) throws BeansException {}
}
A2: BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
/**
* 作用:动态注册BeanDefinition
* 调用时机: Ioc加载时注册BeanDefinition 的时候会调用
*/@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {@Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException (RootBeanDefinition beanDefinition = new RootBeanDefinition(Car.class);registry.registerBeanDefinition("car",beanDefinition);
}
A3: Bean生命周期的回调方法:初始化和销毁
InitializingBean接口
为bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候都会执行该方法。
public interface InitializingBean {void afterPropertiesSet() throws Exception;
}
实现DisposableBean接口
,在这个Bean生命周期结束前调用destory()方法做一些收尾工作
public interface DisposableBean {void destroy() throws Exception;
}
相关文章:
【Spring面试】二、BeanFactory与IoC容器的加载
文章目录 Q1、BeanFactory的作用是什么?Q2、BeanDefinition的作用是什么?Q3、BeanFactory和ApplicationContext有什么区别?Q4、BeanFactory和FactoryBean有什么区别?Q5、说下Spring IoC容器的加载过程(※)Q…...
Android嵌套事务
这时候旋转设备还是会重置秒表。旋转设备时Android会重新创建活动。如果你的活动包含一个 < fragment >元素,每次重新创建活动时,它会重新插入片段的一个新版本。老片段被丢掉,所有实例变量会设置其初始值。在这个特定的例子中…...
如何让项目准时上线?
项目为什么容易延期? 1、软件研发是一项创造性工作 项目延期是一种普遍现象,管理者最为头疼的一个问题。但是外人并不理解。明明是你们自己做的计划,怎么总会出现这么多问题。说到底,这是由于我们的工作特性决定的。我们做的是一…...
ChatGPT 和 Elasticsearch:APM 工具、性能和成本分析
作者:LUCA WINTERGERST 在本博客中,我们将测试一个使用 OpenAI 的 Python 应用程序并分析其性能以及运行该应用程序的成本。 使用从应用程序收集的数据,我们还将展示如何将 LLMs 成到你的应用程序中。 在之前的博客文章中,我们构建…...
不使用辅助变量的前提下实现两个变量的交换
package operator; //不用第三个辅助变量,实现两个数的交换 public class Demo08 {public static void change(int a, int b){a ab;b a-b;a a-b;System.out.println(a);System.out.println(b);}public static void main(String[] args) {change(900,3000);} }后续…...
SV-DJS-i13电梯对讲网关
SV-DJS-i13电梯对讲网关 DJS-I13 是一款主要应用于电梯场景的对讲设备,可以将电梯原有模拟通话器的模拟信号转换成数字信号,不仅有稳定性好、电信级音质的优点,且完美兼容当下所有基于SIP的主流IPPBX/软交换/IMS平台,如Asterisk, Broadsoft,…...
论文解析-基因序列编码算法DeepSEA
论文解析-DeepSEA 参考亮点功能 方法数据集来源数据 实验评估评估DeepSEA预测染色质特征的性能评估DeepSEA在变异序列上的DHS预测性能数据集结果 参考 Zhou, J., Troyanskaya, O. Predicting effects of noncoding variants with deep learning–based sequence model. Nat Me…...
计组与操作系统
非科班出身的程序员,还是得补一下相关理论课程,最近看了下九曲阑干关于CSAPP的视频,学习了一下计算机组成原理,这里列一下相关知识点。 计算机组成原理: 数的表示与运算:CSAPP第二章 指令系统࿰…...
Pytorch中张量矩阵乘法函数(mm, bmm, matmul)使用说明,含高维张量实例及运行结果
Pytorch中张量矩阵乘法函数使用说明 1 torch.mm() 函数1.1 torch.mm() 函数定义及参数1.2 torch.bmm() 官方示例 2 torch.bmm() 函数2.1 torch.bmm() 函数定义及参数2.2 torch.bmm() 官方示例 3 torch.matmul() 函数3.1 torch.matmul() 函数定义及参数3.2 torch.matmul() 规则约…...
如何在matlab绘图的标题中添加变量?变量的格式化字符串输出浅析
文章目录 matlab的格式化输出控制符字段宽度、精度和对齐方式的控制matlab的格式化输出总结 matlab的格式化输出控制符 Matlab在画图的时候,采用title函数可以增加标题,该函数的输入是一个字符串,有时候我们想在字符串中添加一些变量&#x…...
Spring MVC 八 - 内置过滤器
SpringMVC内置如下过滤器: Form DataForwarded HeadersShallow ETagCORS Form Data 浏览器可以通过HTTP GET或HTTP POST提交form data(表单数据),但是非浏览器客户端可以通过HTTP PUT、HTTP DELETE、HTTP PATCH提交表单数据。但…...
@Change监听事件与vue监听属性:watch的区别?
change 和 watch 是 Vue 中用于处理数据变化的两种不同方式。 1. change: - change 是一个事件监听器,用于监听特定DOM元素的变化事件,通常用于表单元素(如输入框、下拉框等)的值变化。 - 它在用户与表单元素交互并提交了变化时触…...
C++面试记录之中望软件
上次面试体验不好,记录了,这次同样记录一次体验不好的面试,中望软件…直接写了名字,因为真的很无语😓 记录一下我不知道的问题 忘记录音了😢 1. main函数之前做了什么? 我:实话我…...
多功能翻译工具:全球翻译、润色和摘要生成 | 开源日报 0914
openai-translator/openai-translator Stars: 18.1k License: AGPL-3.0 这个项目是一个多功能翻译工具,由 OpenAI 提供支持。 可以进行全球单词翻译、单词润色和摘要生成等操作提供三种模式:翻译、润色和摘要支持 55 种不同语言的互相转换支持流模式允…...
在 Vue.js 中,使用 watch 监听data变量如:对象属性/data变量
watch 监听对象属性 在 Vue.js 中,使用 watch 监听对象属性的变化时,应该将属性名作为字符串传递给 watch 选项。 示例如下: javascript watch: {addform.isCheck1: function(newValue) {console.log(newValue);var quantity this.addform…...
vue中预览xml并高亮显示
项目中有需要将接口返回的数据流显示出来,并高亮显示; 1.后端接口返回blob,类型为xml,如图 2.页面中使用pre code标签: <pre v-if"showXML"><code class"language-xml">{{xml}}</code></pre> …...
MFC中嵌入显示opencv窗口
在MFC窗体中建立一个Picture Control控件,用于显示opencv窗口 在属性中设置图片控件的资源ID为IDC_PIC1 主要的思路: 使用GetWindowRect可以获取图片控件的区域 使用cv::resizeWindow可以设置opencv窗口的大小,适合图片控件的大小 使用cvGetWindowHandle函数可以获取到ope…...
金鸣识别网页版:轻松实现表格识别的神器
来百度APP畅享高清图片 金鸣识别网页版是一款功能强大的在线识别工具,它可对图片或PDF中的表格文本内容进行识别,还支持各种证票的结构化识别。以下是以表格识别为例,对金鸣识别网页版的操作说明进行详细介绍: 首先,打…...
DasViewer可以设置打开指定文件吗?
答:会员可以。工具里面选择坐标转换,输入源数据,设置好源坐标和目标坐标以及路径。根据两张坐标系的性质选择转换方式。 DasViewer是由大势智慧自主研发的免费的实景三维模型浏览器,采用多细节层次模型逐步自适应加载技术,让用户在极低的电脑…...
uniapp微信小程序用户隐私保护指引弹窗组件
<template><view v-if"showPrivacy" :class"privacyClass"><view :class"contentClass"><view class"title">用户隐私保护指引</view><view class"des">感谢您选择使用我们的小程序&am…...
Java的反射应用(Method和Class)
记录:473 场景:使用java.lang.reflect.Method和java.lang.Class类,根据Java反射原理实现使用指定字符串类名和方法名称,调用对应对象和对应方法。 版本:JDK 1.8。 1.使用Java反射调用指定类的指定方法 (1)参数说明…...
Java之泛型系列--Class使用泛型的方法(有示例)
原文网址:Java之泛型系列--Class使用泛型的方法(有示例)_IT利刃出鞘的博客-CSDN博客 简介 本文用示例介绍Java在方法前加泛型的使用。 类类型的写法 对象所对应的类的泛型写法 Class classAClass<T> classAClass<?> classB Class与Class<?&g…...
【【无用的知识之串口学习】】
无用的知识之串口学习 USART串口协议 •通信的目的:将一个设备的数据传送到另一个设备,扩展硬件系统 •通信协议:制定通信的规则,通信双方按照协议规则进行数据收发 就是我们并不能在芯片上设计完全部的一下子完成所有的设计&am…...
9月13日上课内容 第三章 ELK日志分析系统
本章结构 ELK日志分析系统简介 ELK日志分析系统分为 Elasticsearch Logstash Kibana 日志处理步骤 1.将日志进行集中化管理 2.将日志格式化(Logstash) 并输出到Elasticsearch 3.对格式化后的数据进行索引和存储 (Elasticsearch) 4.前端数据的展示(Kibana) Elasticsearch介…...
不知道有用没用的Api
encodeURIComponent(https://www.baidu.com/?name啊啊啊) decodeURIComponent(https%3A%2F%2Fwww.baidu.com%2F%3Fname%3D%E5%95%8A%E5%95%8A%E5%95%8A) encodeURI(https://www.baidu.com/?name啊啊啊) decodeURI(https://www.baidu.com/?name%E5%95%8A%E5%95%8A%E5%95%8A) …...
(2023,LENS 视觉模型 LLM)迈向可见的语言模型:通过自然语言的镜头来看计算机视觉
Towards Language Models That Can See: Computer Vision Through the LENS of Natural Language 公众号:EDPJ(添加 VX:CV_EDPJ 进交流群获取资料) 目录 0. 摘要 1. 简介 2. 相关工作 2.1 大语言模型能力 2.2 解决视觉和…...
线段树上树剖再拿线段树维护:0914T4
cp 一种常见套路: 如果在线段树上进行一段区间修改,那么必然是一段右节点一段左节点 这个过程其实就是zkw的本质 下面都要用zkw来理解 考虑原题,有一棵不规则的线段树 类似zkw,在这类题目中,我们要先把开区间变成闭…...
互联网医院系统|互联网医院探索未来医疗的新蓝海
随着互联网技术的飞速发展,互联网医院应运而生,为人们带来全新的医疗体验。本文将深入探讨互联网医院的开发流程、系统优势以及未来发展方向,带您领略医疗领域的新蓝海。互联网医院的开发流程是一个结合技术、医疗和用户需求的复杂过程。首先…...
Acrel-2000系列监控系统在亚运手球比赛馆建设10kV供配电工程中的应用
安科瑞 崔丽洁 摘要:智能化配电监控系统是数字化和信息化时代应运而生的产物,已经被广泛应用于电网用户侧楼宇、体育场馆、科研设施、机场、交通、医院、电力和石化行业等诸多领域的高/低压变配电系统中。安科瑞自研的Acrel-2000系列监控系统可监控高压开关柜、低压…...
c++中遇到一个不了解的函数,查看能用的接口功能
在C中,您可以使用几种方法来查找函数的接口和使用方式。下面是一些常用的方法: 查阅官方文档:每个常见的C库都应该配有官方文档,其中包含所有可用函数和其接口的详细说明。您可以从官方网站或下载的文档中查找所需函数的接口和使用…...
网站建设和软件开发/品牌传播策略
R编程语言中有许多库用来创建图表,其中饼状图是以不同颜色的圆的切片表示的值,这些切片被标记,并且每个切片对应的数字也在图表中表示。在R中,我们将正数作为向量输入的pie()函数创建饼状图,附加参数用于控制标签&…...
旅游网站静态模版下载/自媒体运营主要做什么
文章都是通过阅读源码分析出来的,还在不断完善与改进中,其中难免有些地方理解得不对,欢迎大家批评指正转载请注明:From LXS. http://blog.csdn.net/uiop78uiop78/1.1 Android中的本地窗口在OpenGL的学习过程中,我们不断…...
公司网站建设模板/百度搜索如何去广告
http://edu.163.com/10/1213/16/6NQ0FMHK00293KTO_3.html 三、经济学 经济学完全有资格排在第三位。学习经济学的人,不会搞经济!我这里说的“搞经济”,涵义是很狭义的,就是不会挣钱,更不会赚钱。我本人就是学经济的&am…...
长沙有哪些大型工厂/seo深圳优化
涉及到的三个方法 set_window_size() 用于设置浏览器窗口的大小 e.gset_window_size(600,600) window.scrollTo() 用于设置浏览器窗口滚动条的水平和垂直位置window.scrollTo(300,120) 其中300左边距,120上边距 execute_script() 执行JavaScript代码来移动滚动条的…...
济南做网站的公司/百度推广工具有哪些
登录MySQL的命令是mysql:mysql [-u username] [-h host] [-p[password]] [dbname]mysql目录:数据库目录:/var/lib/mysql/配置文件 :/usr/share/mysql(mysql.server命令及配置文件)相关命令 :/usr/bin(mysqladmin mysql…...
手机网站域名开头/企业网站排名优化
知识趣记-线性代数,高数,机器学习,计网-2020年9月 矩阵的秩: 矩阵非零子式的最高阶数。 确定矩阵的秩,采用消元法。 等价矩阵: BQAP A可以通过有限次的初等变换得到B 特征向量: 在A的作用下&…...