Spring上下文模塊設計

經過此前我們設計的如:IoC、Web、數據訪問、AOP等模塊的設計,我們從設計上已經搭建好了Spring的基礎骨架了,但聰明的碼友會思考想到:作為一個基礎框架而言,目前應該是已經夠用了的,但是上進的碼友怎么會就此止步;從模塊劃分上每個模塊均有自己要關注和實現的內容,那么是否會存在一些共有的內容,比如:環境配置、事件機制、國際化等。

一、背景與設計理念

在Spring框架早期版本中,BeanFactory作為最基礎的IoC容器實現,僅提供了基礎的依賴注入功能和Bean生命周期管理。開發者需要通過顯式編碼來創建和管理對象,每個Bean的依賴關系都需要手動配置和解析,導致大量重復代碼。隨著企業應用復雜度增加,這種基礎容器的局限性日益凸顯:缺乏事件機制國際化支持薄弱資源抽象不足(資源配置分散在各模塊,難以滿足現代應用的需求。

Spring上下文的誕生正是為了解決這些痛點。ApplicationContext作為BeanFactory的擴展,在保留核心依賴注入功能的同時,引入了多項企業級服務支持,形成了完整的應用執行環境。與基礎BeanFactory相比,ApplicationContext提供了以下關鍵增強:

  • 資源管理統一化:通過ResourceLoaderResource接口抽象不同來源的資源(類路徑、文件系統、URL等),使資源獲取與具體環境解耦;
  • 國際化便捷支持:基于MessageSource接口提供消息解析機制,支持層次化消息源和地區化處理
  • 事件發布訂閱模型:通過ApplicationEventPublisherApplicationListener實現觀察者模式,增強組件間解耦
  • 上下文層次化管理:支持父子容器結構,允許在不同層次共享或隔離配置

1、有無Spring上下文的對比分析

能力維度無上下文(BeanFactory)有上下文(ApplicationContext)
依賴注入基礎Bean管理支持完整Bean生命周期管理
資源配置需手動處理資源路徑統一資源抽象(ResourceLoader)
國際化無內置支持多語言消息源(MessageSource)
事件機制需自定義實現內置發布-訂閱模型
容器結構單一容器支持父子容器層次
AOP集成手動代理創建聲明式切面支持
與框架集成困難Spring MVC/Spring Boot無縫集成

在Spring Boot和Spring Cloud等現代框架中,上下文設計進一步演進出層次化容器結構。當使用SpringApplicationBuilder構建應用時,會自動創建父子上下文層次:Bootstrap上下文作為父容器,主應用上下文作為子容器。這種設計使得:

  1. 配置繼承:子容器可以訪問父容器的屬性源,實現配置共享
  2. 隔離與覆蓋:子容器可定義同名屬性覆蓋父容器配置
  3. 多級擴展:通過parent(), child(), sibling()方法構建復雜容器關系
  4. 模塊化部署:不同模塊可使用獨立上下文,通過父子關系共享基礎服務

這種層次化設計在微服務架構中尤為重要。例如在Spring Cloud應用中,Bootstrap上下文負責加載外部配置中心參數,主應用上下文則處理業務Bean初始化,二者分離既保證配置優先加載,又避免環境污染。

2、解耦悖論

Spring模塊化設計的初衷是解耦,但上下文模塊的出現,似乎讓上下文模塊成了核心依賴,那么豈不是違背了解耦的初衷。

確實,Spring各模塊(如AOP、事務、數據訪問)都需要訪問ApplicationContext獲取Bean或環境信息,形成了事實上的中心依賴點。但這并不違背解耦原則,原因在于:

  1. 依賴抽象而非實現
    所有模塊依賴的是ApplicationContext接口(定義在spring-context模塊),而非具體實現類。這種接口隔離確保了模塊間通過契約交互:

  1. 上下文本質是“集成中樞”
    上下文不是業務組件,而是基礎設施層。就像操作系統為應用提供統一API,Spring上下文為模塊提供:
    • 環境配置(Environment)
    • 依賴查找(getBean())
    • 資源抽象(ResourceLoader)
    • 事件機制(ApplicationEventPublisher)

這種中心化服務提供是框架的必然設計。

二、核心組件與職能劃分

通過以上了解,所以在Spring上下文模塊的設計上,要注重設計接口分層和類繼承體系,且要實現功能的高內聚和低耦合。以下從核心接口、實現類和支撐技術三個維度進行分析設計

組件類型關鍵類/接口主要職責實現技術
核心接口ApplicationContext容器基本功能定義接口聚合
ConfigurableApplicationContext生命周期和配置擴展生命周期方法
WebApplicationContextWeb環境擴展ServletContext集成
實現類AbstractApplicationContext容器刷新模板實現模板方法模式
GenericApplicationContext輕量級通用容器組合BeanFactory
AnnotationConfigApplicationContext注解配置支持注解掃描解析
EmbeddedWebApplicationContext內嵌Web容器支持Servlet3.0+API
支撐組件Environment環境配置抽象PropertySource體系
BeanDefinitionRegistryBean定義動態注冊Bean元數據操作
ApplicationEventMulticaster事件廣播機制觀察者模式
ResourcePatternResolver資源加載策略路徑匹配解析

1. 核心接口體系

  • ApplicationContext (核心容器接口):設計一個上下文模塊的根基接口,集成多個基礎接口能力,定義容器的基本行為。它繼承BeanFactory提供Bean管理能力,ResourcePatternResolver支持資源加載,ApplicationEventPublisher實現事件推送,MessageSource處理國際化消息。這種接口聚合設計避免了繼承爆炸問題。
  • ConfigurableApplicationContext (可配置上下文):擴展ApplicationContext,增加生命周期控制start(), stop(), close())和配置能力(設置父容器、注冊關閉鉤子等)。它是所有可寫上下文的契約接口,為子類提供可定制入口點。
  • WebApplicationContext (Web環境擴展):專為Web應用設計,增加getServletContext()方法獲取Servlet上下文,提供Web作用域Bean支持(request/session/application)。

