【Springboot】介紹啟動類和啟動過程

【Springboot】介紹啟動類和啟動過程

  • 【一】Spring Boot 啟動類的注解
    • 【1】核心注解:@SpringBootApplication
      • (1)?@SpringBootConfiguration?:Spring容器會從該類中加載Bean定義
      • (2)?@EnableAutoConfiguration?:自動配置依賴
      • (3)?@ComponentScan?:?自動掃描并注冊Bean
    • 【2】其他常用注解(可根據需要添加)
    • 【3】@MapperScan
    • 【4】自動裝配原理
      • (1)自動裝配的核心思想
      • (2)實現原理的核心組件
  • 【二】Spring Boot 項目啟動的詳細流程
    • 【1】?啟動 Main 方法?
    • 【2】?創建 SpringApplication 實例?:
    • 【3】?運行 SpringApplication 實例(run方法)??:這是最復雜的核心階段。
  • 【三】Spring Boot 生命周期中的擴展點及使用案例
    • 【1】Application Events(應用事件) - 觀察者模式
    • 【2】ApplicationContextInitializer(應用上下文初始化器)
    • 【3】CommandLineRunner / ApplicationRunner
    • 【4】Spring Bean 生命周期鉤子
  • 【四】Spring Bean 生命周期中的重要組件
    • 【1】BeanPostProcessor (BPP) - 容器級后處理器?
    • 【2】BeanFactoryPostProcessor (BFPP) - 工廠級后處理器?
    • 【3】Aware 接口族 - 感知接口?
    • 【4】生命周期回調注解/接口?
    • 【5】生命周期執行順序

【一】Spring Boot 啟動類的注解

Spring Boot 啟動類通常就是一個標注了 @SpringBootApplication的類,但這個注解是一個組合注解(Composite Annotation)?,理解它包含的元注解是關鍵。

【1】核心注解:@SpringBootApplication

這是啟動類上唯一必須的注解,它整合了三個核心注解的功能:

(1)?@SpringBootConfiguration?:Spring容器會從該類中加載Bean定義

(1)?作用?:表明當前類是一個配置類。它的底層是 @Configuration,這意味著Spring容器會從該類中加載Bean定義(@Bean注解的方法)。
(2)?為什么不用 @Configuration?:@SpringBootConfiguration是Spring Boot提供的,語義上更明確地指出這是主配置類,但在功能上與 @Configuration無異。

(2)?@EnableAutoConfiguration?:自動配置依賴

(1)?作用?:?啟用Spring Boot的自動配置機制。這是Spring Boot魔法(Convention over Configuration)的核心。
(2)?原理?:這個注解會通知Spring Boot根據你添加的jar包依賴(如classpath下是否存在DataSource、SpringMVC等類),自動猜測并配置你需要的Bean。例如,當你引入了spring-boot-starter-web,它會自動配置Tomcat和Spring MVC。

(3)?@ComponentScan?:?自動掃描并注冊Bean

(1)?作用?:?自動掃描并注冊Bean。默認會掃描啟動類所在包及其所有子包下的所有組件,包括@Component, @Service, @Repository, @Controller等注解的類,并將它們注冊到Spring容器中。
(2)?重要提示?:這是為什么通常要把啟動類放在項目根包(root package)下的原因。如果放在一個很深的包里,@ComponentScan可能無法掃描到其他重要的組件。

【2】其他常用注解(可根據需要添加)

雖然 @SpringBootApplication已經足夠,但在某些場景下,你可能會在啟動類上額外添加一些注解。
(1)?@EnableScheduling?
?作用?:啟用Spring的定時任務功能。添加后,可以使用 @Scheduled注解來創建定時任務。

(2)?@EnableAsync?
?作用?:啟用Spring的異步方法執行功能。添加后,可以使用 @Async注解來標記異步執行的方法。

