【Spring面试】五、Bean扩展、JavaConfig、@Import

news2025/1/12 18:06:09

文章目录

  • Q1、如何在Spring创建完所有的Bean之后做扩展?
  • Q2、Spring容器启动时,为什么先加载BeanFactoryPostProcess?
  • Q3、Bean的生产顺序是由什么决定的?
  • Q4、Spring有哪几种配置方式
  • Q5、JavaConfig是如何替代spring.xml的?
  • Q6、@Component、@Controller、@Service、@Repository有何区别?
  • Q7、@Import可以有几种用法?

Q1、如何在Spring创建完所有的Bean之后做扩展?

问题涉及的源码分析:

点下Download Sources,把源码注释下载进来。new Spring容器时,调用了refresh方法:

在这里插入图片描述

refresh方法:(IoC容器的加载,就是在refresh方法里实现的)

在这里插入图片描述

new ApplicationContext() --> refresh() --> finishBeanFactorylnitialization (循环所有的BeanDefinition ,通过BeanFactory.getBean()生成所有的Bean), 这个循环结束之后所有的bean也就创建完了。而在循环结束后,还有一段代码,就是扩展的关键:

在这里插入图片描述

即这个实例实现了SmartInitializingSingleton接口,这就是实现的扩展点之一。再看refresh源码,finishBeanFactorylnitialization下面还有个finishRefresh方法:

在这里插入图片描述
这里发布了一个ContextRefreshedEvent的事件,我们只要创建个监听器,监听这个事件,也可以完成扩展。

答案:

  • 方式一:实现SmartInitializingSingleton接口

在这里插入图片描述

  • 方式二:要创建个监听器,监听ContextRefreshedEvent事件

在这里插入图片描述

看下效果,以上即Bean加载完成后输出一句测试的话:

在这里插入图片描述

Q2、Spring容器启动时,为什么先加载BeanFactoryPostProcess?

答案:

  • 因为BeanDefinition会在IoC容器加载的时候先注册,而BeanFactoryPostProcess是所有BeanDefinition注册完后做扩展用的,所以要先加载
  • 其次,Ioc容器的加载,即创建Bean,这就需要解析配置类(xml的bean标签、@Component…),负责解析的类也实现了BeanFactoryPostProcessor

在这里插入图片描述

Q3、Bean的生产顺序是由什么决定的?

BeanDefinition里装着Bean的一些信息,看创建IoC容器的源码中的refresh方法的源码:

在这里插入图片描述

答案:

所以Bean的生产顺序是由BeanDefinition的注册顺序决定的,当然依赖关系也会影响Bean的创建顺序。

BeanDefinition的注册顺序由什么决定?

主要由注解(或配置)的解析顺序来决定,由源码看到解析顺序为:

  • @Configuration
  • @Component(当然它还有@Order来细分,这里不细分)
  • @Import的一类
  • @Bean
  • 使用BeanDefinitionRegistryPostProcessor注册的

从上下文拿一下BeanDefinitionNames,是个String[],有序,输出下:

在这里插入图片描述

在这里插入图片描述

按照上面这个注册顺序,以及Spring中后面的Bean覆盖前面的Bean,还可以这么应用:有个用@Component注册的Bean,我想让他失效并替换成另一个,则可以用@Bean再写一个

Q4、Spring有哪几种配置方式

答案:

有三种方式给Spring容器提供配置的元数据:

  • XML配置文件:从Spring诞生开始用,spring.xml中用<bean>标签
  • 基于注解:从Spring2.5+开始,spring.xml <component-scan base-package=""/> + @Component
  • 基于JavaConfig:从Spring3.0开始,使用@Configuration代替xml,使用@Bean代替Bean标签

Q5、JavaConfig是如何替代spring.xml的?

答案:

对于XML

  • 创建Spring容器是new ClassPathXmlApplicationContext(“a.xml”)
  • 有一个spring.xml文件
  • 配置一个Bean是用bean标签,scope、lazy属性
  • 扫描包用<component-scan base-package=""/>
  • 引入外部的属性配置文件用<property-placeHolder resource="/xx.properties">
  • 引入配置文件后,使用其属性给Bean属性赋值为${}
<property name="password" value="${mysql.password}"></property>
  • 指定其他配置文件用<import resource="">

对于JavaConfig

  • 创建Spring容器是new AnnotationConfigApplicationContext(javaConfig.class)
  • 有一个配置类,被@Configuration注解修饰
  • 配置一个Bean是用@Bean注解,属性也用注解@Scope、@Lazy
  • 扫描包用@ComponentScan
  • 引入外部的属性配置文件用@PropertySource("classpath:db.properties")
  • 使用配置文件中的值为@Value("${}")
  • 指定其他用@Import(配置类)

以上是应用层的区别,最后,从源码和流程上来说:大方向都是创建Spring容器(同一个接口,不同的实现类),然后加载、解析配置,再注册为BeanDefinition后交给Bean工厂生产。

在这里插入图片描述

Q6、@Component、@Controller、@Service、@Repository有何区别?

