Spring Boot 框架整体启动流程详解

news2024/12/25 9:28:18

基于Spring Boot 版本:3.1
Java: 17

Spring Boot 的入口即为xxApplication类的main方法:

@SpringBootApplication
public class SpringBootDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootDemoApplication.class);
    }

}

main方法内部再调用SpringApplication.run(SpringBootDemoApplication.class);

SpringApplication.java ---- run 有两个重载方法:

	/**
	 * 静态方法,使用默认设置从指定的源启动SpringApplication
	 * @param primarySource 载入的指定源
	 * @param args 应用程序参数 (通过从Main方法传递)
	 * @return 正在运行的ApplicationContext
	 */
	public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
		return run(new Class<?>[] { primarySource }, args);
	}

	/**
	 * 静态方法,使用默认设置从指定的源启动SpringApplication
	 * @param primarySources 载入的制定源,数组形式
	 * @param args 应用程序参数 (通过从Main方法传递),数组形式
	 * @return 正在运行的ApplicationContext
	 */
	public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
		return new SpringApplication(primarySources).run(args);
	}

应用程序初始化

经过两次调用run静态方法后,调用new SpringApplication(primarySources).run(args)
首先new SpringApplication,调用链路如图
在这里插入图片描述
该处理的作用有:
1、创建一个SpringApplication实例,根据指定的源primarySources加载实例bean
2、将资源加载器类赋值给实例变量(此处为null)
3、将primarySources转为list并去重后赋值给实例变量
4、推断当前的Web应用程序环境(Reactive还是Servlet)
5、从META-INF/spring.factories加载BootstrapRegistryInitializer类实例
6、从META-INF/spring.factories加载ApplicationContextInitializer类实例
7、从META-INF/spring.factories加载ApplicationListener类实例
8、从堆栈中推断出主应用程序类

  • BootstrapRegistryInitializer:该接口的作用是将一些默认的组件注册到BootstrapRegistry中,这些组件可以帮助Spring Boot实现自动配置和依赖注入等功能。通过实现BootstrapRegistryInitializer接口,开发人员可以向Spring Boot添加自定义组件,并在应用程序启动阶段进行初始化和注册,从而实现更具有个性化的应用程序配置和功能。
  • ApplicationContextInitializer:该接口提供了一种灵活的机制,允许您在应用程序上下文创建之前自定义应用程序上下文的行为。该接口的实现类可以在应用程序上下文创建之前注册到SpringApplication实例中,并在应用程序上下文创建之前执行一些初始化操作,例如覆盖应用程序上下文中的默认bean定义、添加自定义属性源、激活特定的Spring配置文件等。通过实现该接口,可以实现一些在应用程序启动之前需要做的预处理操作,例如加载一些外部配置、初始化日志等。这样可以提高应用的灵活性和可配置性,使应用程序更加适应不同的环境和需求。建议实现Ordered接口,或者使用@Order注解
  • ApplicationListener:该接口的实现类可以在Spring Boot应用程序中注册到ApplicationContext中,以便在应用程序生命周期内接收和处理特定的应用程序事件,例如启动、关闭、失败等事件。
    通过实现该接口,可以在应用程序启动、关闭、失败等关键时刻进行一些自定义操作,例如初始化某些资源、注册特定的Bean、记录日志等。常见的Spring Boot应用程序事件包括ApplicationStartingEvent、ApplicationStartedEvent、ApplicationReadyEvent、ApplicationFailedEvent等。

应用程序启动

new SpringApplication后,调用run方法

