浅析 Spring 启动过程:从源码到核心方法
浅析 Spring 启动过程:从源码到核心方法
- 一、Spring 注解方式启动类 Demo
- 二、Spring 启动过程源码解析
- AnnotationConfigApplicationContext构造函数
- refresh()方法详解
- 三、refresh()的核心方法/步骤
- obtainFreshBeanFactory() - 获取Bean工厂
- prepareBeanFactory(beanFactory) - 配置 Bean 工厂
- invokeBeanFactoryPostProcessors() - 调用注册的BeanFactoryPostProcessor实现类
- finishBeanFactoryInitialization() - 实例化、初始化所有剩余的单例 Bean【重要】【重要】【重要】

在 Java 企业级开发中,Spring 框架是最常用的基础框架之一。了解 Spring 的启动过程,对于理解 Spring 的工作原理、优化应用性能以及排查问题都有着至关重要的作用。本文将结合纯 Spring 的注解方式启动类,深入解读 Spring 启动过程的源码,重点分析
refresh()
方法及其包含的关键步骤。
一、Spring 注解方式启动类 Demo
首先,我们创建一个简单的 Spring 项目,通过注解方式启动 Spring 容器。
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;@ComponentScan("com.coderzpw") // 扫描该路径下的包
@Configuration
public class AppConfig {public static void main(String[] args) {// Spring容器启动AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);// 可以在这里获取Bean进行后续操作// 容器关闭applicationContext.close();}
}
在上述代码中:
@Configuration
注解表明该类是一个配置类,用于替代传统的 XML 配置文件。@ComponentScan("com.coderzpw")
注解用于扫描指定包及其子包下的所有@Component
、@Service
、@Repository
、@Controller
等注解标注的类,并将它们注册为 Spring 容器中的 Bean。- 在
main
方法中,通过AnnotationConfigApplicationContext
来创建 Spring 应用上下文,传入配置类AppConfig.class
,从而启动 Spring 容器。
二、Spring 启动过程源码解析
当我们调用AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
时,Spring 的启动过程便开始了。接下来我们深入源码,一探究竟。
AnnotationConfigApplicationContext构造函数
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {this();register(annotatedClasses);refresh();
}
上述代码中:
this()
调用了无参构造函数,在无参构造函数中会初始化reader
和scanner
,用于读取配置类和扫描 Bean。register(componentClasses)
方法将传入的配置类注册到容器中。- 最后调用的
refresh()
方法是 Spring 启动过程的核心,它完成了 Spring 容器的初始化、Bean 的加载、配置的解析等一系列关键操作。
refresh()方法详解
对 BeanPostProcessor、BeanFactoryPostProcessor不熟悉的同学可以查看下面文章:
【Spring BeanFactoryPostProcessor:机制解读与代码实践】
【Spring BeanPostProcessor:机制解读与代码实践】
refresh()
方法位于AbstractApplicationContext
类中,其源码如下:
@Override
public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// 准备上下文环境,记录启动时间,标记活动状态等prepareRefresh();// 告诉子类刷新内部bean工厂ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// 准备bean工厂,设置一些属性,如类加载器、表达式解析器等prepareBeanFactory(beanFactory);try {// 允许子类在bean工厂准备好后进行进一步的设置postProcessBeanFactory(beanFactory);// 执行BeanFactoryPostProcessor接口的实现类,在bean实例化之前修改bean的定义invokeBeanFactoryPostProcessors(beanFactory);// 注册BeanPostProcessor接口的实现类,用于在bean实例化、配置和初始化前后进行处理registerBeanPostProcessors(beanFactory);// 初始化消息源,用于国际化等功能initMessageSource();// 初始化应用事件广播器initApplicationEventMulticaster();// 留给子类初始化其他特殊bean的钩子方法onRefresh();// 注册监听器到事件广播器registerListeners();// 实例化所有剩余的非惰性单例beanfinishBeanFactoryInitialization(beanFactory);// 完成刷新过程,发布容器刷新完成事件等finishRefresh();}catch (BeansException ex) {if (logger.isWarnEnabled()) {logger.warn("Exception encountered during context initialization - " +"cancelling refresh attempt: " + ex);}// Destroy already created singletons to avoid dangling resources.destroyBeans();// Reset 'active' flag.cancelRefresh(ex);// Propagate exception to caller.throw ex;}finally {// Reset common introspection caches in Spring's core, since we// might not ever need metadata for singleton beans anymore...resetCommonCaches();}}
}
refresh()
方法主要包含 12 个步骤,每个步骤都承担着不同的职责:
prepareRefresh();
【准备工作】
作用:在开始刷新容器之前,进行一些准备工作,如设置容器的启动时间、标记容器为活跃状态、清除缓存等。这是 IoC 容器启动的前奏,为后续的初始化操作做好准备。ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
【获取Bean工厂】
作用:获取或创建一个新的 BeanFactory 实例,BeanFactory 是 Spring IoC 容器的核心,负责管理 Bean 的定义和实例化。这个步骤是 IoC 容器启动的基础,后续的 Bean 加载和创建都依赖于BeanFactory。(重要:XML配置形势下,加载BeanDefinition就是在这个步骤,具体方法步骤:obtainFreshBeanFactory
->refreshBeanFactory
->loadBeanDefinitions
)prepareBeanFactory(beanFactory);
【配置 Bean 工厂】【为BeanFactory做基础的配置】
作用:对获取到的 BeanFactory 进行一些默认配置,如设置类加载器、添加默认的Bean 后置处理器(例如ApplicationContextAwareProcessor、ApplicationListenerDetector)、设置表达式解析器等。这些配置会影响后续 Bean 的创建和初始化过程。postProcessBeanFactory(beanFactory);
【后置处理 Bean 工厂】【子类做后置扩展处理】
作用:允许子类对 BeanFactory 进行额外的后置处理,例如注册自定义的 BeanPostProcessor 或 BeanFactoryPostProcessor。这为开发者提供了扩展 IoC 容器功能的机会。invokeBeanFactoryPostProcessors(beanFactory);
【调用注册的BeanFactoryPostProcessor实现类】
作用:调用所有注册的 BeanFactoryPostProcessor 实现类,这些处理器可以在 Bean 定义加载完成后、Bean 实例化之前对 Bean 定义进行修改。通过这个步骤,开发者可以动态地修改 Bean 的定义信息。registerBeanPostProcessors(beanFactory);
【注册 BeanPostProcessor的实现类】【只注册、不调用】
作用:注册所有的 BeanPostProcessor实现类,这些处理器会在Bean实例化、配置和初始化前后进行额外的处理。例如,AutowiredAnnotationBeanPostProcessor可以处理@Autowired注解,实现自动装配功能initMessageSource();
【初始化消息源】
作用:初始化消息源,用于支持国际化和消息解析。这在需要处理多语言的应用程序中非常有用。initApplicationEventMulticaster();
【初始化应用[事件广播器]】
[事件广播器]:负责将事件广播给所有注册的监听器。
[事件发布者(ApplicationEventPublisher)]:负责发布事件
[事件监听器(ApplicationListener)]:负责监听特定类型的事件
作用:初始化应用事件广播器,用于发布和监听应用程序中的事件。Spring 的事件机制允许组件之间进行松耦合的通信。onRefresh();
【留给子类扩展】【空实现】【子类特定的刷新操作】
作用:允许子类实现特定的刷新逻辑,例如在 WebApplicationContext 中,会创建和初始化 Servlet 上下文。registerListeners();
【注册监听器】
作用:注册应用程序中的事件监听器,这些监听器会监听由事件广播器发布的事件,并执行相应的处理逻辑。finishBeanFactoryInitialization(beanFactory);
【实例化所有剩余的单例 Bean】【Bean 实例化、初始化、BeanPostProcessor的执行】
作用:实例化所有剩余的单例 Bean,这是 IoC 容器启动的核心步骤之一。在这个过程中,BeanFactory 会根据 Bean 定义创建 Bean 实例,并进行依赖注入和初始化操作。finishRefresh();
【完成刷新】
作用:完成容器的刷新工作,清除缓存、发布容器刷新完成事件等。此时,IoC 容器已经完全启动并可以正常使用。
三、refresh()的核心方法/步骤
obtainFreshBeanFactory() - 获取Bean工厂
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {refreshBeanFactory(); // 触发BeanDefinition加载return getBeanFactory();
}
obtainFreshBeanFactory()
是Spring容器启动流程中的核心方法,其核心性体现在:
- BeanFactory生命周期起点:负责创建或刷新BeanFactory实例,是IoC容器诞生的起点
- 配置加载入口:触发XML配置的解析流程,将配置转化为可操作的
BeanDefinition
对象
BeanDefinition加载流程解析
1. 传统Spring项目(XML配置为例)
核心步骤:
refreshBeanFactory()
:销毁旧容器 → 创建DefaultListableBeanFactory
→ 加载BeanDefinition
loadBeanDefinitions()
:通过XmlBeanDefinitionReader
解析XML文件,生成BeanDefinition
并注册
源码示例:
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);// ....initBeanDefinitionReader(beanDefinitionReader);loadBeanDefinitions(beanDefinitionReader);
}
2. SpringBoot项目(注解驱动)
- 实现差异:
- 本质使用
GenericApplicationContext
代替AbstractRefreshableApplicationContext
obtainFreshBeanFactory()
仅设置序列化ID,不执行配置加载
- 本质使用
- 实际加载入口:
ConfigurationClassPostProcessor
(后置处理器)扫描@Configuration
类@ComponentScan
注解触发包扫描,动态注册BeanDefinition
prepareBeanFactory(beanFactory) - 配置 Bean 工厂
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {// 告诉内部 Bean 工厂使用上下文的类加载器等。beanFactory.setBeanClassLoader(getClassLoader());beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));// 注册ApplicationContextAwareProcessor (ApplicationContextAwareProcessor负责处理实现了ApplicationContextAware的类)beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));// // 注册早期后处理器,用于将内部 bean 检测为 ApplicationListeners。beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));// ...// 注册默认的 环境Beanif (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());}if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());}if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());}
}
核心配置:
- 设置类加载器
- 添加默认的Bean 后置处理器(例如
ApplicationContextAwareProcessor
、ApplicationListenerDetector
) - 注册默认的 环境bean
invokeBeanFactoryPostProcessors() - 调用注册的BeanFactoryPostProcessor实现类
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {// 【核心】调用 BeanFactoryPostProcessorsPostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)// ...
}
进入invokeBeanFactoryPostProcessors
:
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {// 【 1. 处理所有 BeanDefinitionRegistryPostProcessor(子接口)】if (beanFactory instanceof BeanDefinitionRegistry) {BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =new LinkedList<BeanDefinitionRegistryPostProcessor>();// 分阶段处理:PriorityOrdered → Ordered → 普通实现// 执行 PriorityOrdered invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);// 执行 OrderedinvokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry);// 执行 普通实现invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);}else {// Invoke factory processors registered with the context instance.invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);}// ...// 【 2. 处理所有 BeanFactoryPostProcessor】// 分阶段处理:PriorityOrdered → Ordered → 普通实现List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();List<String> orderedPostProcessorNames = new ArrayList<String>();List<String> nonOrderedPostProcessorNames = new ArrayList<String>();for (String ppName : postProcessorNames) {if (processedBeans.contains(ppName)) {// skip - already processed in first phase above}else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));}else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {orderedPostProcessorNames.add(ppName);}else {nonOrderedPostProcessorNames.add(ppName);}}// 执行 PriorityOrdered invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);// 执行 OrderedinvokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);// 执行 普通实现invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);// ...
}
具体执行方法:invokeBeanFactoryPostProcessors
/*** 调用给定的BeanFactoryPostProcessor bean。*/
private static void invokeBeanFactoryPostProcessors(Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {for (BeanFactoryPostProcessor postProcessor : postProcessors) {// 执行具体的postProcessBeanFactory方法postProcessor.postProcessBeanFactory(beanFactory);}
}
其中ConfigurationClassPostProcessor
是BeanFactoryPostProcessor
的子类,会在该阶段执行其后置处理逻辑。负责解析 @Configuration
类及其注解(如 @ComponentScan
、@Bean
),动态注册新的 BeanDefinition
ConfigurationClassPostProcessor
核心功能:
- 扫描配置类: 识别
@Configuration
类,解析其上的@ComponentScan
、@Import
等注解 - 处理条件注解: 根据
@Conditional
注解判断是否注册对应的BeanDefinition
finishBeanFactoryInitialization() - 实例化、初始化所有剩余的单例 Bean【重要】【重要】【重要】
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {// ...// 实例化所有剩余的 (非 lazy-init) 单例。【核心】【重要】【bean实例化 -> 属性填充 -> 初始化】beanFactory.preInstantiateSingletons();
}
finishBeanFactoryInitialization() 方法核心作用总结:
- 初始化基础服务
- 设置类型转换服务(
ConversionService
),处理@Value
和属性注入的类型转换
- 设置类型转换服务(
- 冻结 Bean 配置
- 调用
freezeConfiguration()
,停止修改BeanDefinition
,确保后续实例化过程的线程安全
- 调用
- 实例化非懒加载单例 Bean
- 遍历所有
BeanDefinition
,触发getBean()
实例化非抽象、单例且非懒加载的 Bean - 特殊处理
FactoryBean
:根据SmartFactoryBean.isEagerInit()
判断是否立即生成目标对象
- 遍历所有
- 初始化回调与扩展
- 触发
SmartInitializingSingleton.afterSingletonsInstantiated()
,在所有单例创建完成后执行自定义逻辑 - 处理
LoadTimeWeaverAware
接口,支持类加载期字节码增强(如 AspectJ LTW)
- 触发
- 资源回收与优化
- 释放临时类加载器(
TempClassLoader
),避免内存泄漏
- 释放临时类加载器(
该方法涉及 Spring IoC 最复杂的实例化阶段,包括 bean的实例化、属性填充(解决循环依赖)、BeanPostProcesser的前置处理(部分Aware处理逻辑)、bean的初始化、BeanPostProcesser的后置处理(AOP 代理的生成时机)等细节
一篇文章是讲解不清楚finishBeanFactoryInitialization()的,请期待后续总结 ✿ヽ(°▽°)ノ✿
相关文章:
浅析 Spring 启动过程:从源码到核心方法
浅析 Spring 启动过程:从源码到核心方法 一、Spring 注解方式启动类 Demo二、Spring 启动过程源码解析AnnotationConfigApplicationContext构造函数refresh()方法详解 三、refresh()的核心方法/步骤obtainFreshBeanFactory() - 获取Bean工厂prepareBeanFactory(be…...
5G + 区块链:技术巨浪下的新型数字生态!
5G + 区块链:技术巨浪下的新型数字生态! 1. 为什么 5G 和区块链的结合如此重要? 区块链和 5G 这两大技术近几年风头正劲,一个在去中心化数据管理上展现潜力,一个在高吞吐低延迟通信方面带来颠覆。这两者结合,意味着: 更快的数据传输,让区块链交易速度提升,摆脱“低 …...
时序数据库IoTDB分布式架构解析与运维指南
一、IoTDB分布式架构概述 分布式系统由一组独立的计算机组成,通过网络通信,对外表现为一个统一的整体。IoTDB的原生分布式架构将服务分为两个核心部分: ConfigNode(CN):管理节点,负责管理…...
CertiK荣获以太坊基金会两项资助,领跑zkEVM形式化验证
近日,以太坊基金会公布了2025年第一季度研究资助名单,全球最大的Web3.0安全公司CertiK荣获两项研究资助,源于zkEVM形式化验证竞赛。这不仅是以太坊扩展性战略的里程碑式事件,也进一步彰显了CertiK在零知识证明(ZKP&…...
c++和c的不同
c:面向对象(封装,继承,多态),STL,模板 一、基础定义与背景 C语言 诞生年代:20世纪70年代,Dennis Ritchie在贝尔实验室开发。主要特点: 过程式、结构化编程面向系统底层…...
光流 | Matlab工具中的光流算法
在MATLAB中,光流算法用于估计图像序列中物体的运动。以下是详细解释及实现步骤: 1. 光流算法基础 光流基于两个核心假设: 亮度恒定:同一物体在连续帧中的像素亮度不变。微小运动:相邻帧之间的时间间隔短,物体运动幅度小。常见算法: Lucas-Kanade (局部方法):假设局部窗…...
@Controller 与 @RestController-笔记
1.Controller与RestController对比 Spring MVC 中 Controller 与 RestController 的功能对比: Controller是Spring MVC中用于标识一个类作为控制器的标准注解。它允许处理HTTP请求,并返回视图名称,通常和视图解析器一起使用来渲染页面。而R…...
LeetCode 热题 100 105. 从前序与中序遍历序列构造二叉树
LeetCode 热题 100 | 105. 从前序与中序遍历序列构造二叉树 大家好,今天我们来解决一道经典的二叉树问题——从前序与中序遍历序列构造二叉树。这道题在 LeetCode 上被标记为中等难度,要求根据给定的前序遍历和中序遍历序列,构造并返回二叉树…...
IP地址查询助力业务增长
IP地址查询的技术基石 IP地址分为IPv4和IPv6,目前IPv4仍广泛应用,它由四个0-255的十进制数组成,如192.168.1.1。而IPv6为应对IPv4地址枯竭问题而生,采用128位地址长度,极大扩充了地址空间。IP地址查询主要依赖庞大的I…...
Nginx核心功能及同类产品对比
Nginx 作为一款高性能的 Web 服务器和反向代理工具,凭借其独特的架构设计和丰富的功能,成为互联网基础设施中不可或缺的组件。以下是其核心功能及与同类产品(如 HAProxy、LVS)的对比优势: 一、Nginx 核心功能 高性能架…...
抽奖系统-奖品-活动
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言获取奖品列表前端页面活动创建需求分析活动创建后端实现1-控制层实现及校验活动活动创建后端实现2-保存信息活动插入活动奖品插入 整合活动信息存入redis测试活…...
【Java】 volatile 和 synchronized 的比较及使用场景
在 Java 的并发编程中,volatile 和 synchronized 是两个常用的关键字,它们分别用于保证多线程环境中的 可见性 和 原子性,但它们的工作原理和适用场景却有所不同。今天,我们将深入探讨这两个关键字的异同,帮助大家理解…...
javaScript简单版
简介 JavaScript(简称:JS)是一门跨平台、面向对象的脚本语言,是用来控制网页行为,实现页面的交互效果。 JavaScript和Java是完全不同的语言,不论是概念还是设计。但是基础语法类似。 组成: ECMAScript:规定了JS基础语法核心知…...
三种常见接口测试工具(Apipost、Apifox、Postman)
三种常见接口测试工具(Apipost、Apifox、Postman)的用法及优缺点对比总结: 🔧 一、Apipost ✅ 基本用法 支持 RESTful API、GraphQL、WebSocket 等接口调试自动生成接口文档支持环境变量、接口分组、接口测试用例编写可进行前置…...
蓝桥杯13届国B 完全日期
题目描述。 如果一个日期中年月日的各位数字之和是完全平方数,则称为一个完全日期。 例如:2021 年 6 月 5 日的各位数字之和为 20216516,而 16 是一个完全平方数,它是 4 的平方。所以 2021 年 6 月 5 日是一个完全日期。 例如&…...
kafka connect 大概了解
kafka connect Introduction Kafka Connect is the component of Kafka that provides data integration between databases, key-value stores, search indexes, file systems, and Kafka brokers. kafka connect 是一个框架,用来帮助集成其他系统的数据到kafka…...
嵌入式培训之数据结构学习(三)gdb调试、单向链表练习、顺序表与链表对比
目录 一、gdb调试 (一)一般调试步骤与命令 (二)找段错误(无下断点的地方) (三)调试命令 二、单向链表练习 1、查找链表的中间结点(用快慢指针) 2、找出…...
MySQL——九、锁
分类 全局锁表级锁行级锁 全局锁 做全库的逻辑备份 flush tables with read lock; unlock tables;在InnoDB引擎中,我们可以在备份时加上参数–single-transaction参数来完成不加锁的一致性数据备份 mysqldump --single-transaction -uroot -p123456 itcast>…...
精益数据分析(57/126):创业移情阶段的核心要点与实践方法
精益数据分析(57/126):创业移情阶段的核心要点与实践方法 在创业的浩瀚征程中,每一个阶段都承载着独特的使命与挑战。今天,我们继续秉持共同进步的理念,深入研读《精益数据分析》,聚焦创业的首…...
服务器被打了怎么应对
云服务器遭受攻击该如何应对? 在互联网时代,不少使用云服务器的网络工作者常常会面临网络攻击的威胁。若云服务器未配置完善的防火墙,极易引发服务器宕机,甚至被封禁隔离(俗称“陷入黑洞”),进…...
Halcon案例(二):C#联合Halcon回形针以及方向
本案例分3部分 识别效果,分别显示识别前后识别后;代码展示,分别是Halcon源码和Halcon转为C#的代码代码解释(解释在源码中); 原图如下 识别后图像: 其中计算回形针与X轴之间的夹角 Halcon代码: * clip.hdev: Orientation of clips *识别图像中的回形针,并且计算回形针与X轴之间…...
Spyglass:跨时钟域同步(同步单元)
相关阅读 Spyglasshttps://blog.csdn.net/weixin_45791458/category_12828934.html?spm1001.2014.3001.5482 简介 同步单元方案可以用于控制/数据信号跨时钟域同步,该方案使用约束或参数将目标时钟域中单元指定为同步单元,如图1所示。 图1 同步单元方案…...
JAVA异常体系
在 Java 里,异常体系是其错误处理机制的核心内容,它能够帮助开发者有效应对程序运行时出现的各种意外状况。 异常体系的基本架构 它主要包含两个重要分支: Error(错误):这类异常是程序自身无法处理的严重…...
Milvus 视角看主流嵌入式模型(Embeddings)
嵌入是一种机器学习概念,用于将数据映射到高维空间,其中语义相似的数据被紧密排列在一起。嵌入模型通常是 BERT 或其他 Transformer 系列的深度神经网络,它能够有效地用一系列数字(称为向量)来表示文本、图像和其他数据…...
全面解析 Server-Sent Events(SSE)协议:从大模型流式输出到实时通信场景
全面解析 Server-Sent Events(SSE)协议:从大模型流式输出到实时通信场景 一、SSE 协议概述 Server-Sent Events(SSE) 是 HTML5 标准中定义的一种基于 HTTP 的服务器向客户端单向推送实时数据的协议。其核心特性包括&a…...
数据库系统概论|第七章:数据库设计—课程笔记
前言 本章讨论数据库设计的技术和方法,主要讨论基于关系数据库管理系统的关系数据库设计问题,而关于数据库的设计过程中,关于数据模型、关系模型等基本概念在前文中已经有详尽介绍,此处便不再赘述,本文主要围绕概念结…...
Java项目拷打(外卖+点评)
一、点评星球(黑马点评) 1、项目概述 1.1、项目简介 本项目是基于Spring Boot与Redis深度整合的前后端分离的点评平台。系统以Redis为核心技术支撑,重点解决高并发场景下的缓存穿透、击穿、雪崩等问题,涵盖商户展示、优惠券秒杀…...
MCP:开启AI的“万物互联”时代
MCP:开启AI的“万物互联”时代 ——从协议标准到生态革命的技术跃迁 引言:AI的“最后一公里”困境 在2025年的AI技术浪潮中,大模型已从参数竞赛转向应用落地之争。尽管模型能生成流畅的对话、创作诗歌甚至编写代码,但用户逐渐发现…...
【PostgreSQL数据分析实战:从数据清洗到可视化全流程】附录-D. 扩展插件列表(PostGIS/PostgREST等)
👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 附录D. PostgreSQL扩展插件速查表一、插件分类速查表二、核心插件详解三、安装与配置指南四、应用场景模板五、版本兼容性说明六、维护与优化建议七、官方资源与工具八、附录…...
Spring Boot拦截器详解:原理、实现与应用场景
精心整理了最新的面试资料和简历模板,有需要的可以自行获取 点击前往百度网盘获取 点击前往夸克网盘获取 一、拦截器概述 拦截器(Interceptor)是Spring MVC框架中用于对请求进行预处理和后处理的组件,主要作用于Controller层。相…...
万字解析:Java字符串
目录 一、 String类 1. String类的初始化 1.1 常用的三种构造String类的方式 1.2 String类如何存储字符串? 2. String类的常用功能方法 2.0 字符串长度的获取 2.1 String对象的比较 2.2 字符/字符串的查找 2.3 字符串的转化 2.4 字符 / 字符串的替换 2.5…...
0514得物、0509滴滴面试总结复盘
目前最欠缺的还是,编码不是很熟,很多都遇到过但是就是写不出来,或者靠背先写一点,然后去加,加的过程没考虑逻辑是不是对的,用滴滴面试官的一句话,就是多刷多练多编码! 第二块就是项目…...
记录算法笔记(20025.5.14)对称二叉树
给你一个二叉树的根节点 root , 检查它是否轴对称。 示例 1: 输入:root [1,2,2,3,4,4,3] 输出:true 示例 2: 输入:root [1,2,2,null,3,null,3] 输出:false 提示: 树中节点数目…...
AI大模型从0到1记录学习 linux day23
第 1 章 MySQL概述 1.1 基本概念 1.1.1 数据库是什么? 数据库(DB:Database):存储数据的地方。 1.1.2 为什么要用数据库? 应用程序产生的数据是在内存中的,如果程序退出或者是断电了,…...
用git下载vcpkg时出现Connection was reset时的处理
用git安装vcpkg时出现Connect was rest(如上图)。多谢这位网友的博文解决了问题: 通过:http.sslVerify false全局来设置,执行以下命令: git config --global http.sslVerify "false" 原文链接:…...
【数据库复习】SQL语言
一、SQL通用语法与分类 (一)SQL通用语法 SQL语句的格式通常较为规范,以关键字开头,如CREATE、SELECT、INSERT等,后跟具体的表名、字段名和条件等。在MySQL中,还可以使用help命令获取帮助信息,…...
二叉树——层序遍历
目录 实现层序遍历 判断是否为完全二叉树 实现层序遍历 除了先序遍历,中序遍历,后序遍历外,还可以对二叉树进行层序遍历。设二叉树的结点所在层数为1,层序遍历就是从所在二叉树的根结点出发,首先访问第一层的树根结点…...
Seata源码—2.seata-samples项目介绍
大纲 1.seata-samples的配置文件和启动类 2.seata-samples业务服务启动时的核心工作 3.seata-samples库存服务的连接池配置 4.Seata对数据库连接池代理配置的分析 5.Dubbo RPC通信过程中传递全局事务XID 6.Seata跟Dubbo整合的Filter(基于SPI机制) 7.seata-samples的AT事…...
企业数字化转型背景下的企业知识管理挑战与经验杂谈
一、引言 在数字化转型的浪潮下,企业知识管理正面临前所未有的挑战。随着数据量的急剧增长,企业内部积累的信息呈现出碎片化、分散化的趋势,传统的知识管理体系已难以有效应对这一变革。首先,信息碎片化问题日益严重,…...
第二章:磁盘管理与文件管理
一、磁盘管理 1.windows和Linux磁盘管理的区别 windows资源管理方式 系统一般安装在C盘 C盘下的"Windows"目录是操作系统的核心 C盘下的"Program Files"目录下安装软件 C盘下的"用户"目录是所有的用户,包括超级管理员也在其中 …...
Java版OA管理系统源码 手机版OA系统源码
Java版OA管理系统源码 手机版OA系统源码 一:OA系统的主要优势 1. 提升效率 减少纸质流程和重复性工作,自动化处理常规事务,缩短响应时间。 2. 降低成本 节省纸张、打印、通讯及人力成本,优化资源分配。 3. 规范管理 固化企…...
springboot踩坑记录
之前运行好端端的项目,今天下午打开只是添加了一个文件之后 再运行都报Failed to configure a DataSource: url attribute is not specified and no embedded datasource could be configured.Reason: Failed to determine a suitable driver class Action: Conside…...
SpringAI
机器学习: 定义:人工智能的子领域,通过数据驱动的方法让计算机学习规律,进行预测或决策。 核心方法: 监督学习(如线性回归、SVM)。 无监督学习(如聚类、降维)。 强化学…...
acwing 1488. 最短距离 超级源点 最短路 堆优化Dijkstra
经验总结 邻接表 节点1连接到节点2,权重为3。 节点1连接到节点3,权重为5。 节点2连接到节点4,权重为2。 g[1] {{2, 3}, {3, 5}} g[2] {{1, 3}, {4, 2}} g[3] {{1, 5}} g[4] {{2, 2}} vector<vector<PII>> g;题目背景 有 N…...
2002-2024年地级市新质生产力词频统计数据(46个关键词词频)
2002-2024年地级市新质生产力词频统计数据(46个关键词词频) 1、时间:2002-2024年 2、来源:ZF工作报告 3、指标:行政区划代码、年份、地区、所属省份、文本总长度、仅中英文-文本总长度、文本总词频-全模式、文本总词…...
院校机试刷题第二天:1479 01字符串、1701非素数个数
一、1479 01字符串 1.题目描述 2.解题思路 方法一:暴力法 模拟过程,列出几个数据来a[1]1, a[2]2, a[3]3, a[4]5以此类推,这就是斐波那契数列,每一项都等于前两项之和,确定好a[1], a[2]即可。 方法二:动…...
2011-2019年各省总抚养比数据
2011-2019年各省总抚养比数据 1、时间:2011-2019年 2、来源:国家统计局 3、指标:行政区划代码、地区、年份、总抚养比(人口抽样调查)(%) 4、范围:31省 5、指标解释:总抚养比也称总负担系数。指人口总体中非劳动年…...
3337|3335. 字符串转换后的长度 I(||)
1.字符串转换后的长度 I 1.1题目 3335. 字符串转换后的长度 I - 力扣(LeetCode) 1.2解析 递推法解析 思路框架 我们可以通过定义状态变量来追踪每次转换后各字符的数量变化。具体地,定义状态函数 f(i,c) 表示经过 i 次转换后࿰…...
【电路笔记 通信】8B/10B编码 高速数据传输的串行数据编码技术 论文第三部分 The 8B/10B coding map
0810逻辑总览 The 8B/10B coding map 图 1 展示了一个通信适配器接口,它由八条数据线 A、B、C、D、E、F、G、H(注意:使用大写字母表示)、一条控制线 K,以及一条以字节速率运行的时钟线 BYTECLK 组成。控制线 K 用于指…...
智能化双语LaTeX系统,分阶段系统性开发技术实现路径:目标是实现语义级编译和认知增强写作,推动跨文明知识表达
智能化双语LaTeX系统,分阶段系统性开发技术实现路径(D认为W可辅助各环节开发): 第一阶段:双语LaTeX引擎升级 1. 核心架构设计 Unicode深度支持 开发新一代XeLaTeX/LuaLaTeX内核 原生支持UTF-8编码(如汉…...