2. 關鍵實現類

  • AbstractApplicationContext (抽象模板實現):可作為所有具體上下文的骨架實現,采用模板方法模式定義上下文初始化的標準流程,尤其是refresh()方法的實現是整個Spring容器啟動的核心。其關鍵方法包括:
// 模板方法定義容器刷新流程
@Override
public void refresh() throws BeansException, IllegalStateException {this.startupShutdownLock.lock();try {this.startupShutdownThread = Thread.currentThread();StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");// Prepare this context for refreshing.// 準備此上下文以刷新。prepareRefresh();// Tell the subclass to refresh the internal bean factory.// 告訴子類刷新內部bean工廠ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// Prepare the bean factory for use in this context.// 準備好bean工廠以便在上下文中使用prepareBeanFactory(beanFactory);try {// Allows post-processing of the bean factory in context subclasses.// 子類可以對bean工廠進行后處理,比如注冊一些bean處理器、注冊一些監聽器、注冊一些事件處理器等。postProcessBeanFactory(beanFactory);StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");// Invoke factory processors registered as beans in the context.// 調用工廠處理器,這些處理器是作為bean在context中注冊的。invokeBeanFactoryPostProcessors(beanFactory);// Register bean processors that intercept bean creation.// 注冊Bean后置處理器registerBeanPostProcessors(beanFactory);beanPostProcess.end();// Initialize message source for this context.// 初始化消息源initMessageSource();// Initialize event multicaster for this context.// 初始化事件多播器initApplicationEventMulticaster();// Initialize other special beans in specific context subclasses.// 子類擴展點onRefresh();// Check for listener beans and register them.// 注冊事件監聽器registerListeners();// Instantiate all remaining (non-lazy-init) singletons.// 實例化所有剩余的(非懶加載)單例。finishBeanFactoryInitialization(beanFactory);// Last step: publish corresponding event.// 最后一步:發布對應的事件finishRefresh();}catch (RuntimeException | Error 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 {contextRefresh.end();}}finally {this.startupShutdownThread = null;this.startupShutdownLock.unlock();}
}
  • GenericApplicationContext (通用配置上下文):基于組合優于繼承原則設計的輕量級實現,內部持有DefaultListableBeanFactory實例,避免了復雜的繼承層次。適合基于Java配置的應用場景,是AnnotationConfigApplicationContext的基類。

  • AnnotationConfigWebApplicationContext (注解驅動Web上下文):專為Servlet環境設計的注解配置上下文,支持通過@Configuration類定義Bean,自動掃描@Component組件。內部使用AnnotatedBeanDefinitionReader解析注解配置。

