SpringBean模塊(二)bean初始化(2)和容器初始化順序的比較--引入ApplicationContextInitializer

前面介紹了獲取容器可以讓spring bean實現ApplicationContextAware,實際也是初始化執行了setApplicationContext接口,

初始化接口還可以借助一些注解或者spring bean的初始化方法,那么他們的執行順序是什么樣的呢?

一、驗證(沒有依賴關系時)是無序的

1、demo
下面新建三個class文件

分別使用ApplicationContextAware、@PostConstruct和InitializingBean

package com.bit.demo.test.bean;import com.bit.demo.dto.UserDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;@Slf4j
@Component
public class InitUserInitUtil implements ApplicationContextAware {private static UserDTO userDTO;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {log.info("初始化方法,ApplicationContextInitializer");UserDTO user = new UserDTO();user.setUserName("zs");user.setPassword("123456");this.userDTO = user;}public static UserDTO getUserDTO() {return userDTO;}
}
package com.bit.demo.test.bean;import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;@Component
@Slf4j
public class TestClass1 {@PostConstructpublic void init(){//項目啟動執行方法log.info("初始化方法, 使用PostConstruct");}
}
package com.bit.demo.test.bean;import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;@Component
@Slf4j
public class TestClass2 implements InitializingBean {@PostConstructpublic void initAgain() {log.info("初始化方法, 同時使用PostConstruct和InitializingBean");}@Overridepublic void afterPropertiesSet() throws Exception {log.info("初始化方法, 使用InitializingBean");}
}
? 啟動項目輸出
 .   ____          _            __ _ _/\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \\\/  ___)| |_)| | | | | || (_| |  ) ) ) )'  |____| .__|_| |_|_| |_\__, | / / / /=========|_|==============|___/=/_/_/_/:: Spring Boot ::                (v3.2.4)2025-03-28T10:56:01.574+08:00  INFO 13716 --- [           main] com.bit.demo.BitApplication              : Starting BitApplication using Java 17.0.11 with PID 13716 (C:\mydemo\bit-demo\target\classes started by Tina.Zhang in C:\code\cci-voice)
2025-03-28T10:56:01.576+08:00  INFO 13716 --- [           main] com.bit.demo.BitApplication              : No active profile set, falling back to 1 default profile: "default"
2025-03-28T10:56:02.209+08:00  INFO 13716 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 7777 (http)
2025-03-28T10:56:02.216+08:00  INFO 13716 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2025-03-28T10:56:02.217+08:00  INFO 13716 --- [           main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.19]
2025-03-28T10:56:02.258+08:00  INFO 13716 --- [           main] o.a.c.c.C.[.[localhost].[/bitDemo]       : Initializing Spring embedded WebApplicationContext
2025-03-28T10:56:02.258+08:00  INFO 13716 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 648 ms
Logging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter.
Initialization Sequence datacenterId:6 workerId:4_ _   |_  _ _|_. ___ _ |    _ 
| | |\/|_)(_| | |_\  |_)||_|_\ /               |         3.5.5 
2025-03-28T10:56:02.495+08:00  INFO 13716 --- [           main] c.bit.demo.test.bean.InitUserInitUtil    : 初始化方法,ApplicationContextInitializer
2025-03-28T10:56:02.496+08:00  INFO 13716 --- [           main] com.bit.demo.test.bean.TestClass1        : 初始化方法, 使用PostConstruct
2025-03-28T10:56:02.497+08:00  INFO 13716 --- [           main] com.bit.demo.test.bean.TestClass2        : 初始化方法, 同時使用PostConstruct和InitializingBean
2025-03-28T10:56:02.497+08:00  INFO 13716 --- [           main] com.bit.demo.test.bean.TestClass2        : 初始化方法, 使用InitializingBean
2025-03-28T10:56:02.718+08:00  INFO 13716 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 7777 (http) with context path '/bitDemo'
2025-03-28T10:56:02.723+08:00  INFO 13716 --- [           main] com.bit.demo.BitApplication              : Started BitApplication in 1.385 seconds (process running for 1.765)
2、考慮到路徑影響類的加載

前面的輸出順序是InitUserInitUtil > TestClass1 > TestClass2,正好和類路徑順序一致,考慮到類的路徑影響類的加載,現在TestClass1、TestClass2各copy出來一個,加個前綴Aa,排在InitUserInitUtil 的前面。

新增文件