(3)?@EnableTransactionManagement?
?作用?:啟用注解式事務管理。不過,當Spring Boot檢測到存在事務管理器(如引入了JDBC或JPA starter)時,此功能實際上是默認開啟的。顯式添加此注解只是為了代碼意圖更清晰。

(4)?@EnableCaching?
?作用?:啟用Spring的注解驅動緩存功能。添加后,可以使用 @Cacheable, @CacheEvict等注解。

(5)?@Import?
?作用?:用于導入其他配置類(通常是@Configuration類),這些配置類可能不在@ComponentScan的掃描路徑下。例如:@Import({CustomConfig.class, AnotherConfig.class})。

?總結?:對于大多數標準應用,?只使用 @SpringBootApplication注解就足夠了。其他注解如 @EnableScheduling等,應根據具體功能需求選擇性添加。

【3】@MapperScan

@MapperScan注解的主要目的是告訴 MyBatis 應該去哪個或哪些包路徑下掃描 Mapper 接口,并自動將其注冊為 Spring 容器中的 Bean(MapperFactoryBean)?。
(1)?解決了什么問題???
在沒有這個注解之前,你需要在每個 Mapper 接口上手動添加 @Mapper注解,或者手動配置 MapperFactoryBean,非常繁瑣。@MapperScan通過包掃描的方式,實現了批量、自動的注冊,極大簡化了配置。

(2)?底層機制:??
當 Spring 容器啟動時,它會處理 @MapperScan注解。MyBatis-Spring 整合模塊會為指定的包路徑創建 ClassPathMapperScanner,該掃描器會找到所有接口,并為每個接口動態創建一個 MapperFactoryBean的 BeanDefinition 注冊到 Spring 容器中。MapperFactoryBean是一個 FactoryBean,它的 getObject()方法會使用 SqlSession為原始 Mapper 接口創建一個動態代理實例,并將這個代理實例作為 Bean 交給 Spring 管理。這就是為什么你可以在 Service 層直接 @Autowired一個接口的原因。

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import @SpringBootApplication// 方式一:直接掃描一個包
@SpringBootApplication
@MapperScan("com.example.demo.mapper")
public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}
}// 方式二:掃描多個包
@MapperScan(basePackages = {"com.example.mapper", "com.example.other.dao"})// 方式三:類型安全的掃描(推薦)
// 創建一個空的標記接口,放在 com.example.mapper 包下
public interface MapperScanMarker {// 無任何方法,僅作為包路徑標記
}@SpringBootApplication
// 掃描標記接口所在的包
@MapperScan(basePackageClasses = MapperScanMarker.class)
public class DemoApplication {// ...
}

【4】自動裝配原理

(1)自動裝配的核心思想

?要解決的問題:?? 傳統 Spring 應用需要大量手動配置(如 XML、Java Config)來集成第三方庫或框架(例如數據源、事務管理器、MVC 等)。這個過程繁瑣且容易出錯。

?解決方案:?? Spring Boot 自動裝配通過預先定義的條件,在檢測到項目的特定依賴、配置和類路徑后,自動為應用注入所需的 Bean 并完成配置。簡單來說,就是 ??“如果我在類路徑上看到了 X,并且你沒有自己配置 Y,那么我就自動給你配置一個默認的 Y”?。

(2)實現原理的核心組件

(1)@SpringBootApplication與 @EnableAutoConfiguration
一切的起點是主啟動類上的 @SpringBootApplication注解。它是一個組合注解?(Composite Annotation),其核心功能之一由 @EnableAutoConfiguration提供。

@SpringBootApplication // 這是一個元注解,整合了其他注解的功能
public class MyApplication {public static void main(String[] args) {SpringApplication.run(MyApplication.class, args);}
}

@EnableAutoConfiguration本身又是一個開關注解,它通過 @Import導入了最核心的加載器:AutoConfigurationImportSelector。