答案:

这四个注解其实是一个注解,@Controller、@Service、@Repository的源注解都是@Component

在这里插入图片描述

之所以分为三种,是因为开发一个项目,常使用三层架构,即控制层、业务层、数据返回层,提供这三个注解用于不同层,提高代码的阅读性。

Q7、@Import可以有几种用法?

答案:

四种:

  • 第一种:直接指定类(如果是配置类,就会按照配置类来解析,如果是个普通类,则直接解析成Bean)
@Import(UserMapper.class)
@Import(JavaConfig.class)   //此时,JavaConfig这个配置类中的Bean也会生效
  • 第二种:导入一个实现了ImportSelector这个接口的类,这种方式可以一次性注册多个,返回一个String[ ],每一个值是完整类路径
public class MyImportSelector implements ImportSelector{
	
	@Override
	public String[] selectImports(AnnotationMetadata importingClassMetadata){
		//可以以字符串数组的形式注册多个Bean 
		//字符串必须是类的完整类名
		return new String[]{"com.llg.UserMapper","com.llg.Role"};
	}
}
@Configuration
@Import(MyImportSelector.class)
public class MainConfig{

}

但注意,这个时候的Bean创建不是正常的IoC加载流程,使用@Import,之前的一个postProcessBeanFactory在所有Beanfinition注册完之后修改这个Import的Bean的信息就会报错

在这里插入图片描述

  • 第三种:导入一个实现ImportBeanDefinitionRegistrar的接口的类,这种也可以一次导入多个,是通过BeanDefinitionRegistry来动态注册BeanDefinition,因此这种方式是没有上面在所有Beanfinition注册完之后修改这个Import的Bean的信息就会报错的这个情况的。

在这里插入图片描述
在这里插入图片描述

  • 第四种:这种其实是第二种的衍生,第二种的接口有个子接口,叫延迟导入选择器,也可以一次导入多个Bean,和ImportSelector的区别是DeferredImportSelector的顺序更靠后

在这里插入图片描述
在这里插入图片描述

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

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

相关文章

InVideo AI:用人工智能轻松制作视频

简介&#xff1a; InVideo AI 是一款在线视频制作工具&#xff0c;使用人工智能来帮助用户快速、轻松地制作高质量的视频。该工具提供多种功能&#xff0c;包括&#xff1a; 链接&#xff1a; ai.invideo.io 仪表盘&#xff1a; 历史记录&#xff1a; 创建视频&#xff1a…

【Linux从入门到精通】信号(初识信号 信号的产生)

本篇文章会对Linux下的信号进行详细解释。主要内容是什么是信号、信号的产生、核心转储等问题。希望本篇文章会对你有所帮助。 文章目录 引入 一、初识信号 1、1 生活中的信号 1、2 Linux 下的信号 1、3 信号进程所得的初识结论 二、信号的产生 2、1 用户通过终端输入产生信号 …

2023年9月NPDP产品经理国际认证报名来这里就对了

产品经理国际资格认证NPDP是新产品开发方面的认证&#xff0c;集理论、方法与实践为一体的全方位的知识体系&#xff0c;为公司组织层级进行规划、决策、执行提供良好的方法体系支撑。 【认证机构】 产品开发与管理协会&#xff08;PDMA&#xff09;成立于1979年&#xff0c;是…

针对电子企业生产特征,提出MES管理系统解决方案

随着全球经济一体化的不断加剧&#xff0c;中国作为一个制造业大国&#xff0c;在电子组装、SMT贴片、PCB组装等领域取得了很大的突破&#xff0c;企业规模和数量随着不断增加&#xff0c;造成成本压力增加、产品生命周期缩短、设备日益复杂且缺少透明度以及不明需求预测&#…

SLAM从入门到精通(编写第一个package)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 前面我们安装了ROS环境&#xff0c;接着就可以开始进行ROS程序的开发了。在开发之前&#xff0c;我们有几个概念需要厘清一下。第一个是workspace&…

linux系统中LVM磁盘动态扩容方案

LVM动态扩展方案 信息确认&#xff1a; 磁盘空间确认 挂载磁盘的文件系统确认 lv卷组信息确认 1、确认磁盘已扩容&#xff1a;首先确认物理磁盘&#xff08;vdb&#xff09;已成功扩容至500G。 fdisk -l2、重新分区&#xff1a;将物理磁盘上多出的200G空间格式化为新的分区…

geopandas笔记:汇总连接两个区域的边

比如这样的两个区域&#xff0c;我们想知道从蓝到绿、从绿到蓝都有哪些边 1 读取openstreetmap import osmnx as ox import geopandas as gpdGox.graph_from_place(Singapore,simplifyTrue,network_typedrive)ox.plot_graph(G) 2 得到对应的边的信息 nodes,edgesox.graph_to_…

怎么在图片上编辑文字?这几种图片编辑工具了解下

