SpringBoot源码-spring boot启动入口ruan方法主线分析(二)

ops/2024/12/4 18:58:33/

12.刷新前操作

java"> // 刷新前操作prepareContext(context, environment, listeners, applicationArguments, printedBanner);

进入prepareContext

java">private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {context.setEnvironment(environment);postProcessApplicationContext(context);applyInitializers(context);listeners.contextPrepared(context);if (this.logStartupInfo) {logStartupInfo(context.getParent() == null);logStartupProfileInfo(context);}// Add boot specific singleton beansConfigurableListableBeanFactory beanFactory = context.getBeanFactory();beanFactory.registerSingleton("springApplicationArguments", applicationArguments);if (printedBanner != null) {beanFactory.registerSingleton("springBootBanner", printedBanner);}if (beanFactory instanceof DefaultListableBeanFactory) {((DefaultListableBeanFactory) beanFactory).setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);}if (this.lazyInitialization) {context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());}// Load the sourcesSet<Object> sources = getAllSources();Assert.notEmpty(sources, "Sources must not be empty");load(context, sources.toArray(new Object[0]));listeners.contextLoaded(context);}
***applyInitializers(context);实现细节如下***:
	protected void applyInitializers(ConfigurableApplicationContext context) {for (ApplicationContextInitializer initializer : getInitializers()) {Class<?> requiredType = GenericTypeResolver.resolveTypeArgument(initializer.getClass(),ApplicationContextInitializer.class);Assert.isInstanceOf(requiredType, context, "Unable to call initializer.");initializer.initialize(context);}}

getInitializers获取的就是SpringApplication构造函数里的这7个,然后循环调用initialize方法。

org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener# Application Context Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\
org.springframework.boot.context.ContextIdApplicationContextInitializer,\
org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\
org.springframework.boot.rsocket.context.RSocketPortInfoApplicationContextInitializer,\
org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer

七个ApplicationContextInitializer执行完毕之后,增加了两个bfpp,三个listeners
SharedMetadataReaderFactoryContextInitializer:

java">	@Overridepublic void initialize(ConfigurableApplicationContext applicationContext) {applicationContext.addBeanFactoryPostProcessor(new CachingMetadataReaderFactoryPostProcessor());}

ConfigurationWarningsApplicationContextInitializer:

java">	@Overridepublic void initialize(ConfigurableApplicationContext context) {context.addBeanFactoryPostProcessor(new ConfigurationWarningsPostProcessor(getChecks()));}

RSocketPortInfoApplicationContextInitializer:

java">	@Overridepublic void initialize(ConfigurableApplicationContext applicationContext) {applicationContext.addApplicationListener(new Listener(applicationContext));}

ServerPortInfoApplicationContextInitializer:

java">	@Overridepublic void initialize(ConfigurableApplicationContext applicationContext) {applicationContext.addApplicationListener(this);}

ConditionEvaluationReportLoggingListener:

java">	@Overridepublic void initialize(ConfigurableApplicationContext applicationContext) {this.applicationContext = applicationContext;applicationContext.addApplicationListener(new ConditionEvaluationReportListener());if (applicationContext instanceof GenericApplicationContext) {// Get the report early in case the context fails to loadthis.report = ConditionEvaluationReport.get(this.applicationContext.getBeanFactory());}}

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
七个ApplicationContextInitializer执行完毕之后,增加了两个bfpp,三个listeners。

listeners.contextPrepared(context);发布事件通知
EventPublishingRunListener类的contextPrepared方法,发布的是ApplicationContextInitializedEvent事件,会有对应的监听器执行

java">	@Overridepublic void contextPrepared(ConfigurableApplicationContext context) {this.initialMulticaster.multicastEvent(new ApplicationContextInitializedEvent(this.application, this.args, context));}

打印启动日志输出:

java">logStarting:56, StartupInfoLogger (org.springframework.boot)
logStartupInfo:637, SpringApplication (org.springframework.boot)
prepareContext:373, SpringApplication (org.springframework.boot)
run:314, SpringApplication (org.springframework.boot)
run:1226, SpringApplication (org.springframework.boot)
run:1215, SpringApplication (org.springframework.boot)
main:18, SpringbootWebApplication (com.mashibing)
java">	private CharSequence getStartingMessage() {StringBuilder message = new StringBuilder();message.append("Starting ");appendApplicationName(message);appendVersion(message, this.sourceClass);appendOn(message);appendPid(message);appendContext(message);return message;}

在这里插入图片描述

load(context, sources.toArray(new Object[0]));
load方法有自动装配的核心点
在这里插入图片描述

java">load:151, BeanDefinitionLoader (org.springframework.boot)
load:136, BeanDefinitionLoader (org.springframework.boot)
load:128, BeanDefinitionLoader (org.springframework.boot)
load:691, SpringApplication (org.springframework.boot)
prepareContext:392, SpringApplication (org.springframework.boot)
run:314, SpringApplication (org.springframework.boot)
run:1226, SpringApplication (org.springframework.boot)
run:1215, SpringApplication (org.springframework.boot)
main:20, SpringbootWebApplication (com.mashibing)

匹配启动类上是否有@Component注解

java">	private boolean isComponent(Class<?> type) {// This has to be a bit of a guess. The only way to be sure that this type is// eligible is to make a bean definition out of it and try to instantiate it.if (MergedAnnotations.from(type, SearchStrategy.TYPE_HIERARCHY).isPresent(Component.class)) {return true;}// Nested anonymous classes are not eligible for registration, nor are groovy// closuresreturn !type.getName().matches(".*\\$_.*closure.*") && !type.isAnonymousClass()&& type.getConstructors() != null && type.getConstructors().length != 0;}

@SpringBootApplication注解的继承图如下:
在这里插入图片描述
然后开始下面的注册流程:
在这里插入图片描述

执行当前启动类:
在这里插入图片描述
当前springboot项目的启动类注册bean定义信息给beanfactory,后续交给spring管理生命周期,并且执行bfpp的自动装配扫描包等操作
在这里插入图片描述
至此,项目启动类注册bean定义信息成功。
load(context, sources.toArray(new Object[0]));执行结束之后,执行listeners.contextLoaded(context);方法

java">addBeanFactoryPostProcessor:488, AbstractApplicationContext (org.springframework.context.support)
addPostProcessors:222, ConfigFileApplicationListener (org.springframework.boot.context.config)
onApplicationPreparedEvent:203, ConfigFileApplicationListener (org.springframework.boot.context.config)
onApplicationEvent:179, ConfigFileApplicationListener (org.springframework.boot.context.config)
doInvokeListener:172, SimpleApplicationEventMulticaster (org.springframework.context.event)
invokeListener:165, SimpleApplicationEventMulticaster (org.springframework.context.event)
multicastEvent:139, SimpleApplicationEventMulticaster (org.springframework.context.event)
multicastEvent:127, SimpleApplicationEventMulticaster (org.springframework.context.event)
contextLoaded:93, EventPublishingRunListener (org.springframework.boot.context.event)
contextLoaded:65, SpringApplicationRunListeners (org.springframework.boot)
prepareContext:393, SpringApplication (org.springframework.boot)
run:314, SpringApplication (org.springframework.boot)
run:1226, SpringApplication (org.springframework.boot)
run:1215, SpringApplication (org.springframework.boot)
main:20, SpringbootWebApplication (com.mashibing)

在这里插入图片描述
再添加一个BFPP现在加上上面添加的两个 现在有三个了。

打印结束日志

2024-11-06 17:08:18.350  INFO 79556 --- [           main] com.mashibing.SpringbootWebApplication   : Started SpringbootWebApplication in 1768.089 seconds (JVM running for 1792.346)

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

13.刷新应用上下文 完成Spring容器的初始化
refreshContext(context);
Spring源码-ConfigurationClassPostProcessor类解析spring相关注解以及springboot自动装配原理(必会)
refreshContext这个方法实现了spring容器的创建,其中包含了容器内对象的实例化、初始化、属性填充。以及SpringBoot的自动装配原理,这个方法在之前的Spring源码中有详细解读,请移步Spring源码详解
这里还完成了SpringBoot内嵌Tomcat的初始化过程SpringBoot源码-SpringBoot内嵌Tomcat原理

