【Spring源码系列】Spring扫描注解-@ComponentScan底层原理解读

news2024/11/24 12:33:04

这里写目录标题

    • 前言
  • 一、Spring扫描-@ComponentScan注解介绍
    • @ComponentScan作用
    • @ComponentScan重要参数
  • 二、Spring扫描-源码分析
    • 声明关键点
    • 源代码解读
    • Spring扫描流程图

前言

先不废话了,直接干吧。

一、Spring扫描-@ComponentScan注解介绍

@ComponentScan作用

@ComponentScan注解的作用可以简述为:将项目中所有被@Component注解标记的类---->组装成BeanDefinition---->然后以key value的形式注入到IOC容器中。

@ComponentScan重要参数

@ComponentScan中有多个参数,其中尤为重要的几个参数如下:

  1. value:用来指定basePackage的路径;
  2. excludeFilters:可以把被@Component标识的类排除注入到IOC容器;
  3. includeFilters:可以把不被@Component标识的类注入到IOC容器中;

示例:

@ComponentScan(value = "com.zhouyu",
		excludeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,classes = UserService.class)},
		includeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,classes = User.class)})

二、Spring扫描-源码分析

声明关键点

在讲源码之前呢,我们可以先增强几个知识点的概念。这些知识点在阅读Spring扫描源码中起着关键作用。

1、@ComponentScan只会扫描被 @Component标识的类。 诸如@Bean、spring.xml文件的< bean/>标签、编程式声明BeanDefinition等,都不会被@ComponentScan扫描;

2、@ComponentScan的excludeFiltersincludeFilters参数影响着类是否注入IOC容器。excludeFilters中指定了一个带有@Component注解的类,该类也不会注入到容器中;includeFilters中指定了一个不带有@Component注解的类,该类也会注入到容器中;

3、被@ComponentScan扫描注入到IOC容器中的BeanDefinition,其具体实现类是:ScannedGenericBeanDefinition

4、@ComponentScan扫描涉及到的相关注解:@Conditional@Scope和@Lookup@Lazy@Primary@DependsOn@Role@Description

  • @Conditional的作用是:即使该类被@Component修饰,但是Conditional返回false,该类也不会注入到IOC容器;
  • @Scope的作用是:仅仅作为一个标识,赋值给BeanDefinition的scope属性;
  • @Lookup:抽象类本身不能被扫描进容器,但是被@Lookup注解修饰则可以;
  • @Lazy、@Primary、@DependsOn、@Role:这几个类是一起被处理的,也只是用来给BeanDefinition赋值,分别对应着:setLazyInit(boolean)、setPrimary(boolean)、setDependsOn(value)、setRole(value)、setDescription(value);

5、须知Resource类和MetadataReader类。

  • Resource[]数组对象会存储basePackage包路径下所有的class的文件对象(注意:是所有的class的文件对象都会存储,无论有没有被@Component修饰);
  • MetadataReader类是Spring用来解析类的信息(比如类名、类中的方法、类上的注解、是否是抽象类…,这些都可以称之为类的元数据)的一个工具类。MetadataReader、ClassMetadata、AnnotationMetadata都可以用来解析类信息;

6、@ComponentScan扫描最终生成两个map:Map<String, BeanDefinition> beanDefinitionMapMap<String, String> aliasMap

  • beanDefinitionMap用于存储BeanDefinition,key是beanName,value是BeanDefinition;
  • aliasMap用于存储bean的别名,key是别名,value是beanName。@Component没有设置bean别名功能,@Bean可以设置别名。
@ComponentScan("org.example")
public class AppConfig {

    /**
     * 声明:
     *  如果@Bean没有设置value参数,那么IOC中beanName = "createBookService";
     *  如果@Bean设置了多个value参数,那么IOC中beanName = array[0]
     */
    @Bean({"bookService","bookService2"})
    public BookService createBookService(){
        return new BookService();
    }
}	

7、其他:

  • ASM技术:为什么要使用ASM技术,Spring启动的时候需要去扫描,如果指定的包路径比较宽泛,那么扫描的类是非常多的,那如果在Spring启动时就把这些类全部加载进JVM了,这样不太好,所以使用了ASM技术;

源代码解读

源码具体位置:org.springframework.context.annotation.ClassPathBeanDefinitionScanner#doScan

protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
			Assert.notEmpty(basePackages, "At least one base package must be specified");
			Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
			// 遍历basePackages
			for (String basePackage : basePackages) {

				// 扫描basePackages下所有的文件,进行include、exclude、@Conditional判断后返回BeanDefinition
				Set<BeanDefinition> candidates = findCandidateComponents(basePackage);

				for (BeanDefinition candidate : candidates) {
					ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate); // scope解析:单例与多例
					candidate.setScope(scopeMetadata.getScopeName());

					String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry); // 生成beanName:默认是类名首字母小写,如果@Component中指定了name则使用指定的name

					/* ScannedGenericBeanDefinition extends GenericBeanDefinition(AbstractBeanDefinition) implements AnnotatedBeanDefinition  */
					// 设置BeanDefinition的默认值
					if (candidate instanceof AbstractBeanDefinition) {
						postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
					}
					if (candidate instanceof AnnotatedBeanDefinition) {
						// 解析@Lazy、@Primary、@DependsOn、@Role、@Description
						AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
					}

					// 检查Spring容器中是否已经存在该beanName(如果存在则抛出异常)
					if (checkCandidate(beanName, candidate)) {
						BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
						definitionHolder =
								AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
						beanDefinitions.add(definitionHolder);

						// 注册: beanDefinitionMap.put(beanName, beanDefinition)
						registerBeanDefinition(definitionHolder, this.registry);
					}
				}
			}
			return beanDefinitions;
		}

Spring扫描流程图

在这里插入图片描述

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

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

相关文章

vscode搭建LVGL开发环境

更多精彩请关注微信公众号 南山府嵌入式 关注我&#xff0c;每天只是不断 准备环境 vscode msys2 有关vscode程序的安装这里不在演示。 mysys2的安装 点击一步继续操作&#xff1a; 选择安装路径&#xff1a;然后就一直下一步等待安装即可。 安装完成后打开是这样的&#xf…

Qt之天气预报——功能实现篇(含源码+注释)

文章目录一、功能概述1.基本功能2.实时天气模式3.预报天气模式二、天气预报功能示例图1.城市选择&#xff08;下拉框&#xff09;2.城市选择&#xff08;文本框&#xff09;3. 预报天气日期切换4.刷新操作三、使用类的简述3.1 涉及的Qt类3.2 自定义类3.2.1 自定义结构体3.2.2 自…

基于PHP的玩偶玩具商城网站设计

目 录 摘 要 I Abstract II 第1章 绪论 1 1.1 定制商城网站背景及意义 1 1.1.1 开发背景 1 1.1.2 开发意义 1 1.2研究现状 2 1.2.1个性化定制现状 2 1.2.2 定制类网站技术现状 3 1.3 研究主要内容 3 第2章 玩偶定制网站需求分析 4 2.1注册 4 2.2.1登陆 4 2.2.2账户中心 5 2.2.3…

计算机网络笔记1 概述

计算机网络笔记1 概述笔记前言&#x1f497;一、计算机网络概述&#x1f60d;二、计算机网络的性能指标&#x1f4a5;1、速率2、带宽3、吞吐量4、时延5、时延带宽积6、往返时间(Round-Trip-Time)7、利用率8、丢包率三、计算机网络的体系结构&#x1f525;四、计算机网络中的专业…

基于神经气体网络的图像分割与量化(Matlab代码实现)

&#x1f352;&#x1f352;&#x1f352;欢迎关注&#x1f308;&#x1f308;&#x1f308; &#x1f4dd;个人主页&#xff1a;我爱Matlab &#x1f44d;点赞➕评论➕收藏 养成习惯&#xff08;一键三连&#xff09;&#x1f33b;&#x1f33b;&#x1f33b; &#x1f34c;希…

菜狗杯Misc抽象画wp

目录一、拿到题目先干嘛二、具体的解密操作1.把文本放到CyberChef中用Magic解密2.把完整的解密内容复制出来3.打开010并以hex格式粘贴内容4.点一下HEX5.保存成png三、用工具拿到隐写内容一、拿到题目先干嘛 题目附件是一个txt&#xff0c;打开里面就是各种字符&#xff0c;拿去…

操作系统考试速成01

1. ___分时____操作系统允许在一台主机上同时连接多台终端&#xff0c;多个用户可以通过各自的终端同时交互地使用计算机 2.分时操作系统通常采用____时间片轮转___策略为用户服务 3.批处理操作系统&#xff1a;多个作业给到计算机系统 3.实时操作系统&#xff1a;计算机系统…

使用WPS Office模糊处理图片-可用作浏览器背景

前文转到&#xff1a;给浏览器设置一个图片背景/主题 使用WPS Office模糊处理图片-可用作浏览器背景&#xff0c;步骤如下&#xff1a; 1、打开WPS Office&#xff0c;新建一个空白PPT&#xff0c;或者右键-新建-PPT演示文稿 2、将你的图片插入到空白页上&#xff0c;点击 插入…

[激光原理与应用-27]:《激光原理与技术》-13- 激光产生技术 - 激光稳频技术