再次啟動

可以看到Aa開頭的類日志先輸出了。

3、結論

ApplicationContextAware的setApplicationContext、@PostConstruct、

InitializingBean的afterPropertiesSet 他們的執行順序是隨機的。

4、錯誤引用

基于上面,AaTestClass1 >?AaTestClass2 >?InitUserInitUtil >?TestClass1 >?TestClass2

現在如果在AaTestClass2中利用InitUserInitUtil 獲取UserDTO:

package com.bit.demo.test.bean;import com.bit.demo.dto.UserDTO;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;@Component
@Slf4j
public class AaTestClass2 implements InitializingBean {@PostConstructpublic void initAgain() {log.info("初始化方法, 同時使用PostConstruct和InitializingBean");}@Overridepublic void afterPropertiesSet() throws Exception {log.info("初始化方法, 使用InitializingBean");UserDTO innitUser = InitUserInitUtil.getUserDTO();if(innitUser != null) {log.info("獲取user成功",innitUser);}else{log.info("獲取user失敗",innitUser);}}
}

因為此時InitUserInitUtil 還沒有初始化,獲取到的是null:

注意:

這也間接說明了,不要濫用ApplicationContextAware來獲取Bean,能自動獲取Bean的都通過Autowired等注解獲取,因為使用了注解spring自身會優化加載順序,讓被依賴的Bean先執行。在必須手動獲取如非spring bean中使用則不用考慮加載問題(非spring bean根本不會自動加載)。

5、使用自動裝配引入依賴關系來解決引用問題?

我們知道,使用@Autowired等自動裝配,可以讓被依賴的bean先執行。針對上面的問題,改寫下:

package com.bit.demo.test.bean;import com.bit.demo.dto.UserDTO;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
@Slf4j
public class AaTestClass2 implements InitializingBean {@Autowiredprivate InitUserInitUtil initUserInitUtil;@PostConstructpublic void initAgain() {log.info("初始化方法, 同時使用PostConstruct和InitializingBean");}@Overridepublic void afterPropertiesSet() throws Exception {log.info("初始化方法, 使用InitializingBean");UserDTO innitUser = InitUserInitUtil.getUserDTO();if(innitUser != null) {log.info("獲取user成功",innitUser.toString());}else{log.info("獲取user失敗",innitUser);}}
}

這時啟動打印:AaTestClass1??>?InitUserInitUtil > AaTestClass2? >?TestClass1 >?TestClass2,

對比上面的AaTestClass1 >?AaTestClass2 >?InitUserInitUtil >?TestClass1 >?TestClass2,可見InitUserInitUtil 提前加載了?

6、引入ApplicationContextInitializer

上面增加依賴關系可以解決bean的引用問題。

那如果就希望InitUserInitUtil做為一個最底層的bean,能夠在其他業務bean之前加載,還可以使用

ApplicationContextInitializer。
package com.bit.demo.test.bean;import com.bit.demo.dto.UserDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.stereotype.Component;@Slf4j
@Component
public class InitUserInitUtil implements ApplicationContextInitializer {private static UserDTO userDTO;public static UserDTO getUserDTO() {return userDTO;}@Overridepublic void initialize(ConfigurableApplicationContext applicationContext) {log.info("初始化方法,ApplicationContextInitializer");UserDTO user = new UserDTO();user.setUserName("zs");user.setPassword("123456");this.userDTO = user;}
}

注冊:

@SpringBootApplication
public class BitApplication {public static void main(String[] args) {//SpringApplication.run(BitApplication.class, args);SpringApplication application = new SpringApplication(BitApplication.class);application.addInitializers(new InitUserInitUtil()); // 注冊自定義 ApplicationContextInitializerapplication.run(args);}
}
package com.bit.demo.test.bean;import com.bit.demo.dto.UserDTO;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;@Component
@Slf4j
public class AaTestClass2 implements InitializingBean {@PostConstructpublic void initAgain() {log.info("初始化方法, 同時使用PostConstruct和InitializingBean");}@Overridepublic void afterPropertiesSet() throws Exception {log.info("初始化方法, 使用InitializingBean");UserDTO innitUser = InitUserInitUtil.getUserDTO();if(innitUser != null) {log.info("獲取user成功",innitUser);}else{log.info("獲取user失敗",innitUser);}}
}
? ?
再次啟動輸出
 =========|_|==============|___/=/_/_/_/:: Spring Boot ::                (v3.2.4)2025-03-28T11:18:53.520+08:00  INFO 15408 --- [           main] c.bit.demo.test.bean.InitUserInitUtil    : 初始化方法,ApplicationContextInitializer
2025-03-28T11:18:53.525+08:00  INFO 15408 --- [           main] com.bit.demo.BitApplication              : Starting BitApplication using Java 17.0.11 with PID 15408 (C:\mydemo\bit-demo\target\classes started by Tina.Zhang in C:\code\cci-voice)
2025-03-28T11:18:53.526+08:00  INFO 15408 --- [           main] com.bit.demo.BitApplication              : No active profile set, falling back to 1 default profile: "default"
2025-03-28T11:18:54.182+08:00  INFO 15408 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 7777 (http)
2025-03-28T11:18:54.190+08:00  INFO 15408 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2025-03-28T11:18:54.190+08:00  INFO 15408 --- [           main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.19]
2025-03-28T11:18:54.233+08:00  INFO 15408 --- [           main] o.a.c.c.C.[.[localhost].[/bitDemo]       : Initializing Spring embedded WebApplicationContext
2025-03-28T11:18:54.233+08:00  INFO 15408 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 672 ms
Logging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter.
Initialization Sequence datacenterId:6 workerId:2_ _   |_  _ _|_. ___ _ |    _ 
| | |\/|_)(_| | |_\  |_)||_|_\ /               |         3.5.5 
2025-03-28T11:18:54.467+08:00  INFO 15408 --- [           main] com.bit.demo.test.bean.AaTestClass1      : 初始化方法, 使用PostConstruct
2025-03-28T11:18:54.467+08:00  INFO 15408 --- [           main] com.bit.demo.test.bean.AaTestClass2      : 初始化方法, 同時使用PostConstruct和InitializingBean
2025-03-28T11:18:54.468+08:00  INFO 15408 --- [           main] com.bit.demo.test.bean.AaTestClass2      : 初始化方法, 使用InitializingBean
2025-03-28T11:18:54.468+08:00  INFO 15408 --- [           main] com.bit.demo.test.bean.AaTestClass2      : 獲取user成功
2025-03-28T11:18:54.469+08:00  INFO 15408 --- [           main] com.bit.demo.test.bean.TestClass1        : 初始化方法, 使用PostConstruct
2025-03-28T11:18:54.469+08:00  INFO 15408 --- [           main] com.bit.demo.test.bean.TestClass2        : 初始化方法, 同時使用PostConstruct和InitializingBean
2025-03-28T11:18:54.469+08:00  INFO 15408 --- [           main] com.bit.demo.test.bean.TestClass2        : 初始化方法, 使用InitializingBean
2025-03-28T11:18:54.688+08:00  INFO 15408 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 7777 (http) with context path '/bitDemo'
2025-03-28T11:18:54.694+08:00  INFO 15408 --- [           main] com.bit.demo.BitApplication              : Started BitApplication in 1.376 seconds (process running for 1.72)

二、ApplicationContextInitializer

1、介紹

ApplicationContextInitializer 是 Spring 框架中的一個接口,主要用于在 Spring 容器刷新(refresh())之前ApplicationContext 進行自定義的初始化操作。它允許在 ApplicationContext 完全初始化之前進行配置,例如:添加屬性、激活配置文件(Profiles)等。

這種機制讓開發者能夠在 Spring 啟動過程中更早地進行干預,適用于有高級配置需求的應用程序。

該接口位于 org.springframework.context 包下:

public interface ApplicationContextInitializer<C extends ConfigurableApplicationContext> {void initialize(C applicationContext);
}
2、方法說明

initialize(C applicationContext):

  • 該方法在 ApplicationContext 刷新(refresh())之前調用,可以對 applicationContext 進行初始化。

