【SpringBoot】万字源码解析——启动流程
Spring Boot启动流程
Spring Boot
的入口类:
@SpringBootApplication
public class IntelGradingApplication {public static void main(String[] args) {SpringApplication.run(IntelGradingApplication.class, args);}
}
Spring Boot
的启动过程可以分为两方面,一个是 new SpringApplication(primarySources)
的初始化过程,一个是 SpringApplication.run()
的应用运行过程。
public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {return run(new Class[]{primarySource}, args);
}public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {// 传入primarySources数组,构造SpringApplicationreturn (new SpringApplication(primarySources)).run(args);
}
执行构造函数
构造函数是 Spring Boot 启动过程的第一步,负责初始化各种属性、验证输入并设置必要的上下文,为后续的应用启动和上下文配置奠定基础。Spring Boot 通过一个重载构造函数来接收 null
值的资源加载器和主类数组:
public SpringApplication(Class<?>... primarySources) {this((ResourceLoader)null, primarySources);
}public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {....
}
1.初始化字段
重构的构造函数接收ResourceLoader
和primarySources
参数,并为各种字段进行初始化,比如ResourceLoader
, bannerMode
, headless
等。
this.sources = new LinkedHashSet();
this.bannerMode = Mode.CONSOLE;
this.logStartupInfo = true;
this.addCommandLineProperties = true;
this.addConversionService = true;
this.headless = true;
this.registerShutdownHook = true;
this.additionalProfiles = Collections.emptySet();
this.isCustomEnvironment = false;
this.lazyInitialization = false;
this.applicationContextFactory = ApplicationContextFactory.DEFAULT;
this.applicationStartup = ApplicationStartup.DEFAULT;
this.resourceLoader = resourceLoader;
2.设置主源
将primarySources
转换为LinkedHashSet
,以确保启动过程中按顺序处理,避免重复。
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
3.推断应用类型
通过检查类路径classpath
中的组件(如 "org.springframework.web.reactive.DispatcherHandler
)来确定当前应用的类型:
- REACTIVE:响应式 Web 应用(基于 Reactor 和 WebFlux)。
- SERVLET:传统的 Servlet 类型 Web 应用(如使用 Spring MVC)。
- NONE:非 Web 应用,通常是命令行应用。
this.webApplicationType = WebApplicationType.deduceFromClasspath();
4.加载工厂实例
从 META-INF/spring.factories
中加载配置的初始化器 ApplicationContextInitializer
、BootstrapRegistryInitializer
和监听器 ApplicationListener
。
BootstrapRegistryInitializer
允许在Spring Boot
启动时自定义初始化Bootstrap
注册表。Bootstrap
注册表是一个支持应用上下文的初始化过程的机制,通常用于配置与应用启动相关的共享资源。ApplicationContextInitializer
允许用户在ApplicationContext
刷新前进行进一步的初始化配置操作。这包括但不限于添加属性源、修改环境变量、设置 Bean 定义等。ApplicationListener
,用于监听 Spring Boot 的生命周期事件。这些监听器会在应用启动过程中响应不同的事件,如应用启动事件、环境准备事件、上下文刷新事件等。
// 加载Bootstrap注册表初始化器
this.bootstrapRegistryInitializers = new ArrayList(this.getSpringFactoriesInstances(BootstrapRegistryInitializer.class));
// 加载应用上下文初始化器
this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
// 加载监听器
this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
getSpringFactoriesInstances()
方法的核心方法:
loadFactoryNames()
:利用 SpringFactoriesLoader 获取指定工厂的实现类的 Set 集合createSpringFactoriesInstances
:通过反射机制实例化每个工厂的实现类
// 利用Spring工厂加载器获取指定工厂的实现类的set集合
Set<String> names = new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
// 通过反射机制实例化每个工厂的实现类
List<T> instances = this.createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
5.推断主类
通过 StackTraceElement
找到 main
方法,确定应用程序的入口类。这通常是标记了 @SpringBootApplication
注解的类。
this.mainApplicationClass = this.deduceMainApplicationClass();
执行run方法
1.启动计时器并初始化
-
在执行
run
方法的开头,首先启动一个计时器以记录应用启动的总时长。 -
接着,创建一个
DefaultBootstrapContext
,它会遍历并执行在Bootstrap
注册表中的所有初始化器,以确保启动过程中的必要资源和设置得到正确配置。 -
然后,
ConfigurableApplicationContext
的引用被声明为null
,并配置无头属性,以便在没有用户界面的环境中正常运行。
// 1.1.启动计时器
long startTime = System.nanoTime();
// 1.2.初始化bootstrapContext上下文,该方法会遍历并执行BootStrap注册表中的初始化器
DefaultBootstrapContext bootstrapContext = this.createBootstrapContext();
// 1.3.声明ApplicationContext为null
ConfigurableApplicationContext context = null;
// 1.4.设置无头属性
this.configureHeadlessProperty();
2.获取并启动监听器
// 2.1.获取监听器
SpringApplicationRunListeners listeners = this.getRunListeners(args);
// 2.2.通知监听器,应用程序即将启动
listeners.starting(bootstrapContext, this.mainApplicationClass);
在获取监听器的方法 getRunListeners()
中,将所有的监听器封装为一个 SpringApplicationRunListeners 对象,由于在构造函数执行阶段已经加载了监听器对象,在调用方法 getSpringFactoriesInstances
时会直接查询缓存获取对象。
// 2.1.获取监听器
private SpringApplicationRunListeners getRunListeners(String[] args) {Class<?>[] types = new Class[]{SpringApplication.class, String[].class};// 封装从getSpringFactoriesInstances()方法中获得工厂的所有实现类return new SpringApplicationRunListeners(logger, this.getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args), this.applicationStartup);
}
通知监听器应用即将启动。这一步骤确保所有监听器能够在应用启动的早期阶段参与并进行必要的初始化。
// 2.2.通知监听器
listeners.starting(bootstrapContext, this.mainApplicationClass)
3.装配环境参数
- 将环境参数与**「引导上下文」**绑定,
prepareEnvironment()
方法会加载应用的外部配置。这包括application.properties
或application.yml
文件中的属性,环境变量,系统属性等。
// 3.1.创建命令行参数对象
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
// 3.2.加载应用的外部配置
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, bootstrapContext, applicationArguments);
// 3.3.配置忽略 Bean 信息
this.configureIgnoreBeanInfo(environment);
在prepareEnvironment()
方法中,首先会进行环境配置,还会执行监听器的 environmentPrepared()
方法,表明应用程序的环境已经准备好,最后再将环境绑定到应用程序中。
4.打印横幅
Banner printedBanner = this.printBanner(environment);
5.创建应用上下文
根据构造阶段推断出的 Web 应用类型,创建Spring容器
// 5.调用createApplicationContext方法创建Spring容器
context = this.createApplicationContext();
6.应用上下文准备阶段
this.prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
进入 prepareContext()
方法,具体实现如下:
private void prepareContext(DefaultBootstrapContext bootstrapContext, ConfigurableApplicationContext context, ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {// 6.1.将传入的环境参数应用到上下文中,并调用后处理方法context.setEnvironment(environment);this.postProcessApplicationContext(context);// 6.2.遍历并执行所有注册的初始化器,进一步配置应用上下文this.applyInitializers(context);// 6.3.通知监听器,上下文准备完毕listeners.contextPrepared(context);// 6.4.关闭启动阶段的引导上下文,释放与启动相关的资源bootstrapContext.close(context);// 6.5.打印日志启动信息if (this.logStartupInfo) {this.logStartupInfo(context.getParent() == null);this.logStartupProfileInfo(context);}// 6.6.将命令行参数和横幅注册为Bean,存放到应用上下文中ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();beanFactory.registerSingleton("springApplicationArguments", applicationArguments);if (printedBanner != null) {beanFactory.registerSingleton("springBootBanner", printedBanner);}// 6.7.根据Bean工厂,允许配置循环引用和 bean 定义覆盖if (beanFactory instanceof AbstractAutowireCapableBeanFactory) {((AbstractAutowireCapableBeanFactory)beanFactory).setAllowCircularReferences(this.allowCircularReferences);if (beanFactory instanceof DefaultListableBeanFactory) {((DefaultListableBeanFactory)beanFactory).setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);}}// 6.8.设置懒初始化配置if (this.lazyInitialization) {context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());}context.addBeanFactoryPostProcessor(new PropertySourceOrderingBeanFactoryPostProcessor(context));// 6.9.加载源,确保应用上下文中定义的 bean 被正确创建。Set<Object> sources = this.getAllSources();Assert.notEmpty(sources, "Sources must not be empty");this.load(context, sources.toArray(new Object[0]));// 6.10.通知监听器,所有的Bean都已经加载但未进行实例化listeners.contextLoaded(context);
}
7.应用上下文刷新阶段
this.refreshContext(context);
- 首先通过加锁确保线程安全,创建并配置
BeanFactory
,这一过程包括注册 Bean 后处理器和事件监听器。 - 在
onRefresh()
方法中,还会启动 Web 服务器。 - 最后,通过配置好的
BeanFactory
实例化所有的Beans
。在这个过程中,BeanFactory
会根据定义的元数据创建和初始化Beans
,并根据需求进行依赖注入,确保整个应用的组件能够顺利协作。
8.应用上下文收尾阶段
// 8.1.afterRefresh()无实际内容,后续版本被移除
this.afterRefresh(context, applicationArguments);
// 8.2.计算应用启动时间
Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);
if (this.logStartupInfo) {(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), timeTakenToStartup);
}
// 8.3.通知监听器,应用程序启动完成
listeners.started(context, timeTakenToStartup);
9.回调运行器
// 9.1.回调运行器
this.callRunners(context, applicationArguments);
// 9.2.通知监听器
Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);
listeners.ready(context, timeTakenToReady);
该方法从上下文 context
中获取所有已注册的 ApplicationRunner
和 CommandLineRunner
,并结合传入的应用参数 args
执行这些运行器。
这些运行器允许开发者在应用程序启动后执行特定的逻辑,例如初始化数据、设置应用状态或执行启动任务,提供了灵活性和扩展性。
private void callRunners(ApplicationContext context, ApplicationArguments args) {List<Object> runners = new ArrayList();// 9.1.1.从上下文中获取运行器runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());AnnotationAwareOrderComparator.sort(runners);Iterator var4 = (new LinkedHashSet(runners)).iterator();// 9.1.2.结合应用参数执行运行器while(var4.hasNext()) {Object runner = var4.next();if (runner instanceof ApplicationRunner) {this.callRunner((ApplicationRunner)runner, args);}if (runner instanceof CommandLineRunner) {this.callRunner((CommandLineRunner)runner, args);}}
}
10.异常处理
在整个启动过程中,如果出现任何异常,都会被捕获并通过handleRunFailure()
方法进行处理,在该方法中,会通知监听器应用程序启动时出现异常。
该方法会记录错误信息,并通过监听器通知失败事件。最终,抛出IllegalStateException
来中止应用启动,确保调用者能够识别到启动失败的状态。
catch (Throwable var12) {ex = var12;this.handleRunFailure(context, ex, listeners);throw new IllegalStateException(ex);
}
SpringApplicationRunListeners监听器
SpringApplicationRunListeners
是一个具体的类。它实现了 Spring Boot 中的监听器机制,用于在应用程序的不同启动阶段通知注册的监听器(SpringApplicationRunListener
接口的实现类)。通过这个类,Spring Boot 可以在应用启动过程中管理多个监听器,处理各种生命周期事件。
SpringApplicationRunListeners(Log log, Collection<? extends SpringApplicationRunListener> listeners, ApplicationStartup applicationStartup) {// 记录日志this.log = log;// 保存已注册的监听器列表,这些监听器会对应用程序生命周期事件做出响应this.listeners = new ArrayList(listeners);// 跟踪启动步骤,以便进行性能监控this.applicationStartup = applicationStartup;
}
SpringApplicationRunListener
是 Spring Boot 中的一个接口,用于在应用启动过程的不同阶段提供回调。实现这个接口允许监听并响应应用生命周期中的关键事件。该接口定义了多个方法,每个方法对应启动过程中的特定阶段,包括:
- starting(): 在运行开始时调用,此时尚未开始任何处理,可以用于初始化在启动过程中需要的资源。
- environmentPrepared(): 当
SpringApplication
准备好Environment
但在创建ApplicationContext
之前调用,这是修改应用环境属性的好时机。 - contextPrepared(): 当
ApplicationContext
准备好但在加载之前调用,可以用于对上下文进行预处理。 - contextLoaded(): 当
ApplicationContext
被加载但在刷新之前调用,此时所有的 Bean 定义都已加载,但尚未实例化。 - started(): 在
ApplicationContext
刷新之后、任何应用运行器和命令行运行器被调用之前调用,此时应用已经准备好接收请求。 - running(): 在运行器被调用之后、应用启动完成之前调用,这是在应用启动并准备好服务请求时执行某些动作的好时机。
- failed(): 如果启动过程中出现异常,则调用此方法。
SpringFactoriesLoader原理
SpringFactoriesLoader
方法会根据传入的工厂类和类加载器,从 META-INF/spring.factories
文件中加载**「指定类型对应的工厂类名称」**。
loadFactoryNames()
loadFactoryNames
方法是一个高级 API,它通过获取入参中的全限定类名 factoryTypeName
,在内部调用 loadSpringFactories()
方法获取返回的 Map 集合,并根据 factoryTypeName
获取了 Map 中的实现类的 List 集合。
public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {ClassLoader classLoaderToUse = classLoader;if (classLoaderToUse == null) {classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();}// 获取工厂类的全限定名String factoryTypeName = factoryType.getName();// 从 loadSpringFactories 返回的 Map 中获取指定类型工厂的实现类return (List)loadSpringFactories(classLoaderToUse).getOrDefault(factoryTypeName, Collections.emptyList());
}
loadSpringFactories()
loadSpringFactories
方法是更加底层的方法,通过缓存机制和类加载器获取 spring.factories
文件中所有配置的工厂及其实现类,将这些信息封装为 Map
集合后返回给上游的 API。
缓存机制
方法会检查是否已经通过当前类加载器加载过 spring.factories
文件。如果缓存 (cache
) 中已经存在相应的工厂信息,直接返回缓存的 Map<String, List<String>>
,避免重复加载。
Map<String, List<String>> result = (Map)cache.get(classLoader);
if (result != null) {return result;
}
加载 META-INF/spring.factories
方法会通过类加载器查找所有路径下名为 META-INF/spring.factories
的文件。由于每个 JAR 包都可能包含一个 META-INF/spring.factories
文件,方法会返回一个 Enumeration<URL>
对象,表示找到的所有相关资源文件。
Enumeration<URL> urls = classLoader.getResources("META-INF/spring.factories");
解析spring.factories文件
通过迭代逐个读取每个找到的 spring.factories
文件。对于每个文件,使用 PropertiesLoaderUtils.loadProperties()
将文件内容解析为 Properties
对象。
每个 Properties
对象对应一个 spring.factories
文件的内容,其中 key 是工厂类型(例如 org.springframework.context.ApplicationContextInitializer
),value 是逗号分隔的工厂实现类列表。
while(urls.hasMoreElements()) {URL url = (URL)urls.nextElement();UrlResource resource = new UrlResource(url);Properties properties = PropertiesLoaderUtils.loadProperties(resource);
将工厂类型和实现类存入Map
遍历 Properties
的 entrySet()
。对于每个 entry
,key
是工厂类型的全限定类名,value
是对应的工厂实现类名(逗号分隔)。
工厂类型名称通过 entry.getKey()
获取,并使用 String.trim()
去除可能的空白字符。工厂实现类则将逗号分隔的字符串转换为实现类的数组。
while(var6.hasNext()) {Map.Entry<?, ?> entry = (Map.Entry)var6.next();String factoryTypeName = ((String)entry.getKey()).trim();String[] factoryImplementationNames = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());String[] var10 = factoryImplementationNames;int var11 = factoryImplementationNames.length;for(int var12 = 0; var12 < var11; ++var12) {String factoryImplementationName = var10[var12];((List)result.computeIfAbsent(factoryTypeName, (key) -> {return new ArrayList();})).add(factoryImplementationName.trim());}
}
相关文章:
【SpringBoot】万字源码解析——启动流程
Spring Boot启动流程 Spring Boot 的入口类: SpringBootApplication public class IntelGradingApplication {public static void main(String[] args) {SpringApplication.run(IntelGradingApplication.class, args);} }Spring Boot 的启动过程可以分为两方面&am…...
Nginx 配置初步 下
Nginx 配置初步(下) 一行代表一个指令; 每个指令有其上下文环境,比如 listen 指令只能在 http 指令块中出现,不能单独出现。1. Http 服务配置初步 1.1 常用指令 Nginx 的所有模块,打开模块我们就能看到模块中支持的指令。最常用…...
可视化ETL平台-Kettle的安装及简单使用
本章知识简介 主线A: 自连接查询; 主线B: 安装JDK与Kettle; 主线C: 使用Kettle工具. 本章目标: 1: 知道使用一张表可以实现自连接查询; [了解]注意: 左表、右表都是同一张表 2: 了解Kettle环境的安装流程; [了解]a.安装JDKb.安装Kettle 3: 熟悉使用kettle将txt数…...
java8 动态加载jar包至系统的classpath
1. io.test包 创建MyMain.java类,创建addJarToClasspath方法将jar包动态加载进系统的classpath中 package io.test;import java.io.File; import java.net.URL; import java.net.URLClassLoader; import java.lang.reflect.Method;public class MyMain {public st…...
C++二级题 计算好数:1数大于0数(二进制的位运算)
1、题目 若将一个正整数化为二进制数,在此二进制数中,我们将数字1的个数多于数字0的个数的这类二进制数称为好数。 例如: (13)10 (1101)2,其中1的个数为3,0的个数为1,则此数是好数; (10)10 (1…...
数字孪生城市:智慧城市的未来蓝图
在当今数字化时代,智能技术的广泛应用正在改变人们的生活和工作方式。数字孪生城市作为未来新型智慧城市演进的重要方向,数字孪生城市是一种将城市物理世界的各个方面转化为数字形式的技术,通过网络空间与物理世界之间的实时数据交换和仿真分…...
Java篇图书管理系统
目录 前言 一. 图书管理系统的核心 二. 图书管理系统基本框架 2.1 book包 2.1.1 Book(书籍类) 2.1.2 Booklist (书架类) 2.2 user包 2.2.1 User类 2.2.2 Administrator(管理员类) 2.2.3 Visitor(用户类) 2.…...
BUUCTF之web篇
第一题 [极客大挑战 2019]EasySQL 打开靶机后可以看到这是一个登陆的页面 我们可以尝试两种方式登录 弱口令爆破(burpsuite) 通过SQL注入里的万能密码来跳过账户和密码验证的过程 这里就需要万能密码aor true # 在这里单引号的作用是结束用户名或者密码…...
010——二叉树(2)线索化
引入: 问题1: n个节点的二叉树,用二叉链表存储,问在这个二叉链表中一共有 __个指针域? 其中,有 __个指针域不为NULL,__个指针域为NULL? 答:2n n-1 n1 在二叉链表中…...
鸿蒙拍照小助手02
项目文件目录 为了确保项目文件目录清晰,以下是完整的项目文件目录结构: code 拍照小助手/ │ ├── entry/ │ ├── src/ │ │ ├── main/ │ │ │ ├── js/ │ │ │ │ └── 默认/ │ │ │ │ ├── 页面/ │ │ │ │ │ ├── 主页/ │ │ │ │ │ │ ├…...
lua while循环
软考鸭微信小程序 过软考,来软考鸭! 提供软考免费软考讲解视频、题库、软考试题、软考模考、软考查分、软考咨询等服务 Lua作为一种小巧精致的语言,特别适用于嵌入其他程序提供脚本支持。在编程中,循环结构是不可或缺的一部分,而while循环则是…...
JAVA篇之类和对象
目录 一. 面向对象 1.1 面向对象和面向过程 二. 类的定义和使用 2.1 什么是类 2.2 类的定义格式 三. 类的实例化 四. this引用 4.1 this引用的作用 五. 构造方法 5.1 构造方法重载 5.2 通过this调用其他构造方法 5.3 默认初始化 结语 一. 面向对象 Java 是一门面向对…...
IO流详解_CoderLix
主要内容 File类IO流字节流字符流异常处理Properties缓冲流转换流序列化流打印流 File类 1.1 概述 java.io.File 类是文件和目录路径名的抽象表示,主要用于文件和目录的创建、查找和删除等操作。 1.2 构造方法 public File(String pathname) :通过…...
241023-RHEL非管理员安装Docker并开放指定宿主机端口部署Gitlab
A. RHEL非管理员安装Docker 要在没有管理员权限的情况下离线安装 Docker 和 Docker Compose,虽然受到一定限制,仍有一些可行的步骤可以帮助你在有限权限下完成这项任务。需要注意的是,这种方式适用于本地用户环境下的 Docker 安装࿰…...
python ubuntu安装加速
ubuntu升级python到python3.11(可能是全网最靠谱的方法,亲测有效)_ubuntu python3.11-CSDN博客 python-release安装包下载_开源镜像站-阿里云...
100种算法【Python版】第12篇——快速幂算法
本文目录 1 基本原理2 基本步骤3 数学示例4 python代码1 基本原理 快速幂算法(Fast Exponentiation)是一种高效计算整数幂的方法,尤其适用于计算大数的幂。其主要思想是利用分治法和二进制表示来减少乘法运算的次数,从而加快计算速度。 计算 x n x^n x...
Java多线程详解②(全程干货!!!)Thread Runnable
这里是Themberfue 上节主要讲完了多线程的一些基础知识,这节通过代码进一步理解多线程🫡 多线程 Java标准库中提供了Thread类,以程序员们编写多线程代码,我们可以查看官方文档进一步了解Thread的特性以及提供的接口。 类似于Sy…...
机器学习——图神经网络
图神经网络(GNN):理解复杂网络数据的有效工具 图神经网络(Graph Neural Network, GNN)是近年来机器学习领域的热门话题。GNN 以图结构数据为核心,能够高效地捕捉节点和边的复杂关系,广泛应用于社交网络、推荐系统、生…...
一、在cubemx下RTC配置调试实例测试
一、rtc的时钟有lse提供。 二、选择rtc唤醒与闹钟功能 内部参数介绍 闹钟配置 在配置时间时,注意将时间信息存储起来,防止复位后时间重新配置。 if(HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0)! 0x55AA)//判断标志位是否配置过,没有则进…...
【Nas】X-DOC:Mac mini Docker部署中国特供版Jellyfin
【Nas】X-DOC:Mac mini Docker部署中国特供版Jellyfin 1、拉取镜像:2、启动镜像3、访问服务4、参考文档 Mac mini Docker部署中国特供版Jellyfin 1、拉取镜像: docker pull nyanmisaka/jellyfin:230901-amd64jellyfin 10.8.10版本ÿ…...
合合信息:生成式Al时代的内容安全与系统构建加速,开启智能文档的全新潜能
文章目录 写在前面图像内容安全图像篡改应用场景伪造文档/证照检测伪造人脸检测 GAI时代系统构建加速通用文档解析 合合信息 写在前面 随着人工智能技术的飞速发展,生成式AI已经悄然步入了我们的日常生活,以其强大的内容生成能力,重塑了信息…...
京东双十一高并发场景下的分布式锁性能优化
背景 在电商领域,尤其是像京东双十一这样的大促活动,系统需要处理极高的并发请求。这些请求往往涉及库存的查询和更新,如果处理不当,很容易出现库存超卖、数据不一致等问题。分布式锁作为一种有效的解决方案,能够在多…...
华为ICT题库-AI 人工智能部分
1178、以下哪个选项是华为的云端AI芯片?(云服务考点) (A)Inferentia (B)MLU100 (C)Cloud TPU (D)Ascend 910 答案:D 解析:华为的云端AI芯片被称为Ascend芯片系列,其中Ascend 910是其旗舰产品。Ascend 910…...
React Native 修改安卓应用图片和名称
在React Native(RN)项目中,修改安卓应用图标和名称通常涉及对Android原生代码的一些修改。以下是详细步骤: 修改应用图标 准备图标资源: 创建或获取你想要的图标,并确保它们符合Android的图标规范…...
普推知产:商标初审已下,商标申请通过如何高些!
近期下来一批商标注册的初步审公告通知书,一些客户对商标下证要求比较高的,普推知产商标老杨发现,要像下证高核心还是在于名称,名称起好备用的多,让商标专业人士经检索后层层过滤后提报,通过会好很多。 普推…...
HICP--2
在area 0的路由器只生成 area 0 的数据库,只在area 1 的一样。但是既在又在的生成两个 area的 LSDB 一、区域间三类LSA 在OSPF(Open Shortest Path First)协议中,区域间三类LSA(Link-State Advertisement)…...
sheng的学习笔记-AI基础-正确率/召回率/F1指标/ROC曲线
AI目录:sheng的学习笔记-AI目录-CSDN博客 分类准确度问题 假设有一个癌症预测系统,输入体检信息,可以判断是否有癌症。如果癌症产生的概率只有0.1%,那么系统预测所有人都是健康,即可达到99.9%的准确率。 但显然这样的…...
Linux -- 共享内存(2)
目录 命令 ipcs -m : 命令 ipcrm -m shmid: 共享内存的通信: 为什么共享内存更高效? 代码: ShmClient.cc: ShmServer.cc: 结果: 如何让共享内存实现同步? 代码&a…...
云函数实现发送邮件,以qq邮箱为例
云函数实现发送邮件,前端传参调用发送邮件即可。以qq邮箱为例。 1、开启qq邮箱的smtp服务并且生成授权码,操作界面如下图: 2、在腾讯云新建一个云函数代码如下: const nodemailer require("nodemailer");// 云函数入口函数 export…...
Kafka如何控制消费的位置?
大家好,我是锋哥。今天分享关于【Kafka如何控制消费的位置?】面试题?希望对大家有帮助; Kafka如何控制消费的位置? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在 Kafka 中,控制消费位置主要通过以下几个机制来实…...
电子销售网站模板/百度推广基木鱼
昨天,学习了Jar包的打包过程,现在打算记录一下,如何在Eclipse中导入外部Jar包。 第一步:在项目中鼠标右键>>New>>点击Folder。 第二步:在弹出窗口将Folder name命名为lib,点击确定。 第三步&am…...
然后做网站/搜索引擎优化专员
https://blog.csdn.net/weixin_41796631/article/details/83051966 父组件: 子组件...
腾讯公告最新官方消息/搜索引擎优化策略有哪些
今天,我们开始学习运维自动化工具Ansible。 一、Ansible原理 1.1 什么是Ansible Ansible一种集成IT系统的配置管理、应用部署、执行特定任务的开源平台/框架。基于Python语言实现,核心模块包括:jinja2、PyYAML和paramiko。Ansible允许重复…...
用虚拟机做服务器搭建网站/优化网站内容的方法
C#剪切板 Clipboard类 我们现在先来看一下官方文档的介绍 位于:System.Windows.Forms 命名空间下 Provides methods to place data on and retrieve data from the system Clipboard. This class cannot be inherited. 提供一些方法来存放数据和取回数据从系统的剪切板…...
用织梦做模板网站/脑白金网络营销
为什么80%的码农都做不了架构师?>>> 试用过boa constructor、wxglade、wxformBuilder等多个wxpython环境,若要将gui的 RAD和代码功能结合起来,达到像pyqt 的IDE eric4 那样的成熟开发效果,最好的还是 wxpython wxfor…...
创新型的赣州网站建设/互联网创业项目
在C Primer 第五版这本书上的1.5.2练习部分的1.23,有个题目是:读取多条销售记录,并统计每个ISBN(每本书)的销售记录。 在这里我简化了思想:读取并统计每种字符串的的个数 #include <iostream> using…...