3. 支撐性技術組件

  • Environment抽象 (環境配置):通過Environment接口和PropertySource抽象,統一管理配置屬性源(系統變量、環境變量、配置文件等),支持Profile條件裝配。在上下文層次結構中,子容器通過Environment.merge()合并父容器環境。
  • BeanDefinitionRegistry (Bean定義注冊):提供動態注冊Bean定義的能力,允許在運行時修改容器元數據。GenericApplicationContext直接實現此接口,支持編程式Bean注冊。
  • ApplicationEventMulticaster (事件廣播器):作為觀察者模式的核心實現,管理事件監聽器列表,支持同步/異步事件分發。默認使用SimpleApplicationEventMulticaster實現,可通過TaskExecutor擴展為異步模式。

三、核心設計模式應用

1. 代理模式:功能委托與擴展

代理模式在上下文設計中應用廣泛,主要體現在功能解耦職責分離兩方面。AbstractApplicationContext內部通過多個代理組件實現功能委托。

這種設計帶來兩大優勢:

  1. 靈活性:可動態替換代理實現(如將SimpleApplicationEventMulticaster替換為異步廣播器)
  2. 可擴展性:子類只需覆蓋initApplicationEventMulticaster()等初始化方法即可定制組件
public abstract class AbstractApplicationContext {// 消息代理@Nullableprivate MessageSource messageSource;// 事件廣播器代理@Nullableprivate ApplicationEventMulticaster applicationEventMulticaster;// 資源解析器代理private ResourcePatternResolver resourcePatternResolver;@Overridepublic String getMessage(String code, Object[] args, String defaultMessage, Locale locale) {// 委托給messageSource處理return getMessageSource().getMessage(code, args, defaultMessage, locale);}@Overridepublic void publishEvent(ApplicationEvent event) {// 委托給applicationEventMulticaster廣播事件getApplicationEventMulticaster().multicastEvent(event);}
}

2. 模板方法模式:容器生命周期標準化

AbstractApplicationContext.refresh()方法是模板方法模式的典范,定義了容器初始化的12步標準流程,但將關鍵步驟設計為可擴展點

  1. 可覆蓋方法:如postProcessBeanFactory()onRefresh()等protected方法允許子類擴展
  2. 抽象方法:如obtainFreshBeanFactory()強制子類提供具體實現
  3. 鉤子方法:如registerBeanPostProcessors()提供默認實現,子類可選擇覆蓋

這種設計使Spring能夠支持多樣化的配置方式(XML、注解、Groovy等),同時保持核心初始化流程的統一性。例如ClassPathXmlApplicationContext通過覆蓋loadBeanDefinitions()方法實現XML解析:

public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {@Overrideprotected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) {// 創建XML解析器XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);// 加載XML配置reader.loadBeanDefinitions(getConfigLocations());}
}

3. 組合模式:容器層次結構構建

Spring通過組合模式實現容器層次結構,ApplicationContext接口提供getParent()方法獲取父容器引用。這種設計在Web應用中尤為重要:

public class CustomWebApplicationInitializer implements WebApplicationInitializer {public void onStartup(ServletContext servletContext) {// 創建父容器(服務層Bean)AnnotationConfigApplicationContext rootContext = new AnnotationConfigApplicationContext();rootContext.register(ServiceConfig.class);rootContext.refresh();// 創建子容器(Web層Bean)AnnotationConfigWebApplicationContext webContext = new AnnotationConfigWebApplicationContext();webContext.setParent(rootContext); // 設置父子關系webContext.register(WebConfig.class);// 將子容器關聯到DispatcherServletDispatcherServlet servlet = new DispatcherServlet(webContext);ServletRegistration.Dynamic reg = servletContext.addServlet("app", servlet);}
}

在此結構中:

  1. Web層容器可訪問父容器的Bean(如Service組件)
  2. 父容器無法訪問子容器Bean,實現關注點分離
  3. 配置隔離:各層容器可獨立配置自己的Bean作用域

4. 觀察者模式:事件驅動機制

Spring的事件模型是觀察者模式的典型應用,由三個核心組件構成:

  1. ApplicationEvent:事件對象(如ContextRefreshedEvent, RequestHandledEvent
  2. ApplicationListener:事件監聽器接口
  3. ApplicationEventMulticaster:事件廣播中心

具體應用示例:

// 1. 定義自定義事件
public class UserModifyEvent extends ApplicationEvent {public UserModifyEvent(Object source) {super(source);}
}// 2. 創建事件監聽器
@Component
public class UserModifyListener implements ApplicationListener<UserModifyEvent> {@Overridepublic void onApplicationEvent(UserModifyEvent event) {// 處理更新事件邏輯}
}// 3. 發布事件
@Service
public class UserService {@Autowiredprivate ApplicationEventPublisher publisher;public void updateUser(User user) {// 業務邏輯...publisher.publishEvent(new UserModifyEvent(this));}
}

這種松耦合通信機制使業務組件無需直接引用即可交互,增強系統可維護性。

5. 策略模式:可插拔組件實現

上下文模塊中多處應用策略模式實現算法可替換:

  • 資源加載ResourcePatternResolver作為策略接口,PathMatchingResourcePatternResolver是其默認實現
  • 環境管理Environment接口抽象環境策略,StandardEnvironmentStandardServletEnvironment提供不同實現
  • 屬性解析PropertyResolver定義屬性解析策略,PropertySourcesPropertyResolver基于PropertySources實現

策略模式使Spring能夠適應不同運行環境。例如在測試環境中可替換為模擬策略:

public class TestApplicationContext extends GenericApplicationContext {@Overrideprotected ConfigurableEnvironment createEnvironment() {// 返回測試專用的環境策略return new MockEnvironment();}
}

四、高級特性與應用實踐

1. 層次化容器設計

Spring的容器層次結構不僅僅是父子關系,而是支持多級嵌套交叉引用的復雜拓撲。在Spring Cloud環境中,這種設計發揮到極致:

Bootstrap Context (最高級)||--- Application Context (主應用)||--- Web MVC Context (Web模塊)||--- Batch Context (批處理模塊)

屬性解析規則在這種層次結構中遵循:

  1. 優先子級:子容器屬性覆蓋父容器同名屬性
  2. 源獨立性:每個容器維護獨立的屬性源(bootstrap, application等)
  3. 名稱空間隔離:相同屬性源名稱在不同層級互不影響

通過SpringApplicationBuilder可編程式構建此結構:

new SpringApplicationBuilder().parent(ParentConfig.class).web(WebApplicationType.NONE) // 父容器.child(WebConfig.class).web(WebApplicationType.SERVLET)  // 子容器.sibling(BatchConfig.class).web(WebApplicationType.NONE) // 兄弟容器.run(args);

2. 環境抽象與配置管理

Environment抽象是Spring上下文的核心創新,通過PropertySource體系統一管理配置源:

  1. 層次化覆蓋:子容器環境自動合并父容器環境,子級PropertySource優先
  2. 動態配置:通過@PropertySource注解動態添加配置源
  3. Profile激活:條件化加載Bean定義,實現環境適配

在Spring Boot中,屬性加載順序的精心設計體現了環境抽象的威力:

  1. 默認屬性(通過SpringApplication.setDefaultProperties設置)
  2. @Configuration類上的@PropertySource
  3. 配置數據(application.properties/YAML)
  4. 操作系統環境變量
  5. JVM系統屬性

3. 條件化裝配機制

Spring 4.0引入的@Conditional注解將條件判斷提升到元編程級別,成為Spring Boot自動配置的基石。其擴展應用包括:

  • Profile條件@Profile底層基于@Conditional實現
  • 屬性條件@ConditionalOnProperty根據屬性存在性/值決定裝配
  • 資源條件@ConditionalOnResource檢測資源存在性
  • Bean條件@ConditionalOnBean/@ConditionalOnMissingBean根據容器中Bean存在性決策

自定義條件示例:

public class ClusterModeCondition implements Condition {@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {// 從環境獲取運行模式String mode = context.getEnvironment().getProperty("cluster.mode");// 僅當模式為"high-availability"時匹配return "high-availability".equalsIgnoreCase(mode);}
}// 使用自定義條件裝配
@Configuration
@Conditional(ClusterModeCondition.class)
public class ClusterConfig {@Beanpublic ClusterService clusterService() {return new HighClusterService();}
}

4. 上下文生命周期管理

上下文的生命周期由ConfigurableApplicationContext接口嚴格定義,核心階段包括:

  1. 初始化:構造上下文實例,設置配置源
  2. 準備刷新prepareRefresh()初始化環境屬性
  3. Bean工廠創建obtainFreshBeanFactory()加載Bean定義
  4. 后處理:執行BeanFactoryPostProcessor
  5. Bean實例化:注冊BeanPostProcessor,初始化單例
  6. 完成刷新:發布ContextRefreshedEvent
  7. 運行中:處理請求/調用
  8. 關閉:發布ContextClosedEvent,銷毀Bean

生命周期事件為應用提供關鍵擴展點:

  • ContextStartedEvent:上下文啟動后
  • ContextStoppedEvent:上下文停止后
  • ContextRefreshedEvent:上下文完全刷新
  • ContextClosedEvent:上下文關閉

五、設計總結與啟示

Spring上下文模塊經過多年演進形成的架構,體現了以下核心設計哲學:

  1. 可擴展性設計:通過模板方法模式定義骨架流程,預留擴展點(如postProcessBeanFactory())允許子類定制特定步驟。這種設計使Spring能無縫支持XML、注解、Groovy等多種配置方式,同時保持核心流程穩定。
  2. 關注點分離:采用代理模式將消息、事件、資源等功能委托給專門組件,確保核心容器職責單一。例如ApplicationEventMulticaster專注事件廣播,MessageSource處理國際化,各組件通過接口契約協作。
  3. 層次化抽象:通過組合模式構建容器父子關系,實現配置繼承與覆蓋。在微服務架構中,這種設計衍生出Bootstrap上下文、主應用上下文、Web上下文的層級結構,為Spring Cloud的配置管理、服務發現等提供基礎設施。

在現代云原生應用開發中,上下文設計啟示我們:

  • 環境適配:通過Environment抽象統一管理配置源,使應用可無縫遷移到不同環境(本地、測試、生產)
  • 條件化裝配:基于@Conditional的自動配置機制大幅減少樣板代碼
  • 事件驅動:內置事件模型支持響應式編程,增強組件解耦
  • 生命周期管理:標準化的生命周期使框架擴展更可控

Spring上下文模塊的成功證明:強大的抽象能力合理的分層設計是框架靈活性的基石。其設計思想不僅適用于Java生態系統,對任何復雜框架的開發都具有參考價值。隨著Spring 6和Spring Boot 3的演進,響應式上下文、原生鏡像支持等新特性將繼續拓展上下文設計的邊界,為開發者提供更強大的企業級支持。

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

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

相關文章

keil5怎么關閉工程

在project里面有一個close project&#xff0c;點擊后就關掉了&#xff0c;之前還按照其他軟件的操作習慣&#xff0c;右鍵工程選項&#xff0c;但是始終沒有發現關閉選項。

騰訊云:6月30日起,自動禁用,及時排查

大家好&#xff0c;我是小悟。 騰訊云發布公告&#xff0c;宣布從2025年6月30日開始&#xff0c;對長期未使用的AccessKey&#xff08;API訪問密鑰&#xff09;進行自動禁用。 簡單來說&#xff0c;如果你的密鑰在90天內沒動靜&#xff0c;系統就會把它關掉&#xff0c;不管是…

【C++】多重繼承與虛繼承

多重繼承與虛繼承 1.單繼承和多重繼承的區別2.語法規則示例代碼&#xff1a;多重繼承子類指定父類的構造示例代碼&#xff1a;多重繼承子類隱藏父類的同名方法 3.虛繼承解決多重繼承遇到的bug示例代碼&#xff1a;環狀繼承引發的問題 3.1 虛基類&#xff1a;3.2 語法規則&#…

GCC編譯/連接/優化等選項

1. GCC編譯/連接/優化等選項 1. GCC編譯/連接/優化等選項 1.1. 簡介1.2. 常用選項 1.2.1. -c -E -S -o1.2.2. -L<path> -l<library>1.2.3. -D<macro>1.2.4. -I<path> 1.3. 代碼生成和優化 1.3.1. -std<standard>1.3.2. -shared1.3.3. -fPIC1.3.…

FFmpeg 壓縮視頻文件

文章目錄 FFmpeg 壓縮視頻文件基本壓縮命令&#xff08;保持 MP4 格式&#xff09;轉換為其他格式示例&#xff1a;關鍵參數說明&#xff1a;額外優化選項&#xff1a; 在FFmpeg中使用多線程加速1. 幀級多線程 (frame-level multithreading)2. 切片級多線程 (slice-level multi…

Ubuntu 系統通過防火墻管控 Docker 容器

Ubuntu 系統通過防火墻管控 Docker 容器指南 一、基礎防火墻配置 # 啟用防火墻 sudo ufw enable# 允許 SSH 連接&#xff08;防止配置過程中斷聯&#xff09; sudo ufw allow 22/tcp二、Docker 配置調整 # 編輯 Docker 配置文件 sudo vim /etc/docker/daemon.json配置文件內…

虛擬機新增硬盤,與數據掛載

我有個虛擬機&#xff0c;當時選擇了獨立文件&#xff0c;現在遇到個問題&#xff0c;硬盤不夠了&#xff0c;索性加了一個新硬盤&#xff0c;現在想把數據庫的數據映射到這個新的硬盤處理。 羅列硬盤 lsblk我得是sdb是新硬盤 2. 分區 sudo fdisk /dev/sdb交互操作&#xff…

go語言學習 第10章:面向對象編程

第10章&#xff1a;面向對象編程 面向對象編程&#xff08;OOP&#xff09;是一種編程范式&#xff0c;它使用“對象”來表示數據和方法&#xff0c;并通過類來定義對象的結構和行為。Go語言雖然不是傳統的面向對象語言&#xff0c;但它通過結構體&#xff08;struct&#xff…

android計算器代碼

本次作業要求實現一個計算器應用的基礎框架。以下是布局文件的核心代碼&#xff1a; <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"andr…

Go 語言接口詳解

Go 語言接口詳解 核心概念 接口定義 在 Go 語言中&#xff0c;接口是一種抽象類型&#xff0c;它定義了一組方法的集合&#xff1a; // 定義接口 type Shape interface {Area() float64Perimeter() float64 } 接口實現 Go 接口的實現是隱式的&#xff1a; // 矩形結構體…

我們來學mysql -- 8.4版本記錄慢查詢

記錄慢查詢 開啟慢查詢的配置查看慢查詢狀態動態開啟慢查詢日志永久開啟配置log_throttle_queries_not_using_indexes 記錄慢查詢對性能的影響實際案例說明第一條記錄第二條記錄第三條記錄第四條記錄 開啟慢查詢的配置 查看慢查詢狀態 - 執行 show variables like slow_quer…

2025 年中國大學生程序設計競賽全國邀請賽(鄭州)暨第七屆CCPC河南省大學生程序設計競賽(補題)

文章目錄 前言F、幻形之路G、直徑與最大獨立集H&#xff0c;樹論函數M&#xff0c; 川陀航空學院總結 前言 本次比賽&#xff0c;只能說太多沒接觸的知識了&#xff0c;還有太容易被題面嚇住。 F、幻形之路 題目鏈接&#xff1a;幻形之路 解題思路&#xff1a; 對于這一題只…

如何使用k8s安裝redis呢

在Kubernetes (k8s) 上安裝Redis 在Kubernetes上安裝Redis有幾種方法&#xff0c;下面我將介紹兩種常見的方式&#xff1a;使用StatefulSet直接部署和使用Helm chart部署。 一、安裝redis 1.1 拉去ARM鏡像&#xff08;7.4.2&#xff09; docker pull registry.cn-hangzhou.ali…

SpringBoot的5種日志輸出規范策略

在企業級應用開發中&#xff0c;合理規范的日志記錄是系統穩定運行、問題排查和性能優化的關鍵保障。 SpringBoot作為流行的Java開發框架&#xff0c;提供了強大而靈活的日志支持&#xff0c;但如何建立統一、高效的日志輸出規范卻是許多團隊面臨的挑戰。 本文將介紹SpringBo…

Python Cookbook-7.11 在 PostgreSQL 中儲存 BLOB

任務 需要將 BLOB 存入一個 PostgreSQL 數據庫。 解決方案 PostgreSQL7.2 以及更新的版本支持大對象,而psycopg 模塊提供了二進制轉義函數: import psycopg,cPickle #連接到數據庫,用你的本機來測試數據庫,并獲得游標 connection = psycopg.connect("dbname = test…

Android端口轉發

如上圖所示&#xff0c;有一個Android設備&#xff0c;Android設備里面有主板&#xff0c;主板上有網絡接口和Wi-Fi&#xff0c;網絡接口通過網線連接了一個網絡攝像頭&#xff0c;這就跟電腦一樣&#xff0c;電腦即可以通過網線接入一個網絡&#xff0c;也可以同時用Wi-Fi接入…

Unity基礎-協程

Unity基礎-協程 四、協程 概述 協程&#xff08;Coroutine&#xff09;&#xff0c;本質上并不是多線程&#xff0c;而是在當前線程中將代碼分時執行&#xff0c;不卡主線程。可以理解為&#xff0c;協程會把可能使主線程卡頓的程序分時分布進行。 協程通常用來&#xff1a;…

UniApp組件封裝,2025年最新HarmonyOS鴻蒙模塊化開發項目式教程

一、環境配置與前置條件 ?開發工具要求? HBuilderX 4.64&#xff08;鴻蒙插件已預裝&#xff09;DevEco Studio 5.0.3.400&#xff08;真機調試必備&#xff09;鴻蒙離線SDK&#xff08;通過HBuilderX導入&#xff0c;每個項目獨立配置&#xff09; ?項目初始化 # 創建Vu…

C++ 精簡知識點

目錄 一、核心語法 1.指針VS引用 2. 類與對象&#xff08;必寫代碼&#xff09; 3. 繼承與多態&#xff08;必寫代碼&#xff09; 4. 模板&#xff08;必寫代碼&#xff09; 5.智能指針 6. 異常處理&#xff08;必寫結構&#xff09; 二、簡答題速記 三、考試應急策略 一…

7.Vue的compute計算屬性

3.8. 【computed】 作用&#xff1a;根據已有數據計算出新數據&#xff08;和Vue2中的computed作用一致&#xff09;。 <template><div class"person">姓&#xff1a;<input type"text" v-model"firstName"> <br>名&am…