在图片上编辑文字可以带来许多好处。首先&#xff0c;它可以更好地说明图片的内容和意义。有时候&#xff0c;一张图片可能不够清晰地传达想要表达的信息&#xff0c;但是通过在图片上添加文字说明&#xff0c;可以更好地让观众理解图片的意义。其次&#xff0c;编辑文字可以使…

AliExpress速卖通支付下单流程(测评补单优势及技术要点)

1. 打开全球速卖通官网,点击右上方的Join &#xff08;注册&#xff09;填写邮箱和密码&#xff0c;验证完毕后注册成功 2. 点击右上角的Account(账户)进入用户菜单 3. 点击导航了第一个My AliExpress&#xff08;我的速卖通&#xff09;选择左边My Shipping Address&#xff0…

VSCode自动分析代码的插件

今天来给大伙介绍一款非常好用的插件&#xff0c;它能够自动分析代码&#xff0c;并帮你完成代码的编写 效果如下图 首先我们用的是VSCode&#xff0c;&#xff08;免费随便下&#xff09; 找到扩展&#xff0c;搜索CodeGeeX&#xff0c;将它下载好&#xff0c;就可以实现了 到…

PathVariable注解

postman测试传参&#xff1a;http://localhost:8080/admin/employee/2 PathVariable PathVariable注解用法和作用

淘宝商品描述详细信息API接口

淘宝商品描述详细信息API接口是一个用于获取淘宝商品详细信息的API&#xff0c;通过它可以获取到商品的标题、价格、图片等信息。通过淘宝商品描述详细信息API接口&#xff0c;开发者可以方便地获取宝贝的相关信息&#xff0c;并将它们用于各种应用场景中。淘宝商品描述详细信息…

模板语言-Handlebars

Handlebars 是什么 Handlebars 是一种简单的模板语言。 它使用模板与传入的对象来生成HTML 或者其他文本格式。 Handlebars 模板看起来像是嵌入了handlebars 表达式的普通文本。 <p> {{firstname}} {{lastname}}</p> 一个handlebars表达式是使用两对尖括号包裹…

飞猪店铺小管家软件需求分析说明书

飞猪店铺小管家软件 项目背景&#xff1a; 在飞猪店铺运营过程中&#xff0c;客服人数不足导致客服团队忙不过来&#xff0c;容易出现订票信息错误&#xff0c;进而客户无法顺利参观景点&#xff0c;频繁投诉。这种情况不仅影响客户体验&#xff0c;还可能导致商家因赔付而承受…

玖章算术叶正盛:为什么 PostgreSQL 不如 MySQL 流行?|3306π活动预告

议题大纲 PostgreSQL 是业界功能最强大的开源数据库&#xff0c;为什么在全球流行度没有 MySQL 高&#xff0c;本次分享主题计划从产品、技术、商业等方面综合分析两个数据库的竞争。 议题方向&#xff1a; PostgreSQL 与 MySQL 数据库简介 市场分析 产品定位 技术优劣势 …

TensorFlow与pytorch特定版本虚拟环境的安装

TensorFlow与Python的版本对应&#xff0c;注意&#xff0c;一定要选择对应的版本&#xff0c;否则会让你非常痛苦&#xff0c;折腾很久搞不清楚原因。 建议使用国内镜像源安装 没有GPU后缀的就表示是CPU版本的&#xff0c;不加版本就是最新 pip install tensorflow -i https:…

如何创建集成 LSP 支持多语言的 Web 代码编辑器

对于一个云开发平台来说&#xff0c;一个好的 Web IDE 能很大程度地提高用户的编码体验&#xff0c;而一个 Web IDE 的一个重要组成部分就是代码编辑器。 目前有着多款 web 上的代码编辑器可供选择&#xff0c;比如 Ace、CodeMirror、Monaco&#xff0c;这三款编辑器的比较在这…

[ 云计算 华为云 ] 解决办法:如何更换华为云云耀云服务器L实例的镜像 | 文末送书

文章目录 问题描述分析原因解决办法文末送书《ANSYS Workbench项目分析与案例实操详解》博主推荐理由本书内容简介本书作者简介 废话在前&#xff08;直接看解决办法的这段可以过&#xff09;&#xff1a;讲道理&#xff0c;一般情况下云服务器&#xff0c;镜像是随便更换的&am…

13-JVM调优实战-3

上一篇&#xff1a;12-JVM调优实战-2 今天来介绍一款阿里巴巴的调优工具。 Arthas详解 Arthas 是 Alibaba 在 2018 年 9 月开源的 Java 诊断工具。支持 JDK6&#xff0c; 采用命令行交互模式&#xff0c;可以方便的定位和诊断线上程序运行问题。Arthas 官方文档十分详细&am…

【驱动开发】实现三盏灯的控制,编写应用程序测试

head.h #ifndef __HEAD_H__ #define __HEAD_H__//LED1:PE10 //LED2:PF10 //LED3:PE8#define LED_RCC 0X50000A28 //使能GPIO#define LED_MODER 0X50006000 //设置输出模式 #define LED_ODR 0X50006014 //设置输出高低电平#define LED2_MODER 0X50007000 …