public ConfigurableApplicationContext run(String... args) {
		//记录应用程序启动时间
		long startTime = System.nanoTime();
		//创建默认的引导上下文,循环调用BootstrapRegistryInitializer 中的 initialize
		DefaultBootstrapContext bootstrapContext = createBootstrapContext();
		ConfigurableApplicationContext context = null;
		//配置headless,默认为true,不使用图形界面
		configureHeadlessProperty();
		//获取SpringApplicationRunListeners实例,从META-INF/spring.factories 和 SpringApplicationHook 中获取
		SpringApplicationRunListeners listeners = getRunListeners(args);
		//启动SpringApplicationRunListeners实例,循环调用SpringApplicationRunListener实例的starting方法
		listeners.starting(bootstrapContext, this.mainApplicationClass);
		try {
			//创建默认的ApplicationArguments实例,用于保存应用程序接收到的命令行参数
			ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
			//准备环境,准备完毕后调用SpringApplicationRunListener实例的environmentPrepared方法
			ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
			//打印banner
			Banner printedBanner = printBanner(environment);
			//创建ApplicationContext,根据WebApplicationType类型
			context = createApplicationContext();
			//设置启动期间的度量记录类
			context.setApplicationStartup(this.applicationStartup);
			//准备应用程序上下文,这里会调用SpringApplicationRunListener实例的contextPrepared和contextLoaded方法
			prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
			//刷新应用程序上下文
			refreshContext(context);
			//刷新上下文后的操作,可以在子类实现
			afterRefresh(context, applicationArguments);
			//计算启动需要的时间
			Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);
			//记录应用程序启动信息,默认是true
			if (this.logStartupInfo) {
				new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), timeTakenToStartup);
			}
			//调用SpringApplicationRunListener实例的started方法
			listeners.started(context, timeTakenToStartup);
			//执行ApplicationRunner和CommandLineRunner
			callRunners(context, applicationArguments);
		}
		catch (Throwable ex) {
			if (ex instanceof AbandonedRunException) {
				throw ex;
			}
			//处理应用程序启动失败的情况,处理退出码,发送ExitCodeEvent事件,调用SpringApplicationRunListener的failed方法,向用户发送失败报告(可以实现FailureAnalysisReporter自定义),优雅关闭应用程序上下文
			handleRunFailure(context, ex, listeners);
			throw new IllegalStateException(ex);
		}
		try {
			if (context.isRunning()) {
				//准备完成时间
				Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);
				//最后调用SpringApplicationRunListener的ready方法
				listeners.ready(context, timeTakenToReady);
			}
		}
		catch (Throwable ex) {
			if (ex instanceof AbandonedRunException) {
				throw ex;
			}
			handleRunFailure(context, ex, null);
			throw new IllegalStateException(ex);
		}
		//返回应用程序上下文
		return context;
	}

这里完成处理有:
1、记录应用程序启动时间
2、创建默认的引导上下文,循环调用BootstrapRegistryInitializer 中的 initialize
3、配置headless,默认为true,不使用图形界面
4、获取SpringApplicationRunListeners实例,从META-INF/spring.factories 和 SpringApplicationHook 中获取,并启动SpringApplicationRunListeners实例,循环调用SpringApplicationRunListener实例的starting方法
5、创建默认的ApplicationArguments实例,用于保存应用程序接收到的命令行参数
6、准备环境,准备完毕后调用SpringApplicationRunListener实例的environmentPrepared方法
7、打印banner
8、创建ApplicationContext
9、设置启动期间的度量记录类
10、准备应用程序上下文
11、刷新应用程序上下文
12、计算启动需要的时间
13、如果需要,记录应用程序启动信息
14、调用SpringApplicationRunListener实例的started方法
15、执行ApplicationRunner和CommandLineRunner
16、最后调用SpringApplicationRunListener的ready方法
17、返回上下文

这样Spring Boot 整体的启动流程就完成了,后面详细看每一步都具体做了什么。

createBootstrapContext(),创建默认的引导上下文

private DefaultBootstrapContext createBootstrapContext() {
//创建默认的引导上下文
		DefaultBootstrapContext bootstrapContext = new DefaultBootstrapContext();
		//循环调用initialize,可以在应用程序启动阶段进行初始化和注册,从而实现更具有个性化的应用程序配置和功能
	   this.bootstrapRegistryInitializers.forEach((initializer) -> initializer.initialize(bootstrapContext));
		return bootstrapContext;
	}

configureHeadlessProperty(),配置headless

private void configureHeadlessProperty() {
//获取系统配置java.awt.headless的值,未配置使用默认值true
		System.setProperty(SYSTEM_PROPERTY_JAVA_AWT_HEADLESS,
				System.getProperty(SYSTEM_PROPERTY_JAVA_AWT_HEADLESS, Boolean.toString(this.headless)));
	}

this.headless默认为true,表示不需要图形化界面,这样有利于提供性能

getRunListeners(args),获取SpringApplicationRunListeners实例

该方法会从META-INF/spring.factories 和 SpringApplicationHook 中获取,并启动SpringApplicationRunListeners实例,然后循环调用SpringApplicationRunListener实例的starting方法

SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting(bootstrapContext, this.mainApplicationClass);
private SpringApplicationRunListeners getRunListeners(String[] args) {
    //将应用程序接收到的命令行参数组合成一个参数解决器
	ArgumentResolver argumentResolver = ArgumentResolver.of(SpringApplication.class, this);
	argumentResolver = argumentResolver.and(String[].class, args);
	//从META-INF/spring.factories 和 SpringApplicationHook 中获取,并启动SpringApplicationRunListeners实例
	List<SpringApplicationRunListener> listeners = getSpringFactoriesInstances(SpringApplicationRunListener.class,
			argumentResolver);
			//获取当前线程中的SpringApplicationHook,此处暂时有个疑问,没发现怎么设置这个SpringApplicationHook❓
	SpringApplicationHook hook = applicationHook.get();
	//如果hook 存在则将获取的SpringApplicationRunListener放入列表
	SpringApplicationRunListener hookListener = (hook != null) ? hook.getRunListener(this) : null;
	if (hookListener != null) {
		listeners = new ArrayList<>(listeners);
		listeners.add(hookListener);
	}
	return new SpringApplicationRunListeners(logger, listeners, this.applicationStartup);
}

prepareEnvironment(listeners, bootstrapContext, applicationArguments),准备环境

private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
		DefaultBootstrapContext bootstrapContext, ApplicationArguments applicationArguments) {
	//创建并配置环境
	ConfigurableEnvironment environment = getOrCreateEnvironment();
	//配置环境,如果需要转换服务,添加ApplicationConversionService,另外委托给了configurePropertySources(属性源)和configureProfiles(配置文件),子类可以覆盖该方法或分别覆盖两者进行细粒度控制
	configureEnvironment(environment, applicationArguments.getSourceArgs());
	//将ConfigurationPropertySource支持附加到指定的环境
	ConfigurationPropertySources.attach(environment);
	//调用environmentPrepared方法
	listeners.environmentPrepared(bootstrapContext, environment);
	//将defaultProperties属性源移动到指定配置环境的最后
	DefaultPropertiesPropertySource.moveToEnd(environment);
	Assert.state(!environment.containsProperty("spring.main.environment-prefix"),
			"Environment prefix cannot be set via properties.");
			//绑定环境到SpringApplication
	bindToSpringApplication(environment);
	//非自定义环境配置,就将其转换为标准类型
	if (!this.isCustomEnvironment) {
		EnvironmentConverter environmentConverter = new EnvironmentConverter(getClassLoader());
		environment = environmentConverter.convertEnvironmentIfNecessary(environment, deduceEnvironmentClass());
	}
	//重新将ConfigurationPropertySource支持附加到指定的环境
	ConfigurationPropertySources.attach(environment);
	return environment;
}

printBanner(environment) 打印banner

private Banner printBanner(ConfigurableEnvironment environment) {
	//banner关闭,不打印
	if (this.bannerMode == Banner.Mode.OFF) {
		return null;
	}
	//获取资源加载器
	ResourceLoader resourceLoader = (this.resourceLoader != null) ? this.resourceLoader
			: new DefaultResourceLoader(null);
			//banner打印器
	SpringApplicationBannerPrinter bannerPrinter = new SpringApplicationBannerPrinter(resourceLoader, this.banner);
	if (this.bannerMode == Mode.LOG) {
		return bannerPrinter.print(environment, this.mainApplicationClass, logger);
	}
	return bannerPrinter.print(environment, this.mainApplicationClass, System.out);
}

createApplicationContext(),创建应用上下文

protected ConfigurableApplicationContext createApplicationContext() {
		return this.applicationContextFactory.create(this.webApplicationType);
	}

使用策略模式的创建应用程序上下文方法,支持显示设置applicationContextFactory,默认使用DefaultApplicationContextFactory

context.setApplicationStartup(this.applicationStartup),设置启动期间的记录类

默认设置为DefaultApplicationStartup,是一个空操作的记录类,支持显示覆盖

prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner),准备应用程序上下文

