Springboot 启动Bean如何被加载

1.启动类

SpringApplication.run(TianMaoApplication.class, args);
    public ConfigurableApplicationContext run(String... args) {long startTime = System.nanoTime();DefaultBootstrapContext bootstrapContext = this.createBootstrapContext();ConfigurableApplicationContext context = null;this.configureHeadlessProperty();SpringApplicationRunListeners listeners = this.getRunListeners(args);listeners.starting(bootstrapContext, this.mainApplicationClass);try {ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);ConfigurableEnvironment environment = this.prepareEnvironment(listeners, bootstrapContext, applicationArguments);this.configureIgnoreBeanInfo(environment);Banner printedBanner = this.printBanner(environment);context = this.createApplicationContext();context.setApplicationStartup(this.applicationStartup);this.prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);this.refreshContext(context);this.afterRefresh(context, applicationArguments);Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);if (this.logStartupInfo) {(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), timeTakenToStartup);}listeners.started(context, timeTakenToStartup);this.callRunners(context, applicationArguments);} catch (Throwable var12) {this.handleRunFailure(context, var12, listeners);throw new IllegalStateException(var12);}try {Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);listeners.ready(context, timeTakenToReady);return context;} catch (Throwable var11) {this.handleRunFailure(context, var11, (SpringApplicationRunListeners)null);throw new IllegalStateException(var11);}}
context = this.createApplicationContext(); 创建ApplicationContent

然后执行refresh() 这个很重要

 public void refresh() throws BeansException, IllegalStateException {synchronized(this.startupShutdownMonitor) {StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");this.prepareRefresh();ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();this.prepareBeanFactory(beanFactory);try {//会调用后置处理 去扫包 注册 获取Bean定义this.postProcessBeanFactory(beanFactory);StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");this.invokeBeanFactoryPostProcessors(beanFactory);this.registerBeanPostProcessors(beanFactory);beanPostProcess.end();this.initMessageSource();this.initApplicationEventMulticaster();this.onRefresh();this.registerListeners();this.finishBeanFactoryInitialization(beanFactory);this.finishRefresh();} catch (BeansException var10) {if (this.logger.isWarnEnabled()) {this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var10);}this.destroyBeans();this.cancelRefresh(var10);throw var10;} finally {this.resetCommonCaches();contextRefresh.end();}}}

run 的时候会执行 服务端口的读取,打印banner 等操作

@FunctionalInterface
public interface ApplicationContextFactory {ApplicationContextFactory DEFAULT = (webApplicationType) -> {try {switch(webApplicationType) {case SERVLET:return new AnnotationConfigServletWebServerApplicationContext();case REACTIVE:return new AnnotationConfigReactiveWebServerApplicationContext();default:return new AnnotationConfigApplicationContext();}} catch (Exception var2) {throw new IllegalStateException("Unable create a default ApplicationContext instance, you may need a custom ApplicationContextFactory", var2);}};ConfigurableApplicationContext create(WebApplicationType webApplicationType);static ApplicationContextFactory ofContextClass(Class<? extends ConfigurableApplicationContext> contextClass) {return of(() -> {return (ConfigurableApplicationContext)BeanUtils.instantiateClass(contextClass);});}static ApplicationContextFactory of(Supplier<ConfigurableApplicationContext> supplier) {return (webApplicationType) -> {return (ConfigurableApplicationContext)supplier.get();};}
}

这面是创建了AnnotationConfigServletWebServerApplicationContext

这面要说下 AnnotationConfigServletWebServerApplicationContext 

private final AnnotatedBeanDefinitionReader reader;
private final ClassPathBeanDefinitionScanner scanner;

定义了这两个,如run 代码所示 refresh 时候调用这个初始化之后会执行后置处理

 protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {super.postProcessBeanFactory(beanFactory);if (this.basePackages != null && this.basePackages.length > 0) {this.scanner.scan(this.basePackages);}if (!this.annotatedClasses.isEmpty()) {this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));}}

