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

【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还只是代码里的简单定义,即概念态的Bean)
  • 调用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的作用是什么&#xff1f;Q2、BeanDefinition的作用是什么&#xff1f;Q3、BeanFactory和ApplicationContext有什么区别&#xff1f;Q4、BeanFactory和FactoryBean有什么区别&#xff1f;Q5、说下Spring IoC容器的加载过程&#xff08;※&#xff09;Q…...

Android嵌套事务

这时候旋转设备还是会重置秒表。旋转设备时Android会重新创建活动。如果你的活动包含一个 < fragment >元素&#xff0c;每次重新创建活动时&#xff0c;它会重新插入片段的一个新版本。老片段被丢掉&#xff0c;所有实例变量会设置其初始值。在这个特定的例子中&#xf…...

如何让项目准时上线?

项目为什么容易延期&#xff1f; 1、软件研发是一项创造性工作 项目延期是一种普遍现象&#xff0c;管理者最为头疼的一个问题。但是外人并不理解。明明是你们自己做的计划&#xff0c;怎么总会出现这么多问题。说到底&#xff0c;这是由于我们的工作特性决定的。我们做的是一…...

ChatGPT 和 Elasticsearch:APM 工具、性能和成本分析

作者&#xff1a;LUCA WINTERGERST 在本博客中&#xff0c;我们将测试一个使用 OpenAI 的 Python 应用程序并分析其性能以及运行该应用程序的成本。 使用从应用程序收集的数据&#xff0c;我们还将展示如何将 LLMs 成到你的应用程序中。 在之前的博客文章中&#xff0c;我们构建…...

不使用辅助变量的前提下实现两个变量的交换

package operator; //不用第三个辅助变量&#xff0c;实现两个数的交换 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 是一款主要应用于电梯场景的对讲设备&#xff0c;可以将电梯原有模拟通话器的模拟信号转换成数字信号&#xff0c;不仅有稳定性好、电信级音质的优点&#xff0c;且完美兼容当下所有基于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…...

计组与操作系统

非科班出身的程序员&#xff0c;还是得补一下相关理论课程&#xff0c;最近看了下九曲阑干关于CSAPP的视频&#xff0c;学习了一下计算机组成原理&#xff0c;这里列一下相关知识点。 计算机组成原理&#xff1a; 数的表示与运算&#xff1a;CSAPP第二章 指令系统&#xff0…...

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在画图的时候&#xff0c;采用title函数可以增加标题&#xff0c;该函数的输入是一个字符串&#xff0c;有时候我们想在字符串中添加一些变量&#x…...

Spring MVC 八 - 内置过滤器

SpringMVC内置如下过滤器&#xff1a; Form DataForwarded HeadersShallow ETagCORS Form Data 浏览器可以通过HTTP GET或HTTP POST提交form data&#xff08;表单数据&#xff09;&#xff0c;但是非浏览器客户端可以通过HTTP PUT、HTTP DELETE、HTTP PATCH提交表单数据。但…...

@Change监听事件与vue监听属性:watch的区别?

change 和 watch 是 Vue 中用于处理数据变化的两种不同方式。 1. change: - change 是一个事件监听器&#xff0c;用于监听特定DOM元素的变化事件&#xff0c;通常用于表单元素&#xff08;如输入框、下拉框等&#xff09;的值变化。 - 它在用户与表单元素交互并提交了变化时触…...

C++面试记录之中望软件

上次面试体验不好&#xff0c;记录了&#xff0c;这次同样记录一次体验不好的面试&#xff0c;中望软件…直接写了名字&#xff0c;因为真的很无语&#x1f613; 记录一下我不知道的问题 忘记录音了&#x1f622; 1. main函数之前做了什么&#xff1f; 我&#xff1a;实话我…...

多功能翻译工具:全球翻译、润色和摘要生成 | 开源日报 0914

openai-translator/openai-translator Stars: 18.1k License: AGPL-3.0 这个项目是一个多功能翻译工具&#xff0c;由 OpenAI 提供支持。 可以进行全球单词翻译、单词润色和摘要生成等操作提供三种模式&#xff1a;翻译、润色和摘要支持 55 种不同语言的互相转换支持流模式允…...

在 Vue.js 中,使用 watch 监听data变量如:对象属性/data变量

watch 监听对象属性 在 Vue.js 中&#xff0c;使用 watch 监听对象属性的变化时&#xff0c;应该将属性名作为字符串传递给 watch 选项。 示例如下&#xff1a; javascript watch: {addform.isCheck1: function(newValue) {console.log(newValue);var quantity this.addform…...

vue中预览xml并高亮显示

项目中有需要将接口返回的数据流显示出来&#xff0c;并高亮显示&#xff1b; 1.后端接口返回blob,类型为xml,如图 2.页面中使用pre code标签&#xff1a; <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畅享高清图片 金鸣识别网页版是一款功能强大的在线识别工具&#xff0c;它可对图片或PDF中的表格文本内容进行识别&#xff0c;还支持各种证票的结构化识别。以下是以表格识别为例&#xff0c;对金鸣识别网页版的操作说明进行详细介绍&#xff1a; 首先&#xff0c;打…...

DasViewer可以设置打开指定文件吗?

答&#xff1a;会员可以。工具里面选择坐标转换&#xff0c;输入源数据&#xff0c;设置好源坐标和目标坐标以及路径。根据两张坐标系的性质选择转换方式。 DasViewer是由大势智慧自主研发的免费的实景三维模型浏览器,采用多细节层次模型逐步自适应加载技术,让用户在极低的电脑…...

uniapp微信小程序用户隐私保护指引弹窗组件

<template><view v-if"showPrivacy" :class"privacyClass"><view :class"contentClass"><view class"title">用户隐私保护指引</view><view class"des">感谢您选择使用我们的小程序&am…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

Java面试专项一-准备篇

一、企业简历筛选规则 一般企业的简历筛选流程&#xff1a;首先由HR先筛选一部分简历后&#xff0c;在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如&#xff1a;Boss直聘&#xff08;招聘方平台&#xff09; 直接按照条件进行筛选 例如&#xff1a…...

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中&#xff0c;我们渴望一个能激发创想、愉悦感官的工作与生活伙伴&#xff0c;它不仅是冰冷的科技工具&#xff0c;更能触动我们内心深处的细腻情感。正是在这样的期许下&#xff0c;华硕a豆14 Air香氛版翩然而至&#xff0c;它以一种前所未有的方式&#x…...

使用Spring AI和MCP协议构建图片搜索服务

目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式&#xff08;本地调用&#xff09; SSE模式&#xff08;远程调用&#xff09; 4. 注册工具提…...

【笔记】WSL 中 Rust 安装与测试完整记录

#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统&#xff1a;Ubuntu 24.04 LTS (WSL2)架构&#xff1a;x86_64 (GNU/Linux)Rust 版本&#xff1a;rustc 1.87.0 (2025-05-09)Cargo 版本&#xff1a;cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...

CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝

目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为&#xff1a;一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...