private void prepareContext(DefaultBootstrapContext bootstrapContext, ConfigurableApplicationContext context,
		ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
		ApplicationArguments applicationArguments, Banner printedBanner) {
		//将指定环境设置到应用程序上下文中
	context.setEnvironment(environment);
	//应用后置处理器
	postProcessApplicationContext(context);
	//如果需要,添加AOT生成的初始化器
	addAotGeneratedInitializerIfNecessary(this.initializers);
	//应用ApplicationContextInitializer
	applyInitializers(context);
	//通知侦听器应用程序上下文已经准备好
	listeners.contextPrepared(context);
	// 关闭引导上下文
	bootstrapContext.close(context);
	if (this.logStartupInfo) {
		logStartupInfo(context.getParent() == null);
		logStartupProfileInfo(context);
	}
	 // 添加引导所必需的单例
	ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
	beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
	if (printedBanner != null) {
		beanFactory.registerSingleton("springBootBanner", printedBanner);
	}
	if (beanFactory instanceof AbstractAutowireCapableBeanFactory autowireCapableBeanFactory) {
	//设置循环引用
			autowireCapableBeanFactory.setAllowCircularReferences(this.allowCircularReferences);
		if (beanFactory instanceof DefaultListableBeanFactory listableBeanFactory) {
		
//设置是否允许覆盖
			listableBeanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
		}
	}
	if (this.lazyInitialization) {
	//设置延迟初始化
		context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
	}
	//设置一个PropertySourceOrderingBeanFactoryPostProcessor处理器
	context.addBeanFactoryPostProcessor(new PropertySourceOrderingBeanFactoryPostProcessor(context));
	if (!AotDetector.useGeneratedArtifacts()) {
		// Load the sources
		Set<Object> sources = getAllSources();
		Assert.notEmpty(sources, "Sources must not be empty");
		//将所有源bean加载到上下文中
		load(context, sources.toArray(new Object[0]));
	}
	//通知侦听器应用程序上下文已经加载完成
	listeners.contextLoaded(context);
}

refreshContext(context) 刷新上下文

private void refreshContext(ConfigurableApplicationContext context) {
		if (this.registerShutdownHook) {
			//如果需要,注册ShutdownHook以确保优雅关闭应用程序
			shutdownHook.registerApplicationContext(context);
		}
		//调用Spring的刷新应用程序上下文
		refresh(context);
	}

afterRefresh(context, applicationArguments) 刷新上下文后

protected void afterRefresh(ConfigurableApplicationContext context, ApplicationArguments args) {
	}

这是一个模版方法,子类实现

started方法

listeners.started(context, timeTakenToStartup);

告知所有监听器应用程序启动完成

callRunners(context, applicationArguments) 执行ApplicationRunner和CommandLineRunner

private void callRunners(ApplicationContext context, ApplicationArguments args) {
		List<Object> runners = new ArrayList<>();
		runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
		runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
		AnnotationAwareOrderComparator.sort(runners);
		for (Object runner : new LinkedHashSet<>(runners)) {
			if (runner instanceof ApplicationRunner applicationRunner) {
				callRunner(applicationRunner, args);
			}
			if (runner instanceof CommandLineRunner commandLineRunner) {
				callRunner(commandLineRunner, args);
			}
		}
	}

用户自定义实现,会循环调用两个类的run,CommandLineRunner参数是数组,ApplicationRunner参数是ApplicationArguments类

调用ready

if (context.isRunning()) {
				Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);
				listeners.ready(context, timeTakenToReady);
			}

最终调用监听器的ready方法,告知上下文刷新完成,并且调用了所有CommandLineRunner和ApplicationRunner

总结

最后使用一张图来总结整个启动流程。
在这里插入图片描述

作者其他文章:
Spring Boot 3.x系列文章

  1. Spring Boot 2.7.8 中文参考指南(一)
  2. Spring Boot 2.7.8 中文参考指南(二)-Web
  3. Spring Boot 源码阅读初始化环境搭建
  4. Spring Boot 框架整体启动流程详解

Prometheus 系列文章

  1. Prometheus 的介绍和安装
  2. 直观感受PromQL及其数据类型
  3. PromQL之选择器和运算符
  4. PromQL之函数
  5. Prometheus 告警机制介绍及命令解读
  6. Prometheus 告警模块配置深度解析
  7. Prometheus 配置身份认证
  8. Prometheus 动态拉取监控服务
  9. Prometheus 监控云Mysql和自建Mysql