(2)AutoConfigurationImportSelector
這個類是自動裝配的大腦。它的核心任務是決定需要導入哪些自動配置類。
?工作原理?:AutoConfigurationImportSelector會讀取項目 classpath 下所有 JAR 包中的 ?META-INF/spring.factories? 文件。
?關鍵文件?:在 spring-boot-autoconfigure-x.x.x.x.jar中,META-INF/spring.factories文件是一個鍵值對形式的配置文件。其中 EnableAutoConfiguration這個 key 后面列出了一長串的自動配置類(XXXAutoConfiguration)。
?spring.factories文件片段示例:??

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\
# ... 省略上百個配置類
org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration

AutoConfigurationImportSelector會獲取所有這些配置類的全限定名,并將它們作為候選配置類。

(3)@Conditional條件注解家族 - ?靈魂所在?
僅僅將候選配置類全部加載是不行的,Spring Boot 需要根據當前應用的環境來智能判斷哪些配置類應該真正生效。這就是 @Conditional系列注解的作用。

這些注解是自動裝配的“開關”,它們會在配置類或 Bean 被加載前進行條件判斷,只有滿足所有條件,配置才會生效。

(4)XXXAutoConfiguration自動配置類
這些是具體的執行者。每個 XXXAutoConfiguration都是一個標準的 ?Spring 配置類?(@Configuration),其內部使用 @Bean方法來定義組件,并且方法上通常裝飾著各種 @Conditional注解。

【二】Spring Boot 項目啟動的詳細流程

Spring Boot 的啟動流程可以看作是傳統 Spring 應用啟動流程的一個高度封裝和自動化版本。其核心是 SpringApplication.run(Application.class, args)方法。
以下是其詳細步驟:

【1】?啟動 Main 方法?

JVM 調用應用程序的 main方法。

【2】?創建 SpringApplication 實例?:

(1)在 run方法內部,首先會創建一個 SpringApplication實例。
(2)這個實例會進行一些初始化工作,例如:
1-?推斷應用類型?:判斷是普通的Servlet應用(Spring MVC)還是響應式Web應用(WebFlux)。
?2-初始化器(Initializers)??:加載 META-INF/spring.factories文件中配置的 ApplicationContextInitializer。
?3-監聽器(Listeners)??:加載 META-INF/spring.factories文件中配置的 ApplicationListener(應用監聽器)。這些監聽器將用于接收整個啟動過程中發布的各種事件。

【3】?運行 SpringApplication 實例(run方法)??:這是最復雜的核心階段。

(1)?a. 啟動計時器 & 發布開始事件?:啟動一個計時器,并發布 ApplicationStartingEvent事件。此時容器還未創建,任何Bean都未初始化。
(2)?b. 準備環境(Environment)??:創建并配置應用運行環境(Environment),讀取所有配置源(application.properties/yaml、系統屬性、環境變量等)。發布 ApplicationEnvironmentPreparedEvent事件。
(3)?c. 創建應用上下文(ApplicationContext)??:根據第一步推斷的應用類型,創建對應的 ApplicationContext(例如,對于Servlet應用,創建 AnnotationConfigServletWebServerApplicationContext)。
(4)?d. 準備應用上下文?:
將環境(Environment)設置到上下文中。
執行所有 ApplicationContextInitializer的 initialize方法,對上下文進行自定義初始化。
發布 ApplicationContextInitializedEvent事件。
(5)?e. 刷新應用上下文(核心中的核心)??:調用上下文的 refresh()方法。這一步完成了傳統Spring應用容器的所有初始化工作:
?加載Bean定義?:解析啟動類(因為它是@Configuration),執行@ComponentScan掃描并注冊所有Bean定義。
?執行自動配置?:執行 @EnableAutoConfiguration邏輯,加載 spring-boot-autoconfigurejar 包中 META-INF/spring.factories文件里的所有自動配置類(XXXAutoConfiguration),根據條件(@ConditionalOnXxx)判斷是否需要配置相應的Bean。
?初始化Bean?:實例化所有非懶加載的單例Bean。
(6)?f. 后置處理?:執行 CommandLineRunner和 ApplicationRunner接口的實現Bean。
(7)?g. 啟動完成?:發布 ApplicationStartedEvent事件,啟動計時器停止,打印啟動耗時日志。
整個流程伴隨著事件的發布,允許開發者通過監聽這些事件在特定階段插入自定義邏輯。

