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

【Spring生命周期核心底层源码之剖析】

文章目录

  • 一、Spring生命周期核心底层源码剖析—扫描
    • 1.1、Spring底层扫描机制doScan方法源码剖析

一、Spring生命周期核心底层源码剖析—扫描

1.1、Spring底层扫描机制doScan方法源码剖析

其源代码如下:

protected Set<BeanDefinitionHolder> doScan(String... basePackages) {Assert.notEmpty(basePackages, "At least one base package must be specified");Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();for (String basePackage : basePackages) {Set<BeanDefinition> candidates = findCandidateComponents(basePackage);//遍历其获取到的BeanDefinition对象for (BeanDefinition candidate : candidates) {//为其BeanDefinition对象进行属性赋值,例如scope,beanName等ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);candidate.setScope(scopeMetadata.getScopeName());String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);if (candidate instanceof AbstractBeanDefinition) {postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);}if (candidate instanceof AnnotatedBeanDefinition) {AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);}//判断当前的bean是否已经在Spring容器中存在,存在需封装为BeanDefinitionHolder对象if (checkCandidate(beanName, candidate)) {BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);definitionHolder =AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);beanDefinitions.add(definitionHolder);registerBeanDefinition(definitionHolder, this.registry);}}}return beanDefinitions;}

1、其主要是通过传入的包路径进行资源加载,加载时方法为上诉代码的for循环下的第一行代码的findCandidateComponents()方法,可以详细看此方法,是如何加载资源的,其方法代码如下(具体说明以及解析过程可参考注释):

public Set<BeanDefinition> findCandidateComponents(String basePackage) {//此处主要是判断项目是否配置了相关的bean文件,若有,就不需要再逐个类进行扫描+判断是否为Beanif (this.componentsIndex != null && indexSupportsIncludeFilters()) {return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);}//大部分的业务都会走如下方法else {return scanCandidateComponents(basePackage);}}//scanCandidateComponents方法具体实现为
private Set<BeanDefinition> scanCandidateComponents(String basePackage) {Set<BeanDefinition> candidates = new LinkedHashSet<>();try {//1、资源路径组装解析String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +resolveBasePackage(basePackage) + '/' + this.resourcePattern;//2、利用类元数据读取器读取器路径下包含的资源数据Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);boolean traceEnabled = logger.isTraceEnabled();boolean debugEnabled = logger.isDebugEnabled();//3、遍历类元数据读取器获取到的资源数据(class资源文件数据)for (Resource resource : resources) {if (traceEnabled) {logger.trace("Scanning " + resource);}try {//4、获取当前类元数据(calss)具体资源信息MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);//5、判断当前的类(class)上包含的是否包含排除注解excludeFilters以及非排除注解includeFilters,以及是否包含相关的条件注解Conditionalif (isCandidateComponent(metadataReader)) {//6、创建一个BeanDefinition对象,用于封装其类特征信息,例如:beanClass、scope、lazyInit等属性ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);//7、将类资源数据加入到BeanDefinition中sbd.setSource(resource);//8、判断当前的类资源是否是独立的(例如是否是内部类等),除此歪,需要判断其是否为接口或者抽象类,如果是抽象类,那类中必须有被Lookup注解的方法,否则不会被当做beanif (isCandidateComponent(sbd)) {if (debugEnabled) {logger.debug("Identified candidate component class: " + resource);}//9、将封装好的BeanDefinition对象加入到返回的集合Set中candidates.add(sbd);}else {if (debugEnabled) {logger.debug("Ignored because not a concrete top-level class: " + resource);}}}else {if (traceEnabled) {logger.trace("Ignored because not matching any filter: " + resource);}}}catch (FileNotFoundException ex) {if (traceEnabled) {logger.trace("Ignored non-readable " + resource + ": " + ex.getMessage());}}catch (Throwable ex) {throw new BeanDefinitionStoreException("Failed to read candidate component class: " + resource, ex);}}}catch (IOException ex) {throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);}return candidates;}

相关文章:

【Spring生命周期核心底层源码之剖析】

文章目录 一、Spring生命周期核心底层源码剖析—扫描1.1、Spring底层扫描机制doScan方法源码剖析 一、Spring生命周期核心底层源码剖析—扫描 1.1、Spring底层扫描机制doScan方法源码剖析 其源代码如下&#xff1a; protected Set<BeanDefinitionHolder> doScan(Strin…...

关于Thread.sleep方法的一些使用

Thread.sleep方法的作用就是使当前线程暂停执行一段指定的时间。 它的参数是以ms为单位的时间参数&#xff0c;表示暂停时间长度。如Thread.sleep(1000);表示暂停1s。 这个方法通常用在以下一些情况&#xff1a; 1、模拟延迟&#xff1a;在某些情况下&#xff0c;我们希望在…...

MeterSphere | 前端入参加密

项目场景&#xff1a; 在 MeterSphere 开源框架中&#xff0c;解决前端手机号入参加密 解决方案&#xff1a; 导入 JavaScript 包采用加密算法 导入网上 JavaScript 包 // 1. 通过cdn加载网上的js文件 g new Packages.org.mozilla.javascript.tools.shell.Global(Packages.o…...

微服务如何做负载均衡?

笔者在参与联通某子公司时&#xff0c;遇到了这样一个问题。感觉比较实际&#xff0c;特来记录一波。 先看腾讯混元的解答&#xff1a; 微服务架构中&#xff0c;负载均衡是必不可少的。在微服务中&#xff0c;负载均衡可以通过以下几种方式来实现&#xff1a; 1. DNS轮询&am…...

C++高级编程:构建高效稳定接口与深入对象设计技巧

C高级编程&#xff1a;构建高效稳定接口与深入对象设计技巧 建立稳定接口 类是C中的主要抽象单位。你应该将抽象原则应用于你的类&#xff0c;尽可能将接口与实现分离。具体来说&#xff0c;你应该使所有数据成员私有&#xff0c;并可选择性地提供getter和setter方法。这就是…...

Qt——连接mysql增删查改(仓库管理极简版)

目录 UI布局设计 .pro文件 mainwindow.h main.cpp UI布局设计 .pro文件 QT core gui QT core gui sql QT sqlgreaterThan(QT_MAJOR_VERSION, 4): QT widgetsCONFIG c11# The following define makes your compiler emit warnings if you use # any …...

Panda3d 场景管理

Panda3d 场景管理 文章目录 Panda3d 场景管理有关分层场景图的重要信息NodePathNodePath 以及 Node 的函数调用模型文件文件格式加载模型文件将模型放置在场景图中模型缓存压缩模型异步加载模型通过回调函数进行 常见的状态变化修改节点的位置和姿态改变父级节点改变颜色隐藏和…...

京东数据分析(京东销量):2023年9月京东投影机行业品牌销售排行榜

鲸参谋监测的京东平台9月份投影机市场销售数据已出炉&#xff01; 根据鲸参谋电商数据分析平台的相关数据数据显示&#xff0c;9月份&#xff0c;京东平台投影机的销量为13万&#xff0c;环比下滑约17%&#xff0c;同比下滑约25%&#xff1b;销售额将近2.6亿&#xff0c;环比下…...

uniapp cli化一键游项目启动报错总结

问题1、使用hbuilder运行指令&#xff0c;开始编译后没有反应&#xff0c;使用命令构建自行结束进程 解决&#xff1a;因为使用了node16.24&#xff0c;卸载重新安装14.17后解决 问题2、 21:31:11.483 Module build failed (from ./node_modules/vue/cli-service/node_module…...

我的月光宝盒初体验失败了

哈哈哈&#xff0c;我爱docker, docker 使我自由&#xff01;&#xff01;&#xff01; docker make me free! 菠萝菠萝蜜口号喊起来。 https://github.com/vivo/MoonBox/ windows上安装好了docker之后&#xff0c;docker-compose是自带的。 docker-compose -f docker-compo…...

vue3+vite搭建后台项目-1 引入element-plus 中文包,打包时报错问题

vue3vite搭建后台项目-1 引入element-plus 中文包,打包时报错问题 终端报错 If theelement-pluspackage actually exposes this module, try adding a new declaration (.d.ts) file containing are moduleelement-plus/dist/locale/zh-cn.mjsdec import zhCn fromelement-plus…...

带你详细了解git的【分支和标签】

&#x1f3c5;我是默&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; ​​​ &#x1f31f;在这里&#xff0c;我要推荐给大家我的专栏《git》。&#x1f3af;&#x1f3af; &#x1f680;无论你是编程小白&#xff0c;还是有一定基础的程序员&#xff0c;…...

分类预测 | Matlab实现PSO-LSTM粒子群算法优化长短期记忆神经网络的数据多输入分类预测

分类预测 | Matlab实现PSO-LSTM粒子群算法优化长短期记忆神经网络的数据多输入分类预测 目录 分类预测 | Matlab实现PSO-LSTM粒子群算法优化长短期记忆神经网络的数据多输入分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.Matlab实现PSO-LSTM粒子群算法优化长短…...

Spring 事务失效的场景

1.直接new出来的对象添加事务不起作用&#xff0c;因为只有spring定义的bean才接受事务。 2.由于mysql的引擎用Myisam不支持事务&#xff0c;所以如果使用mysql的myisam引擎的话&#xff0c;事务不起作用。 3.如果Transaction注解到非public方法上&#xff0c;事务不起作用&…...

酷柚易汛ERP-自定义打印整体介绍

1、产品介绍 每种单据系统预设常用模板&#xff0c;提供A4纸张、三等分、二等分&#xff0c;销货单额外提供80mm、58mm供用户选择&#xff1b;每张单据可设置一个默认模板和多个常用模&#xff1b;除默认模板外&#xff0c;其他模板都允许删除&#xff0c;用户可以根据公司业务…...

activiti命令模式与责任链模式

来源&#xff1a;activiti学习&#xff08;七&#xff09;——命令模式和职责链模式在activiti中的应用 文章目录 设计模式命令模式CommandHelloCommandByeCommand ReceiverInvokerClient 职责链模式AbstractHandlerConcreteHandlerAConcreateHandlerB Client activiti中很多ap…...

C++20 Text formatting

C20 Text formatting 格式化字符串&#xff0c; 和 python 类似。 std::formatter - cppreference.com string — Common string operations — Python 3.12.0 documentation 新格式库位于 <format> 头文件中。格式库基于 Python3 中的 str.format() 方法建模。格式…...

redis-plus-plus--github中文翻译--2

12 能不能举个例子 当然可以。以下是一个具体的例子,说明如何使用cmake命令为redis-plus-plus配置编译和安装路径: 假设: hiredis 被安装在 /opt/libs/hiredis你想要将 redis-plus-plus 安装到 /opt/libs/redis-plus-plus那么,你可以使用以下的 cmake 命令: cmake -DCM…...

Vuex状态管理:Getters :VOA模式

简介&#xff1a; Getters 用于对 Store 中的数据进行加工处理形成新的数据。 Getters 可以对 Store 中已有的数据加工处理之后形成新的数据&#xff0c;类似 Vue 的计算属性。 Store 中数据发生变化&#xff0c;Getters 的数据也会跟着变化。 案列 /src/store/index.js状态…...

二十三种设计模式全面解析-享元模式(Flyweight Pattern)详解:构建高效共享的对象结构

在软件开发中&#xff0c;我们经常会面临大量相似对象的创建和管理问题。这些相似对象的创建和销毁过程可能会占用大量的内存和系统资源&#xff0c;导致性能下降。为了解决这个问题&#xff0c;享元模式&#xff08;Flyweight Pattern&#xff09;应运而生。本文将深入探讨享元…...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程&#xff1a;&#xff08;白话解释&#xff09; 我们将原始待发送的消息称为 M M M&#xff0c;依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)&#xff08;意思就是 G &#xff08; x ) G&#xff08;x) G&#xff08;x) 是已知的&#xff09;&#xff0…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 &#xff08;FL&#xff09; 支持跨分布式客户端进行协作模型训练&#xff0c;而无需共享原始数据&#xff0c;这使其成为在互联和自动驾驶汽车 &#xff08;CAV&#xff09; 等领域保护隐私的机器学习的一种很有前途的方法。然而&#xff0c;最近的研究表明&…...

React Native在HarmonyOS 5.0阅读类应用开发中的实践

一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强&#xff0c;React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 &#xff08;1&#xff09;使用React Native…...

什么是库存周转?如何用进销存系统提高库存周转率?

你可能听说过这样一句话&#xff1a; “利润不是赚出来的&#xff0c;是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业&#xff0c;很多企业看着销售不错&#xff0c;账上却没钱、利润也不见了&#xff0c;一翻库存才发现&#xff1a; 一堆卖不动的旧货…...

oracle与MySQL数据库之间数据同步的技术要点

Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异&#xff0c;它们的数据同步要求既要保持数据的准确性和一致性&#xff0c;又要处理好性能问题。以下是一些主要的技术要点&#xff1a; 数据结构差异 数据类型差异&#xff…...

AI病理诊断七剑下天山,医疗未来触手可及

一、病理诊断困局&#xff1a;刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断"&#xff0c;医生需通过显微镜观察组织切片&#xff0c;在细胞迷宫中捕捉癌变信号。某省病理质控报告显示&#xff0c;基层医院误诊率达12%-15%&#xff0c;专家会诊…...

人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式

今天是关于AI如何在教学中增强学生的学习体验&#xff0c;我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育&#xff0c;这并非炒作&#xff0c;而是已经发生的巨大变革。教育机构和教育者不能忽视它&#xff0c;试图简单地禁止学生使…...

搭建DNS域名解析服务器(正向解析资源文件)

正向解析资源文件 1&#xff09;准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2&#xff09;服务端安装软件&#xff1a;bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...

华为OD机试-最短木板长度-二分法(A卷,100分)

此题是一个最大化最小值的典型例题&#xff0c; 因为搜索范围是有界的&#xff0c;上界最大木板长度补充的全部木料长度&#xff0c;下界最小木板长度&#xff1b; 即left0,right10^6; 我们可以设置一个候选值x(mid)&#xff0c;将木板的长度全部都补充到x&#xff0c;如果成功…...

【堆垛策略】设计方法

堆垛策略的设计是积木堆叠系统的核心&#xff0c;直接影响堆叠的稳定性、效率和容错能力。以下是分层次的堆垛策略设计方法&#xff0c;涵盖基础规则、优化算法和容错机制&#xff1a; 1. 基础堆垛规则 (1) 物理稳定性优先 重心原则&#xff1a; 大尺寸/重量积木在下&#xf…...