Grafana 系列文章,版本:OOS v9.3.1

  1. Grafana 的介绍和安装
  2. Grafana监控大屏配置参数介绍(一)
  3. Grafana监控大屏配置参数介绍(二)
  4. Grafana监控大屏可视化图表
  5. Grafana 查询数据和转换数据
  6. Grafana 告警模块介绍
  7. Grafana 告警接入飞书通知

Spring Boot Admin 系列

  1. Spring Boot Admin 参考指南
  2. SpringBoot Admin服务离线、不显示健康信息的问题
  3. Spring Boot Admin2 @EnableAdminServer的加载
  4. Spring Boot Admin2 AdminServerAutoConfiguration详解
  5. Spring Boot Admin2 实例状态监控详解
  6. Spring Boot Admin2 自定义JVM监控通知
  7. Spring Boot Admin2 自定义异常监控
  8. Spring Boot Admin 监控指标接入Grafana可视化

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

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

相关文章

Android 13 wifi adb设置固定端口解决

Android 13 wifi adb设置固定端口解决 本文只管解决介绍不做代码层面具体分析。 文章目录 Android 13 wifi adb设置固定端口解决一、前言二、设置wifi 固定端口号三、打开 "无线调试"1、手动打开设置里面的开发者选项 里面的“无线调试”2、通过命令设置打开 "…

想面试Java后端,至少这些你都要会吧

跨越Java后端面试的最重要关卡&#xff0c;就是对技术知识的准备。但难点在于&#xff0c;后端技术栈的内容繁杂&#xff0c;你需要掌握一个广泛的领域。那么&#xff0c;为了保证你能够顺利面试Java后端岗位&#xff0c;下面分享我认为你必须要掌握的技术&#xff1a; 1. Jav…

【实验练习】基于SVM的实现鸢尾花(Iris)数据集分类 (Python实现)

题目 采用SVM方法实现鸢尾花(Iris)数据集分类 数据集 iris.name是关于数据集的属性说明&#xff1b; iris.data是实际的数据集&#xff0c;它包含三类数据&#xff0c;每类数据有50条数据。 要求 训练集&#xff1a;选取Iris数据集中80%的数据&#xff0c;即120个数据&…

小程序容器技术:数字门户的创新引擎

数字门户是指提供一站式访问和集成多个在线服务、信息和资源的网络平台。它通常是一个网站或应用程序&#xff0c;为用户提供广泛的功能和服务&#xff0c;如新闻、天气预报、电子邮件、在线购物、社交媒体、银行服务、电子支付、在线学习、政府服务等。数字门户的目标是通过集…

Laravel 招聘系统 - 求职者和雇主的解决方案

您是否正在寻找一个将求职者和雇主联系起来的解决方案&#xff1f;那就不要再找了&#xff01;我们隆重推出 Laravel 招聘板&#xff0c;这是一个使用 Laravel 9.x 框架构建的尖端招聘板脚本。凭借其简洁而优雅的设计&#xff0c;该脚本旨在创建一个用于广告职位空缺、寻找合适…

【Python小技巧】Python操控Chrome浏览器实现网页打开、切换、关闭(送独家Chrome操作打包类源码、Chrome浏览器Cookie在哪里?)

文章目录 前言一、什么时候需要用Python控制浏览器&#xff1f;二、下载Chrome浏览器驱动文件1. 安装Chrome浏览器并查看版本2. 下载浏览器驱动文件3. 解压到python编译器目录&#xff08;python.exe所在目录&#xff09; 三、Python控制Chrome浏览器&#xff08;附源代码&…

基于国产RK3588+多路H.265视频编解码 转码 3U VPX 方案

一、概述 3U VPX音视频转码模块是信迈科技推出的基于RK3588平台用于音视频的编解码、转码&#xff0c;本模块SDI视频、模拟音频输入&#xff0c;视频进行分辨率和帧率的变换&#xff0c;音频进行采样率和码率等的变换&#xff0c;网口输入的视频流进行解码或者转码&…

Linux——进程优先级环境变量

目录 1、进程优先级 1.1 基本概念 1.2 查看系统进程 1.3 PRI and NI 1.4 PRI vs NI 1.5 查看进程优先级的命令 1.6 其他概念 2、环境变量 2.1 基本概念 2.2 常见环境变量 2.3 查看环境变量方法 2.4 测试PATH 2.5 测试HOME 2.6 和环境变量相关的命令 2.7 环境变量…