【三】Spring Boot 生命周期中的擴展點及使用案例

Spring Boot 在整個生命周期中提供了大量“鉤子”(Hook),允許開發者介入并執行自定義邏輯。以下是一些最重要的擴展點:

【1】Application Events(應用事件) - 觀察者模式

通過實現 ApplicationListener接口或使用 @EventListener注解來監聽特定事件。
?常用事件?:
ApplicationStartingEvent:應用剛啟動,任何處理都還未進行。
ApplicationEnvironmentPreparedEvent:環境已準備完畢,上下文還未創建。
ApplicationContextInitializedEvent:上下文已創建且初始化器已被調用,但Bean定義還未加載。
ApplicationPreparedEvent:Bean定義已加載,但Bean還未實例化。
ApplicationStartedEvent:上下文已刷新,所有Bean已實例化,CommandLineRunner/ApplicationRunner還未執行。
ApplicationReadyEvent:應用已完全啟動,可以正常接收請求。
?案例:在應用啟動成功后打印一條日志?java

import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;@Component
public class StartupNotifier {@EventListener(ApplicationReadyEvent.class)public void onAppReady() {System.out.println("🎉 Application is now ready and can serve traffic!");// 可以在這里執行一些啟動后的檢查,比如檢查數據庫連接狀態等}
}

【2】ApplicationContextInitializer(應用上下文初始化器)

在 ApplicationContext刷新(refresh)之前,對其執行自定義的初始化操作。
?案例:在上下文準備階段設置一個自定義屬性?java

import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;public class MyInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {@Overridepublic void initialize(ConfigurableApplicationContext applicationContext) {// 向環境中添加一個屬性applicationContext.getEnvironment().getSystemProperties().put("myCustomProperty", "initialized");}
}

?注冊方式?:需要在 META-INF/spring.factories文件中注冊。

復制org.springframework.context.ApplicationContextInitializer=com.example.MyInitializer

【3】CommandLineRunner / ApplicationRunner

在應用上下文刷新完成后、應用完全啟動之前,執行一些特定的代碼。非常適合進行數據初始化、緩存預熱等操作。兩者功能幾乎一樣,區別在于參數:
CommandLineRunner:提供原始的字符串數組參數 String… args(即main方法的args)。
ApplicationRunner:提供更結構化的 ApplicationArguments對象來解析參數。
?案例:應用啟動后初始化一些數據?java

import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;@Component
public class DataLoader implements CommandLineRunner {private final UserRepository userRepository;public DataLoader(UserRepository userRepository) {this.userRepository = userRepository;}@Overridepublic void run(String... args) throws Exception {// 檢查數據庫是否已有數據,如果沒有則插入默認數據if (userRepository.count() == 0) {User admin = new User("admin", "admin@example.com");userRepository.save(admin);System.out.println("Initial admin user created.");}}
}

【4】Spring Bean 生命周期鉤子

這是 Spring 框架本身的擴展點,在 Spring Boot 中同樣適用。
@PostConstruct:在Bean的依賴注入完成后,初始化方法(InitializingBean.afterPropertiesSet)之前執行。
InitializingBean接口:實現 afterPropertiesSet()方法,在所有屬性設置完成后執行。
@PreDestroy:在Bean被容器銷毀之前執行。
?案例:Bean初始化后連接資源?java

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;@Component
public class ResourceConnector {@PostConstructpublic void connect() {System.out.println("Connecting to external resource...");// 初始化連接}@PreDestroypublic void disconnect() {System.out.println("Disconnecting from external resource...");// 關閉連接,釋放資源}
}

【四】Spring Bean 生命周期中的重要組件

【1】BeanPostProcessor (BPP) - 容器級后處理器?

(1)?作用?:這是Spring框架最強大、最核心的擴展接口。它作用于整個ApplicationContext,對所有Bean的初始化過程進行攔截和增強。你可以把它想象成一個“Bean加工流水線”。
(2)?兩個核心方法?:
1-postProcessBeforeInitialization(Object bean, String beanName):在Bean的初始化回調方法?(如@PostConstruct)之前執行。可以對Bean進行包裝或替換(例如返回一個代理對象,AOP就是基于此實現的)。
2-postProcessAfterInitialization(Object bean, String beanName):在Bean的初始化回調方法之后執行。此時Bean已基本完成初始化。
(3)?重要實現?:AutowiredAnnotationBeanPostProcessor(處理@Autowired注解)、CommonAnnotationBeanPostProcessor(處理@PostConstruct、@Resource等)、AnnotationAwareAspectJAutoProxyCreator(負責AOP動態代理)。

【2】BeanFactoryPostProcessor (BFPP) - 工廠級后處理器?

(1)?作用?:在Bean實例化之前,可以讀取、修改Bean的定義(BeanDefinition)。它操作的是“藍圖”,而不是Bean實例本身。
(2)?核心方法?:postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
(3)?經典案例?:PropertySourcesPlaceholderConfigurer(處理 ${…}占位符)就是在此時將Bean定義中的占位符替換為實際的屬性值。

【3】Aware 接口族 - 感知接口?

?(1)作用?:讓Bean能“感知”到容器本身和某些特定的資源。這些接口的回調發生在BeanPostProcessor之前,初始化方法之后。
(2)?常用接口?:
1-BeanNameAware:感知自己在容器中的Bean名稱。
2-ApplicationContextAware:感知自己所在的ApplicationContext(這是手動獲取Bean的一種方式)。
3-BeanFactoryAware:感知創建自己的BeanFactory。

【4】生命周期回調注解/接口?

(1)?作用?:定義Bean自身初始化和銷毀時的行為。
(2)?初始化?:
?JSR-250注解?:@PostConstruct(推薦使用,標準注解)。
?Spring接口?:InitializingBean及其 afterPropertiesSet()方法。
?XML配置?:init-method屬性。
(3)?銷毀?:
?JSR-250注解?:@PreDestroy(推薦使用)。
?Spring接口?:DisposableBean及其 destroy()方法。
?XML配置?:destroy-method屬性。

【5】生命周期執行順序

?執行順序?:BeanFactoryPostProcessor-> BeanPostProcessor的Before-> Aware接口 -> @PostConstruct-> InitializingBean-> init-method-> BeanPostProcessor的After-> … -> @PreDestroy-> DisposableBean-> destroy-method。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/922038.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/922038.shtml
英文地址,請注明出處:http://en.pswp.cn/news/922038.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Gears實測室:第一期·音游跨設備性能表現與工具價值實踐

在音游品類中&#xff0c;《跳舞的線》以 “音樂與操作節奏深度綁定” 的玩法特性&#xff0c;對設備性能提出了特殊要求 —— 穩定的幀率與低延遲的渲染響應&#xff0c;直接影響玩家對音符時機的判斷&#xff0c;一旦出現卡頓或幀波動&#xff0c;易導致操作失誤&#xff0c;…

格式刷+快捷鍵:Excel和WPS表格隔行填充顏色超方便

有時候我們會對Excel或WPS表格的數據區域每隔一行填充一個底紋&#xff0c;便于閱讀和查看。可以使用條件格式搭配公式實現&#xff0c;也可以手動設置。通常手動設置的時候是先設置一行&#xff0c;然后再雙擊格式刷應用。可以有更快的方式&#xff1a;先設置一行底紋&#xf…

將現有Spring Boot項目作為模塊導入到另一個Spring Boot項目

將現有Spring Boot項目作為模塊導入到另一個Spring Boot項目的操作步驟如下&#xff1a;?項目結構調整?將待導入的項目文件夾復制到主項目的根目錄下修改子模塊目錄名保持命名規范&#xff08;如ms-xxx格式&#xff09;?父POM配置?在主項目的pom.xml中添加<modules>聲…

激光頻率梳 3D 輪廓測量 - 銑刀刀片的刀口鈍化值 R 的測量

一、引言銑刀刀片的刀口鈍化值 R 是影響切削性能的關鍵參數&#xff0c;其精度直接關系到工件表面質量與刀具壽命。傳統測量方法在面對微米級鈍化圓角時存在分辨率不足、接觸式測量易損傷刃口等問題。激光頻率梳 3D 輪廓測量技術憑借飛秒級時頻基準與亞微米級測量精度&#xff…

3-10〔OSCP ? 研記〕? WEB應用攻擊?XSS攻擊理論基礎

鄭重聲明&#xff1a; 本文所有安全知識與技術&#xff0c;僅用于探討、研究及學習&#xff0c;嚴禁用于違反國家法律法規的非法活動。對于因不當使用相關內容造成的任何損失或法律責任&#xff0c;本人不承擔任何責任。 如需轉載&#xff0c;請注明出處且不得用于商業盈利。 …

《嵌入式硬件(四):溫度傳感器DS1820》

一、DS1820的引腳DS1820單總線數字溫度計&#xff1a;異步串行半雙工特性&#xff1a;1&#xff09;獨特的單線接口&#xff0c;只需 1 個接口引腳即可通信2&#xff09;多點&#xff08;multidrop&#xff09;能力使分布式溫度檢測應用得以簡化3&#xff09;不需要外部元件4&a…

langchain 輸出解析器 Output Parser

示例中使用的公共代碼&#xff1a; from langchain_deepseek import ChatDeepSeek chat ChatDeepSeek(model"deepseek-chat",temperature0,api_keyAPI_KEY, )使用方法&#xff1a; 引入解析器實例化解析器調用解析器的get_format_instructions()獲得提示詞&#xff…

LeetCode算法日記 - Day 37: 驗證棧序列、N叉樹的層序遍歷

目錄 1. 驗證棧序列 1.1 題目解析 1.2 解法 1.3 代碼實現 2. N叉樹的層序遍歷 2.1 題目解析 2.2 解法 2.3 代碼實現 1. 驗證棧序列 https://leetcode.cn/problems/validate-stack-sequences/description/ 給定 pushed 和 popped 兩個序列&#xff0c;每個序列中的 值…

金融數據庫--3Baostock

一、 Baostock 是什么&#xff1f;Baostock&#xff08;寶碩股票&#xff09;是一個免費、開源的證券數據平臺&#xff08;SDK&#xff09;&#xff0c;旨在為金融量化投資者、研究人員和學生提供穩定、準確、易用的A股歷史數據和相關金融數據。其核心是一個 Python 庫&#xf…

微信小程序-1-微信開發者工具環境搭建和初始化創建項目

文章目錄1 小程序概述1.1 什么是微信小程序1.2 大前端概念1.3 賬號注冊1.4 開發流程1.5 小程序成員2 創建項目2.1 創建項目流程2.2 創建項目2.3 本地開發支持http3 項目目錄3.1 項目目錄結構3.2 配置文件3.2.1 app.json(全局配置)3.2.2 xxx.json(頁面配置)3.2.3 project.config…

Go語言開發AI應用

為什么選擇Go語言開發AI應用在人工智能快速發展的今天&#xff0c;選擇合適的編程語言對于AI應用的成功至關重要。雖然Python長期以來被認為是AI開發的首選語言&#xff0c;但Go語言正在逐漸嶄露頭角&#xff0c;成為AI應用開發的有力競爭者。Go語言的核心優勢1. 卓越的性能表現…

10. 游戲開發中的TCP與UDP

1.TCP和UDP 2.TCP為什么慢于UDP 3.可靠UDP1.TCP和UDP 1).通過打電話的方式說明TCP和UDPa.TCP(傳輸控制協議), 就像打電話- 需要先撥號, 接通, 問候(建立連接)- 你一句, 我一句, 對方沒有聽清會要求你重復(確認與重傳)- 保證對話有條不紊, 內容準確無誤(可靠, 有序)- 如果信號不…

CMap常用函數

CMap 是 MFC 中用于存儲鍵值對&#xff08;key-value&#xff09;的關聯容器類&#xff0c;類似于 C 標準庫中的 std::map&#xff0c;但依賴 MFC 框架實現。它采用哈希表&#xff08;Hash Table&#xff09;作為底層數據結構&#xff0c;支持高效的鍵值查找、插入和刪除操作。…

Rocky9.0去堆疊雙發arp(支持“ARP 廣播雙發”)

摘要 在去堆疊/MLAG 場景下&#xff0c;默認 bonding 只會以單口回復 ARP&#xff0c;另一臺交換機收不到 ARP Reply。本文在 Linux bonding 驅動中增加參數 arp_broadcast_mode&#xff0c;當開啟時對 ARP 包臨時切換到 廣播模式&#xff0c;實現雙口同時發 ARP Reply。文內提…

網頁連接攝像頭

攝像機處理 <!-- camera_solve.html --> <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>…

FPGA雷達信號處理之:自適應門限閾值

一、原理 參考這個博主&#xff0c;講的很仔細&#xff1a;基于脈沖功率的雷達脈沖參數檢測原理詳解 二、FPGA實現 使用system generator搭建算法模型如下&#xff1a; 在這里&#xff0c;濾波器窗長度為8&#xff0c;原博主設置為50效果更好&#xff0c;門限公式如下&#xf…

Vue 中實現選中文本彈出彈窗的完整指南

在現代 Web 應用中&#xff0c;選中文本后顯示相關操作或信息是一種常見的交互模式。本文將詳細介紹如何在 Vue 中實現選中文本后彈出彈窗的功能&#xff0c;包括其工作原理、多種實現方式以及實際項目中的應用示例。 一、實現原理 1. 文本選中檢測機制 瀏覽器提供了 Select…

第4節-排序和限制-FETCH

摘要: 在本教程中&#xff0c;你將學習如何使用 PostgreSQL 的 FETCH 子句從查詢中檢索部分行。 PostgreSQL FETCH 簡介 在 PostgreSQL 中&#xff0c;OFFSET 子句的作用類似于 LIMIT 子句。FETCH 子句允許你限制查詢返回的行數。 LIMIT 子句并非 SQL 標準的一部分。不過&#…

洛谷 P2680 [NOIP 2015 提高組] 運輸計劃(二分答案 + 樹上差分)

題目鏈接題目概括與評價 很經典&#xff0c;突破口藏的很深&#xff0c;求最小值這里&#xff0c;是問題切入點&#xff0c;想到用二分答案&#xff0c;然后思考怎么寫 f_check 函數。二分答案樹上差分。代碼 #include <iostream> #include <vector> #include <…

接力鄧承浩,姜海榮能講好深藍汽車新故事嗎?

出品 | 何璽排版 | 葉媛深藍汽車迎來新話事人。9月5日&#xff0c;新央企長安汽車旗下品牌深藍汽車傳出新的人事調整。多家業內媒體報道稱&#xff0c;榮耀前中國區CMO姜海榮已正式加入長安汽車&#xff0c;并出任旗下深藍汽車CEO一職。原CEO鄧承浩則升任深藍汽車董事長&#x…