scanner 会先扫包 看如下的代码注释

    protected Set<BeanDefinitionHolder> doScan(String... basePackages) {Assert.notEmpty(basePackages, "At least one base package must be specified");Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet();String[] var3 = basePackages;int var4 = basePackages.length;for(int var5 = 0; var5 < var4; ++var5) {String basePackage = var3[var5];Set<BeanDefinition> candidates = this.findCandidateComponents(basePackage);Iterator var8 = candidates.iterator();while(var8.hasNext()) {//先去获取bean的定义BeanDefinition candidate = (BeanDefinition)var8.next();ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);candidate.setScope(scopeMetadata.getScopeName());//生成beanNameString beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);//执行bean定义的后置操作if (candidate instanceof AbstractBeanDefinition) {this.postProcessBeanDefinition((AbstractBeanDefinition)candidate, beanName);}//@Bean 的读取if (candidate instanceof AnnotatedBeanDefinition) {AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition)candidate);}if (this.checkCandidate(beanName, candidate)) {BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);//如果是scope 是target_class 需要注册一个代理进去 用来以后创建新对象definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);beanDefinitions.add(definitionHolder);this.registerBeanDefinition(definitionHolder, this.registry);}}}return beanDefinitions;}

reader 去注册包

 private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name, @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier, @Nullable BeanDefinitionCustomizer[] customizers) {AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);if (!this.conditionEvaluator.shouldSkip(abd.getMetadata())) {abd.setInstanceSupplier(supplier);ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);abd.setScope(scopeMetadata.getScopeName());String beanName = name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry);AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);int var10;int var11;if (qualifiers != null) {Class[] var9 = qualifiers;var10 = qualifiers.length;//设置primary 设置懒加载 设置 Qualifierfor(var11 = 0; var11 < var10; ++var11) {Class<? extends Annotation> qualifier = var9[var11];if (Primary.class == qualifier) {abd.setPrimary(true);} else if (Lazy.class == qualifier) {abd.setLazyInit(true);} else {abd.addQualifier(new AutowireCandidateQualifier(qualifier));}}}if (customizers != null) {BeanDefinitionCustomizer[] var13 = customizers;var10 = customizers.length;for(var11 = 0; var11 < var10; ++var11) {BeanDefinitionCustomizer customizer = var13[var11];customizer.customize(abd);}}BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);//去设置别名等操作 最后的所有bean都会被放到一个set集合BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);}}

所有的bean 都会被放到 

AnnotationConfigServletWebServerApplicationContext
private final Set<Class<?>> annotatedClasses; (应该吧什么时候初始化还没看到来)

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

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

相关文章

IP地理位置定位技术:保护网络安全的新利器

随着互联网的普及和网络活动的日益频繁&#xff0c;网络安全问题越来越受到人们的关注。恶意流量攻击、网络欺诈等网络安全威胁层出不穷&#xff0c;如何准确识别和定位网络攻击者成为一项重要任务。在这个背景下&#xff0c;IP地理位置定位技术应运而生&#xff0c;为网络安全…

OpenHarmony Ohpm安装历程(个人踩坑,最后安装成功)

大家好&#xff0c;我是【八戒&#xff0c;你又涨价了哎】 以下是我个人在学习OpenHarmony过程中的分享&#xff0c;请大家多多指教 目录 问题描述&#xff1a; 尝试解决 尝试一、 尝试二、 尝试三、 最终解决方案 问题描述&#xff1a; 当我学习到使用OpenHarmony的三方…

2005B 2.4W AB类音频功率放大器应用领域

2005B 2.4W AB类音频功率放大器应用领域&#xff1a;1、便携式DVD&#xff1b;2、笔记本电脑&#xff1b;3、插卡音箱 / USB音箱&#xff1b;4、液晶电视 / 液晶显示器等等。 2005B是一颗单通道AB类音频功率放大器。在5V 电源供电&#xff0c;THDN10%&#xff0c;4欧姆负载上可…

SQLite 安装和 Java 使用教程

SQLite是一个C语言库&#xff0c;它实现了一个小型、快速、自包含、高可靠性、功能齐全的SQL数据库引擎。SQLite是世界上使用最多的数据库引擎。SQLite内置于所有手机和大多数计算机中&#xff0c;并捆绑在人们每天使用的无数其他应用程序中。 SQLite文件格式稳定、跨平台、向…

免疫微环境、免疫细胞浸润分析、免疫功能分析

Immune MicroEnvironment、Immune infiltration analysis 01.肿瘤免疫微环境&#xff08;TIME&#xff09;02.TIME的免疫特点和相关机制03.检测免疫浸润的工具3.1.基于marker gene的ssGSEA富集分析的免疫分析方法3.1.1.xCELL3.1.2.MCP-counter3.1.3.ESTIMATE3.1.4.3.1.5.ssGSEA…

在Linux系统中创建虚拟串口

在Linux系统中创建虚拟串口 文章目录 在Linux系统中创建虚拟串口1、虚拟串口介绍2、使用 socat创建虚拟串行端口2.1 安装socat2.2 创建简单的虚拟串口2.3 创建指定波特率的串行端口 有多种方法可以在 Linux 中创建虚拟串口来测试和调试串行通信协议。 在本文中&#xff0c;我们…

基于饥饿游戏算法优化概率神经网络PNN的分类预测 - 附代码

基于饥饿游戏算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于饥饿游戏算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于饥饿游戏优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神…

代码随想录二刷 | 链表 | 基础知识

代码随想录二刷 &#xff5c; 链表&#xff5c; 基础知识 链表链表的类型单链表双链表循环链表 链表的存储方式链表的定义链表的操作删除节点增加节点 性能分析 链表 链表是一种通过指针串联在一起的线性结构&#xff0c;每一个节点由两部分组成&#xff0c;一个是数据域一个是…

<MySQL> 如何合理的设计数据库中的表?数据表设计的三种关系

目录 一、表的设计 二、一对一关系 三、一对多关系 四、多对多关系 一、表的设计 数据库设计就是根据需要创建出符合需求的表。 首先根据需求找到体系中的关键实体对象&#xff0c;通常每个实体对象都会有一个表&#xff0c;表中包含了这个实体的相关属性。 再理清楚实体对…

数据结构【DS】树与二叉树的应用

哈夫曼树 树的带权路径长度最小的二叉树WPL 路径长度【边数】 * 结点权值n个叶结点的哈夫曼树共有 2n-1 个结点 哈夫曼树的任意非叶结点的左右子树交换后仍是哈夫曼树对同一组权值&#xff0c;可能存在不同构的多棵哈夫曼树&#xff0c;但树的带权路径长度最小且唯一哈夫曼树…

Java贪吃蛇小游戏

Java贪吃蛇小游戏 import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.LinkedList; import java.util.Random;publi…

C语言——操作符详解

前言&#xff1a;这篇文章主要讲解一下C语言中常见的操作符的使用&#xff0c;做一下整理&#xff0c;便于日后回顾&#xff0c;同时也希望能帮助到大家。 &#x1f3ac;个人简介&#xff1a;努力学习ing &#x1f4dd;CSDN主页 愚润求学 &#x1f304;每日鸡汤&#xff1a;念…

大数据的技术运用:探索未来的无限可能性

随着科技的不断进步和社会信息的快速增长&#xff0c;大数据已成为一个热门话题。本文将探讨大数据技术在多个领域的应用&#xff0c;以及它对未来的影响和无限可能性。 导言 在过去的几十年里&#xff0c;大数据技术取得了惊人的发展&#xff0c;它不仅改变了企业的经营方式&a…

大模型LLM 在线量化;GPTQ\AWQ量化

1、大模型LLM 在线量化 参考:https://www.cnblogs.com/bruceleely/p/17348782.html ##8bit model = AutoModel.from_pretrained("THUDM/chatglm-6b", trust_remote_code=True).quantize(8).half(

开源与闭源:数字化时代的创新与合作之争

引言&#xff1a; 在数字化时代&#xff0c;开源与闭源软件的辩论一直是技术界的热门话题。特斯拉CEO马斯克最近公开表示&#xff0c;OpenAI不应该闭源&#xff0c;而自家首款聊天机器人将开源。这一表态引发了广泛的讨论和思考。本文将从不同角度探讨开源与闭源软件的优势与劣…

odoo17 web.assets_web.min.js 赏析

odoo17 web.assets_web.min.js 赏析 前文说到&#xff0c;odoo17的前端js做了大量裁剪优化&#xff0c;最终打包成了一个文件assets.web.js 稍微看一下这个文件的结构 web.assets_web.min.js 行 1: /* /web/static/src/module_loader.js */ 行 173: /* /web/static/…

数据中心标签的重要性

布线标签的实施是为了为用户今后的维护和管理带来最大的 便利&#xff0c;提高其管理水平和工作效率&#xff0c;减少网络配置时间&#xff0c;标签标识系统包括三个方面:标识分类及定义,标签和建立文档。 标签、标识的分类有哪些? 数据中心内的每一电缆、光缆、配线设备、端…

解决网络编程中的EOF违反协议问题:requests库与SSL错误案例分析

1. 问题背景 近期&#xff0c;一个用户在使用requests库进行网络编程时遭遇到了一个不寻常的问题&#xff0c;涉及SSL错误&#xff0c;并提示错误消息为SSLError(SSLEOFError(8, uEOF occurred in violation of protocol (_ssl.c:661)),))。该用户表示已经采取了多种方法来解决…

109.firefly-extboot的生成脚本

内核版本&#xff1a; 4.4.194 在firefly的sdk 2.5.1c及以后的版本都是extboot.img&#xff08;对应表中的extboot&#xff09; 但是之前的并不是&#xff0c;而且一个boot.img&#xff0c;&#xff08;对应表中rkboot&#xff09; rkboot的生成方法可以参考解决linux5.15编…

【数据机构】最小生成树(prim算法)

一.引例 在n个城市之间建设通信网络&#xff0c;至少需要架设多少条通信线路&#xff1f;如果每两个城市之间架设通信线路的造价是不一样的&#xff0c;那么如何设计才能使得总造价最小&#xff1f; 二.生成树与生成森林 生成树&#xff1a;n个顶点的连通图G的生成树是包含G中…