目录 前言&#xff1a; 第1章 什么频率的稳定性和可复现性。 1.1 频率的稳定度 1.2 频率复现性 第2章 影响激光频率稳定的因素。 2.1 温度引起腔长变化。则有 2.2 大气变化引起折射率的变化。 2.3 机械振动对频率稳定性的影响。 2.4 外部因素 2.5 内部因素 第3章 常…

Day16--购物车页面-商品列表-基于props封装radio的勾选状态

提纲挈领&#xff1a; 我的操作&#xff1a; 1》打开 my-goods.vue 组件的源代码&#xff0c;为商品的左侧图片区域添加 radio 组件&#xff1a; 2》给类名为 goods-item-left 的 view 组件添加样式&#xff0c;实现 radio 组件和 image 组件的左右布局&#xff1a; 1》和2》的…

9 个你可能从未使用过的很棒的 CSS 属性

如今&#xff0c;网络上的每个网站或 Web 应用程序都需要大量的 CSS 代码来装饰它们&#xff0c;这样可以使网站看起来既漂亮又出众。我个人认为如果不使用 CSS&#xff0c;我们将永远不会有一个可以帮助我们脱颖而出的优秀网页设计。 CSS 是一种非常有用的样式表语言&#xf…

记liunx服务器java程序无法访问的问题处理

查看java程序的运行日志&#xff1a; 通过日志查看&#xff0c;在凌晨3点半之后就没有再打印信息了&#xff0c;说明大概在这个点程序已经挂了。 查看liunx的系统日志&#xff1a; 查看linux系统级别的message信息&#xff1a; 在3点半出现了OOM&#xff08;内存溢出&#xff0…

在构建 Web3 前,需先知道什么是区块链,毕竟 Web3 是基于区块链

什么是区块链 要说什么是区块链&#xff0c;那么这里就不得不提比特币了&#xff0c;它是一种点对点&#xff08;Peer to Peer&#xff0c;P2P&#xff09;形式的去中心化加密货币&#xff0c;点对点的传输意味着是一个去中心化的支付系统。比特币的概念最初是由中本聪在2008年…

传奇开服架设教程

传奇架设其实很简单 很多网友非常爱玩这款游戏&#xff0c;可能还有朋友不知道怎么架设这款游戏 今天特意写篇传奇架设教程&#xff0c;希望大家都能打造出真正属于自己的传奇 首先传奇架设需要准备以下几个软件 准备工具&#xff1a; 1、传奇服务端&#xff08;版本&#…

excel求和怎么操作?这三个简单操作方法,轻松掌握

​excel作为常用的办公软件&#xff0c;不少人都会在工作的时候使用到。其中最常用的一个功能就是使用excel进行求和了。excel求和怎么操作&#xff1f;excel求和的快捷键是什么&#xff1f;今天小编给大家带来了excel求和的三种方法&#xff0c;亲测好用&#xff0c;有需要的小…

C++【类的自动类型转换和强制类型转换】,总要了解一下

学习目标 学习类的自动类型转换和强制类型转换 学习内容 &#x1f496;类的强制转换数据类型和自动转换数据&#xff1a; 类的强制转换数据类型 想让类的对象强制转换为基本数据类型&#xff0c;需要在类中添加类的转换函数 1、转换函数必须是类方法2、转换函数不能指定返回…

1.2 无监督学习和强化学习

1.2 无监督学习和强化学习无监督学习定义无监督学习与监督学习的区别相关概念流程图强化学习无监督学习 定义 无监督学习 (Unsupervised Learning&#xff09;是指从无标注数据中学习预测模型的机器学习问题&#xff0c;其本质是学习数据中的统计规律或潜在结构。 无监督学习…

算法与数据结构介绍

算法与数据结构介绍 算法和数据结构不受语言限制&#xff0c;每种编程语言都有关于自己的实现 算法 什么是算法 算法是指解题方案的准确而完整的描述&#xff0c;算法是一系列解决问题的清晰指令&#xff0c;算法使用系统的方法来解决问题的机制。 算法作用 对于实际业务…

Kamiya丨Kamiya艾美捷大鼠成纤维细胞生长因子2说明书

Kamiya艾美捷大鼠成纤维细胞生长因子2&#xff0c;碱性&#xff08;FGF2&#xff09;ELISA预期用途&#xff1a; 该试剂盒是一种夹心酶免疫分析法&#xff0c;用于在体外定量测量大鼠FGF2血清、血浆、组织匀浆、细胞裂解物、细胞培养上清液和其他生物液体。对于仅供研究使用。…

laravel vue tailwind normalize

下载laravel最新7.x composer create-project --prefer-dist laravel/laravle blog 7.x-dev cd blog valet link blog valet links blog.test 测试通过后&#xff0c;开始安装tailwind npm i npm i tailwindcss autoprefixer postcss7 都是最新版应该也没有什么问题 在根目录下…