Springboot配置文件中的明文密码漏洞

目录 一、背景 二、本地修复测试 1、maven中引入jasypt 2、编写加密解密工具类 3、修改配置文件&#xff0c;增加秘钥 4、秘钥放在启动项 三、生产实现 1、升级打包代码 2、生产yml修改明文密码处 3、修改启动命令 一、背景 最近接收到网安的系统安全…

c++类和对象【3】(static成员,友元内部类,匿名对象等)

文章目录 1.友元函数1.1友元函数1.2友元类 2内部类3.匿名对象4.拷贝对象的一些编译器优化5.static成员 1.友元函数 我们在类外面去访问类里的私有成员&#xff0c;就要突破类的访问限定因此就有了友元&#xff0c;它提供了一种突破封装的方式&#xff0c;但是友元会增加耦合度…

GPT时代,一定要收藏的结构化提问技巧

有一种被称为“SMART”的结构化提问方法&#xff0c;可以帮助你更好的组织和明确提出的问题。“SMART”是一个缩写&#xff0c;它代表了以下几个关键元素&#xff1a; S&#xff1a;Specific&#xff08;具体&#xff09; 确保问题具体明确&#xff0c;避免模糊或含糊不清的表…

基于SVPWM调制的三相整流器_Simulink仿真模型

文章目录 模型总览特性功能实现输入三相交流电压220Vac 经过三相整流器进行功率变换&#xff0c;输出电压750V&#xff0c;输出功率10kW&#xff0c;同时实现功率因数校正/PFC功能&#xff08;控制输入电流与输入电压同相且为正弦电流&#xff09;&#xff0c;输入电流THD为1.3…

spring cloud搭建(zuul)

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

路径规划算法:基于黏菌优化的路径规划算法- 附代码

路径规划算法&#xff1a;基于黏菌优化的路径规划算法- 附代码 文章目录 路径规划算法&#xff1a;基于黏菌优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要&#xff1a;本文主要介绍利用智能优化算法黏菌…

一百二十二、Git——Git上传代码(完善中)

方式一、用IDEA 第一步&#xff0c;IEDA拉项目 File——New——Project from Version Control——Git 输入URL&#xff0c;选择Directory&#xff0c;点击clone 第二步&#xff0c;把上传文件拉到IDEA项目&#xff0c;然后选中文件&#xff0c;右击Git,选择Reposity,如果上传…

中国人口增长预测

目录 问题分析 模型建立 Logistic模型 Leslie模型 模型求解 问题一 问题二 问题三 问题分析 问题 基本假设 &#xff08;1&#xff09;不考虑移民对人口总数的影响 &#xff08;2&#xff09;超过90岁按照90岁计算 &#xff08;3&#xff09;在较短时间内&#xff0c;平均…

深度学习预预训练与MMPretrain

MMPretrain算法库 优势&#xff1a; 含有各种主干网络模型自监督学习功能多模态学习功能丰富的数据集含有训练技巧和策略易用&#xff0c;例如可解释性分析、推理api 包含多种丰富任务的开箱即用推理api 图像分类图像语义描述视觉问答视觉定位检索 安装步骤 配置文件中含有…

python 社区发现算法

转载&#xff1a;这个Python库超级棒啊&#xff0c;包含Louvain 算法、Girvan-Newman 算法等多种社区发现算法&#xff0c;还具有可视化功能_11205354的技术博客_51CTO博客 熟知社区发现算法&#xff0c;你不能错过这个 Python 库。它涵盖 Louvain 算法、Girvan-Newman 算法等…

Java基础(项目2)——项目案例:控制台的一个云就业平台项目【应聘+招聘】

目录 引出项目的分层固定的流程反思1.entity --- 实体类2.dao ---数据库的CRUD【进化到Spring的JdbcTemplate】以职位投递的dao为例---进化到Spring的JdbcTemplate&#xff1a; 3.service --- 组织代码的业务【进化到servlet调用service】4.util ---需要用到的工具【进化到duri…

leetcode450. 删除二叉搜索树中的节点(java)

删除二叉搜索树中的节点 leetcode450. 删除二叉搜索树中的节点题目描述 解题思路代码演示二叉树专题 leetcode450. 删除二叉搜索树中的节点 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;https://leetcode.cn/problems/delete-node-in-a-bst 题目描述…