14.刷新后操作

java">afterRefresh(context, applicationArguments);
java">	/*** Called after the context has been refreshed.* @param context the application context* @param args the application arguments*/protected void afterRefresh(ConfigurableApplicationContext context, ApplicationArguments args) {}

15.结束记录启动时间
stopWatch.stop();

java">	/*** Stop the current task.* <p>The results are undefined if timing methods are called without invoking* at least one pair of {@code start()} / {@code stop()} methods.* @see #start()* @see #start(String)*/public void stop() throws IllegalStateException {if (this.currentTaskName == null) {throw new IllegalStateException("Can't stop StopWatch: it's not running");}long lastTime = System.nanoTime() - this.startTimeNanos;this.totalTimeNanos += lastTime;this.lastTaskInfo = new TaskInfo(this.currentTaskName, lastTime);if (this.keepTaskList) {this.taskList.add(this.lastTaskInfo);}++this.taskCount;this.currentTaskName = null;}

http://www.ppmy.cn/ops/139067.html

相关文章

【机器学习】探索机器学习决策树算法的奥秘

决策树 前言基本概念常见的决策树算法ID3算法C4.5算法CART算法 决策树的优缺点应用场景决策树的可视化总结 前言 在当今这个数据驱动的时代&#xff0c;机器学习作为数据分析与预测的利器&#xff0c;正以前所未有的速度改变着我们的生活和工作方式。在众多机器学习算法中&…

redis 从16db块 加到32db块

在 Redis 中&#xff0c;数据库的数量和编号是由配置文件中的 databases 参数决定的。默认情况下&#xff0c;Redis 支持 16 个数据库&#xff0c;编号从 0 到 15。然而&#xff0c;有些 Redis 实例可能会配置为支持更多的数据库&#xff0c;例如 15、16、17 等。 原因分析 配…

HTMLCSS 创意工坊:卡片网格的鼠标魔法秀

这个HTML页面展示了一个包含SVG图标和文本的卡片网格。鼠标移入旋转放大的效果 演示效果 HTML&CSS <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevi…

动态规划-----路径问题

动态规划-----路径问题 下降最小路径和1&#xff1a;状态表示2&#xff1a;状态转移方程3 初始化4 填表顺序5 返回值6 代码实现 总结&#xff1a; 下降最小路径和 1&#xff1a;状态表示 假设&#xff1a;用dp[i][j]表示&#xff1a;到达[i,j]的最小路径 2&#xff1a;状态转…

2024下半年——【寒假】自学黑客计划(网络安全)

CSDN大礼包&#xff1a;&#x1f449;基于入门网络安全/黑客打造的&#xff1a;&#x1f449;黑客&网络安全入门&进阶学习资源包 前言 什么是网络安全 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&a…

【AI系统】昇腾异构计算架构 CANN

昇腾异构计算架构 CANN 本文将介绍昇腾 AI 异构计算架构 CANN&#xff08;Compute Architecture for Neural Networks&#xff09;&#xff0c;这是一套为高性能神经网络计算需求专门设计和优化的架构。CANN 包括硬件层面的达芬奇架构和软件层面的全栈支持&#xff0c;旨在提供…

MySQL 主从同步一致性详解

MySQL主从同步是一种数据复制技术&#xff0c;它允许数据从一个数据库服务器&#xff08;主服务器&#xff09;自动同步到一个或多个数据库服务器&#xff08;从服务器&#xff09;。这种技术主要用于实现读写分离、提升数据库性能、容灾恢复以及数据冗余备份等目的。下面将详细…

数据结构与算法——N叉树(自学笔记)

本文参考 N 叉树 - LeetBook - 力扣&#xff08;LeetCode&#xff09;全球极客挚爱的技术成长平台 遍历 前序遍历&#xff1a;A->B->C->E->F->D->G后序遍历&#xff1a;B->E->F->C->G->D->A层序遍历&#xff1a;A->B->C->D->…