  • CConfigurableApplicationContext 的子類,如 AnnotationConfigApplicationContextGenericApplicationContext

3、典型使用場景
(1)動態修改 Environment 變量

initialize() 方法中修改 Environment,實現動態配置:

@Override
public void initialize(ConfigurableApplicationContext applicationContext) {ConfigurableEnvironment environment = applicationContext.getEnvironment();environment.getSystemProperties().put("my.custom.property", "CustomValue");System.out.println("? 設置環境變量 my.custom.property = " + environment.getProperty("my.custom.property"));
}
(2)激活特定的 Spring Profile
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {ConfigurableEnvironment environment = applicationContext.getEnvironment();environment.setActiveProfiles("dev"); // 激活 dev ProfileSystem.out.println("? 激活 Profile: " + String.join(", ", environment.getActiveProfiles()));
}
(3)在 Spring 容器啟動前添加 PropertySource

如果需要在 Spring 啟動前添加額外的配置源(如數據庫、遠程配置中心等),可以這樣做:

import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertiesPropertySource;
import java.util.Properties;@Override
public void initialize(ConfigurableApplicationContext applicationContext) {MutablePropertySources propertySources = applicationContext.getEnvironment().getPropertySources();Properties properties = new Properties();properties.put("extra.config", "Loaded from ApplicationContextInitializer");propertySources.addFirst(new PropertiesPropertySource("extraProperties", properties));System.out.println("? 額外配置: " + applicationContext.getEnvironment().getProperty("extra.config"));
}

4、與其他 Spring 組件的對比
組件作用范圍作用時間點主要用途
ApplicationContextInitializerSpring 容器ApplicationContext.refresh() 之前初始化 ApplicationContext,添加 PropertySource、修改配置等
BeanFactoryPostProcessorBeanFactoryApplicationContext.refresh() 期間修改 Bean 定義(如動態修改 @Bean 配置)
BeanPostProcessor單個 BeanBean 初始化前后處理 Bean 實例,如 AOP、代理等
ApplicationRunner / CommandLineRunner應用啟動完成后ApplicationContext 初始化后運行啟動任務(如初始化數據、執行業務邏輯)
5、執行時期和注意事項

ApplicationContextInitializer 的執行時機 早于 Spring 容器刷新(refresh()),如下所示:

(1)創建 SpringApplication

(2)調用 ApplicationContextInitializer.initialize()

(3)加載 Environment

(4)創建 ApplicationContext 并調用 refresh()

(5)掃描 BeanFactory 并注冊 Bean

(5)調用 BeanFactoryPostProcessor

(6)調用 InitializingBean@PostConstruct

(7)啟動 Spring 容器

注意:由于 ApplicationContextInitializerrefresh() 之前執行,此時 Bean 還未初始化,不能調用 applicationContext.getBean()

import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;public class MyApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {@Overridepublic void initialize(ConfigurableApplicationContext applicationContext) {System.out.println("? 獲取 ApplicationContext:" + applicationContext);System.out.println("? 獲取 Environment:" + applicationContext.getEnvironment());// ? 不能使用 getBean(),因為此時 Bean 還未初始化try {Object myBean = applicationContext.getBean("myBean");System.out.println("獲取 Bean: " + myBean);} catch (Exception e) {System.out.println("?? 此時無法獲取 Bean,因為 ApplicationContext 還未刷新!");}}
}
6、使用方法
(1)實現ApplicationContextInitializer
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;public class MyApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {@Overridepublic void initialize(ConfigurableApplicationContext applicationContext) {System.out.println("🚀 ApplicationContextInitializer 執行...");// 獲取 EnvironmentConfigurableEnvironment environment = applicationContext.getEnvironment();// 設置自定義屬性environment.getSystemProperties().put("custom.property", "Hello Spring!");// 打印 Environment 變量System.out.println("? Environment 自定義屬性:" + environment.getProperty("custom.property"));}
}
(2)注冊ApplicationContextInitializer

Spring 提供了 3 種方式 來注冊 ApplicationContextInitializer

①??在 SpringApplication 中添加 addInitializers

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class MyApplication {public static void main(String[] args) {SpringApplication application = new SpringApplication(MyApplication.class);application.addInitializers(new MyApplicationContextInitializer()); // 注冊自定義 ApplicationContextInitializerapplication.run(args);}
}

②?在 spring.factories 中自動加載

創建 META-INF/spring.factories 文件:

org.springframework.context.ApplicationContextInitializer=com.example.MyApplicationContextInitializer

③?在測試中使用 @ContextConfiguration

如果只想在測試環境中使用 ApplicationContextInitializer,可以使用 @ContextConfiguration

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ContextConfiguration;@SpringBootTest
@ContextConfiguration(initializers = MyApplicationContextInitializer.class)
public class MyApplicationTests {@Testvoid contextLoads() {System.out.println("🔍 運行測試...");}
}

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

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

相關文章

中小型企業網絡的搭建

1.1 網絡邏輯拓撲、布線方案的設計 1.1.1 網絡設計依據 網絡設計應遵循以下基本原則&#xff1a; 高效性&#xff1a;確保網絡架構能夠支持企業日常業務的高效運行。 可靠性&#xff1a;采用冗余設計&#xff0c;確保網絡的高可用性&#xff0c;避免單點故障。 可擴展性…

angr基礎學習

參考&#xff1a;angr AngrCTF_FITM/筆記/03/Angr_CTF從入門到精通&#xff08;三&#xff09;.md at master ZERO-A-ONE/AngrCTF_FITM angr_explore 00_angr_find IDA分析結果&#xff1a; 邏輯簡單&#xff0c;輸入&#xff0c;complex_function進行加密&#xff0c;加密…

軟考-高級-系統架構設計師【考試備考資料下載】

計算機技術與軟件專業技術資格&#xff08;水平&#xff09;考試是原中國計算機軟件專業技術資格和水平考試的完善與發展。計算機技術與軟件專業技術資格&#xff08;水平&#xff09;考試是由國家人力資源和社會保障部、工業和信息化部領導下的國家級考試。 計算機技術與軟件專…

3. 第三放平臺部署deepseek

有時候我們會發現使用deepseek服務器&#xff0c;異常卡頓&#xff0c;這是由于多方面原因造成的&#xff0c;比如說訪問人數過多等。想要解決這個問題&#xff0c;我們可以選擇第三方平臺進行部署 第三方平臺 我們可以選擇的第三方平臺很多&#xff0c;比如硅基流動、秘塔搜索…

1.4-蜜罐\堡壘機\API接口

1.4-蜜罐\堡壘機\API接口 蜜罐&#xff1a;用來釣魚或誘惑測試人員的防護系統 bash <(curl -sS -L https://hfish.net/webinstall.sh) # 安裝HFISH蜜罐堡壘機&#xff1a; 運維用的&#xff0c;統一管理運維平臺;拿下堡壘機就很有可能等于拿下了多個平臺 jumpServer一鍵安…

知識圖引導的檢索增強生成

摘要 檢索增強生成&#xff08;RAG&#xff09;已經成為一種很有前途的技術&#xff0c;用于解決大型語言模型&#xff08;LLM&#xff09;生成的響應中的幻覺問題。現有的RAG研究主要集中在應用基于語義的方法來提取孤立的相關組塊&#xff0c;忽略了它們之間的內在關系。在本…

【機器學習】imagenet2012 數據預處理數據預處理

【機器學習】數據預處理 1. 下載/解壓數據2. 數據預處理3. 加載以及訓練代碼3.1 使用PIL等加載代碼3.2 使用OpenCV的方式來一張張加載代碼3.3 h5的方式來加載大文件 最后總結 這個數據大約 140個G,128w的訓練集 1. 下載/解壓數據 首先需要下載數據&#xff1a; 數據最后處理…

質量工程:數字化轉型時代的質量體系重構

前言&#xff1a;質量理念的范式轉移閱讀原文 如果把軟件開發比作建造摩天大樓&#xff1a; 傳統測試 竣工后檢查裂縫&#xff08;高成本返工&#xff09; 質量工程 從地基開始的全流程監理體系&#xff08;設計圖紙→施工工藝→建材選擇→竣工驗收&#xff09; IEEE研究…

【全棧開發】—— Paddle OCR 文字識別 + deepseek接入(基于python 最新!!!)

所有源碼都在文章中&#xff0c;大家不要私信來要源碼&#xff0c;當然&#xff0c;評論區歡迎交流技術 目錄 Paddle OCR 配置環境 示例 deepseek接入 環境配置 api 調用代碼 sliconflow Paddle OCR 配置環境 清華源下載 paddlepaddle&#xff1a; pip install paddlepaddle …

SAIL-RK3588J 核心板技術方案——高精度裝配式建筑機器人控制?

&#xff08;本方案契合《建筑機器人產業目錄》政策要求&#xff09; 一、方案背景與政策支持? ?政策驅動? 2025年2月《建筑機器人產業目錄》明確將?“高精度建筑機器人控制設備”?納入重點補貼范圍&#xff0c;要求定位精度≤0.5mm、支持實時質檢與多機協同&#xff0c…

OpenAI API - 快速入門開發

文章目錄 開發者快速入門分析圖像輸入使用工具擴展模型提供閃電般的 AI 體驗構建代理進一步探索 模型精選模型推理模型旗艦聊天模型成本優化模型實時模型舊版 GPT 模型DALLE文本轉語音轉寫嵌入調度工具特定模型GPT 基礎模型 Libraries創建和導出 API 密鑰安裝官方 SDKJavaScrip…

藍橋杯省賽 棋盤 3533 二維差分+二維前綴和

傳送門 0棋盤 - 藍橋云課 const int N 2e3 10;int n,m; int a[N][N];void insert(int x11,int y11,int x22,int y22) {a[x11][y11] ;a[x11][y22 1] --;a[x22 1][y11] --;a[x22 1][y22 1] ; }void solve() {cin >> n >> m;for (int i 1;i < m;i ){int x11…

《C++Linux編程進階:從0實現muduo 》-第6講.C++死鎖問題如何分析調試-原子操作,互斥量,條件變量的封裝

重點內容 視頻講解&#xff1a;《CLinux編程進階&#xff1a;從0實現muduo C網絡框架系列》-第6講.C死鎖問題如何分析調試-原子操作,互斥量,條件變量的封裝 代碼改動 lesson6代碼 實現&#xff1a;base/Atomic.h 實現&#xff1a;base/Mutex.h 實現&#xff1a;base/Condit…

洛谷題單1-P5708 【深基2.習2】三角形面積-python-流程圖重構

題目描述 一個三角形的三邊長分別是 a a a、 b b b、 c c c&#xff0c;那么它的面積為 p ( p ? a ) ( p ? b ) ( p ? c ) \sqrt{p(p-a)(p-b)(p-c)} p(p?a)(p?b)(p?c) ?&#xff0c;其中 p 1 2 ( a b c ) p\frac{1}{2}(abc) p21?(abc)。輸入這三個數字&#xff…

matplotlib標題比x,y軸字體大,明明標題字體更大?

原始代碼&#xff1a; plt.xlabel(訓練輪次&#xff08;Epochs&#xff09;, fontsize14, fontweightbold, fontpropertieschinese_font) # 設置中文字體、加大、加粗 plt.ylabel(R值, fontsize14, fontweightbold, fontpropertieschinese_font) # 設置中文字體、加大、加粗…

Baklib內容中臺的核心優勢是什么?

智能化知識管理引擎 Baklib的智能化知識管理引擎通過多源數據整合與智能分類技術&#xff0c;實現企業知識資產的自動化歸集與動態更新。系統內置的語義分析算法可自動識別文檔主題&#xff0c;結合自然語言處理技術生成結構化標簽體系&#xff0c;大幅降低人工標注成本。針對…

Android學習總結之ContentProvider跨應用數據共享

在 Android 開發中&#xff0c;跨應用數據共享是構建開放生態的關鍵需求。作為四大組件之一&#xff0c;ContentProvider通過標準化接口和安全機制&#xff0c;成為實現這一需求的核心樞紐。本文將圍繞其生命周期方法、核心機制、自定義實現及最佳實踐展開&#xff0c;幫助開發…

計算機底層基石:原碼、反碼、補碼、移碼深度剖析

在計算機的世界里&#xff0c;所有數據最終都以二進制的形式進行存儲與運算。原碼、反碼、補碼和移碼作為二進制數據的重要編碼方式&#xff0c;對計算機實現高效數據處理起著關鍵作用。接下來&#xff0c;我們將深入剖析這幾種編碼。? 一、原碼? 1.1 定義? 原碼是最簡單…

Bitnode和Bitree有什么區別 為什么Bitree前多了*

Bitnode 和 Bitree 的區別在于它們的類型定義和用途&#xff1a; Bitnode: 這是一個結構體類型&#xff0c;表示二叉樹中的一個節點。 它包含三個成員&#xff1a; data&#xff1a;存儲節點的數據&#xff08;這里是 char 類型&#xff09;。 lchild&#xff1a;指向左子節點…

AI 時代,我們該如何寫作?

當ChatGPT/DeepSeek能在幾秒鐘內產出一篇文章&#xff0c;而且生成能力日益精進&#xff0c;你是否也曾思考&#xff0c;我還能做什么&#xff1f; 當2024年AI開始進入人們的視野&#xff0c;我在CSDN 上的博客也悄然發生了變化&#xff0c;以前一篇文章發布后&#xff0c;閱讀…