Springboot 集成 SpringState 狀態機

Springboot 集成 SpringState 狀態機

  • 1.SpringState 簡介
  • 2.狀態機示例
    • 2.1 項目結構和依賴包
    • 2.2 定義事件類和狀態類
    • 2.3 Spring 事件監聽器
    • 2.4 狀態機持久化類
      • 2.4.1 Redis 狀態機持久化容器
      • 2.4.2 Redis 配置
      • 2.4.3 狀態機監聽器
    • 2.5 裝機器容器
    • 2.6 狀態機事件發送器
    • 2.7 狀態機配置
    • 2.8 接口類
    • 2.9 實現類
    • 2.10 狀態機上下文
    • 2.11 配置文件
  • 3.狀態機測試
    • 3.1創建訂單
    • 3.2持久化結果
    • 3.3 支付訂單
    • 3.4 發貨
    • 3.5 確認收貨

1.SpringState 簡介

狀態機核心概念??

項目說明
狀態(State)??對象生命周期中的特定條件(如訂單的待支付、已發貨)
事件(Event)??觸發狀態轉換的動作(如支付成功、取消訂單)
轉換(Transition)??定義事件如何驅動狀態遷移(如待支付 → 支付事件 → 待發貨)
守衛(Guard)??條件檢查,決定是否允許轉換(如“僅未超時訂單可支付”)
??動作(Action)??條件檢查,決定是否允許轉換(如“僅未超時訂單可支付”)

應用場景

  • 訂單生命周期管理??
    管理訂單從創建到完成的完整流程(如待支付 → 待發貨 → 已完成)

  • 工作流引擎??
    審批流程的狀態控制(如提交 → 審核中 → 已批準)

  • ??游戲狀態流轉??
    角色狀態切換(如空閑 → 戰斗 → 死亡)

  • 物聯網設備監控??
    設備狀態跟蹤(如離線 → 在線 → 故障)

2.狀態機示例

2.1 項目結構和依賴包

在這里插入圖片描述

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>spring-state-m</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>21</maven.compiler.source><maven.compiler.target>21</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><spring-boot.version>3.5.3</spring-boot.version></properties><dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!-- Spring State Machine --><dependency><groupId>org.springframework.statemachine</groupId><artifactId>spring-statemachine-starter</artifactId><version>4.0.0</version></dependency><!-- Spring State Machine Redis Persistence --><dependency><groupId>org.springframework.statemachine</groupId><artifactId>spring-statemachine-data-redis</artifactId><version>4.0.0</version></dependency></dependencies>
</project>

啟動類

package org.example;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;@EnableAsync
@SpringBootApplication
public class SpringStateMachine {public static void main(String[] args) {SpringApplication.run(SpringStateMachine.class, args);}
}

2.2 定義事件類和狀態類

事件用于驅動狀態轉移,狀態用于記錄事件進度

事件類

package org.example.common;/*** @Author zhx && moon* @Since 21* @Date 2025-06-18 PM 6:38*/
public enum OrderEvent {PAY,            // 支付操作SHIP,           // 發貨操作CONFIRM,        // 確認收貨CANCEL          // 取消訂單
}

狀態類

package org.example.common;/*** @Author zhx && moon* @Since 21* @Date 2025-06-18 PM 6:37*/
public enum OrderState {UNPAID,         // 待支付PAID,           // 已支付SHIPPED,        // 已發貨CONFIRMED,      // 已確認收貨CANCELLED       // 已取消
}

2.3 Spring 事件監聽器

Spring 事件監聽器,用于異步處理事件流,當狀態機結束時,推送當前狀態機到監聽器,監聽器則從持久化中刪除該狀態機

package org.example.config;import org.example.entity.OrderSMContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;/*** @Author zhx && moon* @Since 21* @Date 2025-06-20 AM 10:18*/
@Component
public class AsyncEventListener {Logger logger = LoggerFactory.getLogger(this.getClass());@AutowiredSMContainer smContainer;@Async@EventListenerpublic void handleAsyncEvent(OrderSMContext context) {logger.info("order id {} has delete {}", context.getOrderId(), smContainer.delete(context.getOrderId()));}}

2.4 狀態機持久化類

利用 Redis 做狀態機的持久化存儲

2.4.1 Redis 狀態機持久化容器

package org.example.config;import org.example.common.OrderEvent;
import org.example.common.OrderState;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.statemachine.data.redis.RedisStateMachineContextRepository;
import org.springframework.statemachine.persist.RepositoryStateMachinePersist;
import org.springframework.stereotype.Component;/*** @Author zhx && moon* @Since 21* @Date 2025-06-18 PM 6:54*/
@Component
public class MYRedisPerSisterConfig {@Autowiredprivate RedisConnectionFactory factory;/*** 創建 RedisStateMachineRepository 實例*/@Bean(name = "redisStateMachineContextRepository")public MYRedisStateMachinePer<OrderState, OrderEvent> getRedisPerSister() {// 創建 RedisStateMachineRepository 實例RedisStateMachineContextRepository<OrderState, OrderEvent> repository = new RedisStateMachineContextRepository<>(factory);// 持久化RepositoryStateMachinePersist perSister = new RepositoryStateMachinePersist(repository);// 獲取 Redis StateMachinePerSister 實例MYRedisStateMachinePer machine = new MYRedisStateMachinePer<>(perSister);RedisTemplate<String, byte[]>  redisTemplate = createDefaultTemplate(factory);machine.setRedisTemplate(redisTemplate);// 返回return machine;}/*** 與 RedisStateMachineContextRepository 使用相同的序列化配置* @param connectionFactory* @return*/private static RedisTemplate<String, byte[]> createDefaultTemplate(RedisConnectionFactory connectionFactory) {RedisTemplate<String, byte[]> template = new RedisTemplate();template.setKeySerializer(new StringRedisSerializer());template.setHashKeySerializer(new StringRedisSerializer());template.setConnectionFactory(connectionFactory);template.afterPropertiesSet();return template;}
}

2.4.2 Redis 配置

package org.example.config;import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.statemachine.StateMachinePersist;
import org.springframework.statemachine.data.redis.RedisStateMachinePersister;/*** @Author zhx && moon* @Since 21* @Date 2025-06-19 PM 5:21*/
public class MYRedisStateMachinePer<S, E> extends RedisStateMachinePersister<S, E> {RedisTemplate<String, byte[]> redisTemplate;public MYRedisStateMachinePer(StateMachinePersist<S, E, String> stateMachinePersist) {super(stateMachinePersist);}public void setRedisTemplate(RedisTemplate<String, byte[]> redisTemplate){this.redisTemplate = redisTemplate;}/*** 檢查 Redis 中是否存在指定的 key* @param key* @return*/public boolean isUnExist(String key){return !this.redisTemplate.hasKey(key);}/*** 刪除 Redis 中指定的 key* @param key* @return*/public boolean deleteKey(String key){return this.redisTemplate.delete(key);}}

2.4.3 狀態機監聽器

用于監聽狀態機狀態變化

package org.example.config;import org.example.common.OrderEvent;
import org.example.common.OrderState;
import org.example.entity.OrderSMContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.messaging.Message;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.listener.StateMachineListenerAdapter;
import org.springframework.statemachine.state.State;
import org.springframework.stereotype.Component;/*** @Author zhx && moon* @Since 21* @Date 2025-06-19 PM 4:58*/
@Component
public class RedStateMachineListener extends StateMachineListenerAdapter<OrderState, OrderEvent> {Logger logger = LoggerFactory.getLogger(this.getClass());@Autowiredprivate ApplicationEventPublisher publisher;/*** 狀態變化* @param from* @param to*/@Overridepublic void stateChanged(State<OrderState, OrderEvent> from, State<OrderState, OrderEvent> to) {// 狀態變更時的處理if (null == from) {logger.info("state machine init, from Init to {}", to.getId());} else {logger.info("state machine change, from {} to {}", from.getId(), to.getId());}}/*** 狀態機啟動成功時的回調* @param sm*/@Overridepublic void stateMachineStarted(StateMachine<OrderState, OrderEvent> sm) {logger.info("state machine {} start success.", sm.getId());}/*** 狀態機結束的回調* @param sm*/@Overridepublic void stateMachineStopped(StateMachine<OrderState, OrderEvent> sm) {logger.info("state machine {} stop success.", sm.getId());publisher.publishEvent(new OrderSMContext(sm.getId()));}@Overridepublic void eventNotAccepted(Message<OrderEvent> event) {logger.error("Event not accepted: {}", event.getPayload());}}

2.5 裝機器容器

用于管理狀態機的創建,本地化緩存與持久化存儲

package org.example.config;import org.example.common.OrderEvent;
import org.example.common.OrderState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.config.StateMachineFactory;
import org.springframework.stereotype.Component;import java.util.HashMap;
import java.util.Map;
import java.util.Objects;/*** @Author zhx && moon* @Since 21* @Date 2025-06-19 PM 4:30*/
@Component
public class SMContainer {Logger logger = LoggerFactory.getLogger(this.getClass());@Autowiredprivate StateMachineFactory<OrderState, OrderEvent> factory;@Autowiredprivate MYRedisStateMachinePer<OrderState, OrderEvent> myRedisStateMachinePer;private Map<String, StateMachine<OrderState, OrderEvent>> map = new HashMap<>(16);/*** 獲取狀態機* @param orderId 訂單ID* @return 狀態機實例*/public synchronized StateMachine<OrderState, OrderEvent> getStateMachine(String orderId) {String key = getKey(orderId);try {// 取緩存StateMachine<OrderState, OrderEvent> sm = map.get(orderId);// 校驗if (Objects.isNull(sm)) {// 獲取狀態機實例sm = factory.getStateMachine(orderId);// 校驗是否存在if (myRedisStateMachinePer.isUnExist(key)) {sm.startReactively().subscribe();myRedisStateMachinePer.persist(sm, key);} else {// 恢復狀態myRedisStateMachinePer.restore(sm, key);}// 緩存狀態機map.put(orderId, sm);}return sm;} catch (Exception e) {logger.error("get state machine error: {}", e.getMessage(), e);return null;}}/*** 保存狀態機* @param orderId* @param stateMachine*/public synchronized boolean save(StateMachine<OrderState, OrderEvent> stateMachine, String orderId){try {String key = getKey(orderId);myRedisStateMachinePer.persist(stateMachine, key);return true;} catch (Exception e) {logger.error("save state machine error: {}", e.getMessage(), e);return false;}}/*** 刪除狀態機* @param orderId* @return*/public synchronized boolean delete(String orderId){return myRedisStateMachinePer.deleteKey(getKey(orderId));}/*** 獲取 KEY* @param orderId* @return*/private String getKey(String orderId){return "STATE-MACHINE:" +orderId;}}

2.6 狀態機事件發送器

用于統一發送狀態機事件,管理事件發送過程

package org.example.config;import org.example.common.OrderEvent;
import org.example.common.OrderState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.StateMachineEventResult;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;import java.util.concurrent.atomic.AtomicBoolean;/*** @Author zhx && moon* @Since 21* @Date 2025-06-20 PM 2:22*/
@Component
public class SMEventSender {Logger logger = LoggerFactory.getLogger(this.getClass());@AutowiredSMContainer smContainer;/*** 初始化訂單狀態機* @param orderId*/public void initOrderStateMachine(String orderId) {smContainer.getStateMachine(orderId);}/*** 發送事件* @param orderId* @param event* @return*/public boolean send(String orderId, OrderEvent event) {// 獲取狀態StateMachine<OrderState, OrderEvent> sm = smContainer.getStateMachine(orderId);// 構建事件消息Message<OrderEvent> message = MessageBuilder.withPayload(event).setHeader("orderId", orderId) // 訂單對象關聯狀態機.build();// 發送事件AtomicBoolean result = new AtomicBoolean(false);sm.sendEvent(Mono.just(message)).subscribe(r->{if (r.getResultType() == StateMachineEventResult.ResultType.ACCEPTED) {// 成功result.set(true);// 在未完成時持久化if (!OrderEvent.CONFIRM.equals(event)) {smContainer.save(sm, orderId);}} else {result.set(false);}});// 輸出logger.info("send event: {}, orderId: {}, result: {}", event, orderId, result.get());// 返回return result.get();}}

2.7 狀態機配置

狀態機配置,定義事件和狀態關系,以及守衛和動作

package org.example.config;import org.example.common.OrderEvent;
import org.example.common.OrderState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.statemachine.config.EnableStateMachineFactory;
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
import org.springframework.statemachine.config.builders.StateMachineConfigurationConfigurer;
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;import java.util.EnumSet;/*** @Author zhx && moon* @Since 21* @Date 2025-06-18 PM 6:38*/
@Configuration
@EnableStateMachineFactory
public class StateMachineConfig extends StateMachineConfigurerAdapter<OrderState, OrderEvent> {Logger logger = LoggerFactory.getLogger(this.getClass());@AutowiredRedStateMachineListener listener;@Overridepublic void configure(StateMachineConfigurationConfigurer<OrderState, OrderEvent> config) throws Exception {config.withConfiguration()// 注冊監聽器.listener(listener);}/*** 狀態機初始化* @param states* @throws Exception*/@Overridepublic void configure(StateMachineStateConfigurer<OrderState, OrderEvent> states) throws Exception {states.withStates().initial(OrderState.UNPAID).states(EnumSet.allOf(OrderState.class)).end(OrderState.CONFIRMED).end(OrderState.CANCELLED);}/*** 狀態轉移邏輯* @param transitions* @throws Exception*/@Overridepublic void configure(StateMachineTransitionConfigurer<OrderState, OrderEvent> transitions) throws Exception {transitions// 支付:UNPAID -> PAID.withExternal().source(OrderState.UNPAID).target(OrderState.PAID).guard(context -> {// (前置)守衛條件,校驗支付結果logger.info("check order {} pay result ...", context.getMessageHeader("orderId"));return true;}).action(context -> {// (后置)觸發動作,通知倉庫備貨logger.info("order {} pay success, notify warehouse to prepare goods ...", context.getMessageHeader("orderId"));}).event(OrderEvent.PAY).and()// 發貨:PAID -> SHIPPED.withExternal().source(OrderState.PAID).target(OrderState.SHIPPED).event(OrderEvent.SHIP).and()// 確認收貨:SHIPPED -> CONFIRMED.withExternal().source(OrderState.SHIPPED).target(OrderState.CONFIRMED).event(OrderEvent.CONFIRM).and()// 取消訂單(僅在待支付可取消).withExternal().source(OrderState.UNPAID).target(OrderState.CANCELLED).event(OrderEvent.CANCEL);}}

2.8 接口類

用于模擬訂單操作

package org.example.controller;import org.example.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/*** @Author zhx && moon* @Since 21* @Date 2025-06-18 PM 6:41*/
@RestController
@RequestMapping("/orders")
public class OrderController {@Autowiredprivate OrderService orderService;@GetMapping("/create")public String create() {return orderService.createOrder();}@GetMapping("/pay/{orderId}")public String pay(@PathVariable("orderId") String orderId) {return orderService.payOrder(orderId);}@GetMapping("/shipped/{orderId}")public String shipped(@PathVariable("orderId") String orderId) {return orderService.shipped(orderId);}@GetMapping("/confirm/{orderId}")public String confirm(@PathVariable("orderId") String orderId) {return orderService.confirm(orderId);}@GetMapping("/{orderId}/status")public String status(@PathVariable String orderId) {return "當前狀態: " + orderService.getOrderState(orderId);}}

2.9 實現類

package org.example.service;import org.example.common.OrderEvent;
import org.example.common.OrderState;
import org.example.config.SMEventSender;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;/*** @Author zhx && moon* @Since 21* @Date 2025-06-18 PM 6:40*/
@Service
public class OrderService {@AutowiredSMEventSender smEventSender;/*** 創建訂單并初始化狀態機* @return*/public String createOrder() {try {// 使用時間戳作為訂單IDString orderId = String.valueOf(System.currentTimeMillis());// 初始化smEventSender.initOrderStateMachine(orderId);// 返回訂單IDreturn orderId;} catch (Exception e) {return e.getMessage();}}/*** 支付* @param orderId* @return*/public String payOrder(String orderId) {try {boolean result = smEventSender.send(orderId, OrderEvent.PAY);return "success:" + result;} catch (Exception e) {return e.getMessage();}}/*** 發貨* @param orderId* @return*/public String shipped(String orderId) {try {boolean result = smEventSender.send(orderId, OrderEvent.SHIP);return "success:" + result;} catch (Exception e) {return e.getMessage();}}/*** 確認收貨* @param orderId* @return*/public String confirm(String orderId) {try {boolean result = smEventSender.send(orderId, OrderEvent.CONFIRM);return "success:" + result;} catch (Exception e) {return e.getMessage();}}public OrderState getOrderState(String orderId) {return OrderState.UNPAID;}
}

2.10 狀態機上下文

用于管理狀態機信息

package org.example.entity;import org.example.common.OrderState;import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;/*** @Author zhx && moon* @Since 21* @Date 2025-06-18 PM 6:54*/
public class OrderSMContext {public OrderSMContext(String orderId){this.orderId = orderId;}private String orderId;private OrderState currentState;private Map<String, Object> extendedState = new HashMap<>();private LocalDateTime createdAt;private LocalDateTime lastModifiedAt;public String getOrderId() {return orderId;}public void setOrderId(String orderId) {this.orderId = orderId;}
}

2.11 配置文件

spring:data:redis:database: 0host: 192.168.1.103port: 6379password: 123456timeout: 5000

3.狀態機測試

3.1創建訂單

在這里插入圖片描述

3.2持久化結果

初始化時自動將數據持久化到 Redis

在這里插入圖片描述

3.3 支付訂單

在這里插入圖片描述

3.4 發貨

在這里插入圖片描述

3.5 確認收貨

在這里插入圖片描述

后臺日志

在這里插入圖片描述

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

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

相關文章

實戰四:基于PyTorch實現貓狗分類的web應用【2/3】

?一、需求描述 實戰四分為三部分來實現&#xff0c;第二部分是基于PyTorch的貓狗圖像可視化訓練的教程&#xff0c;實現了一個完整的貓狗分類模型訓練流程&#xff0c;使用預訓練的ResNet50模型進行遷移學習&#xff0c;并通過SwanLab進行實驗跟蹤。 效果圖 ?二、實現思路 …

對比幾個測試云的一些速度

最近被hosting vps主機的速度給困擾了&#xff0c;干脆放下手中的活 測試下 test.php放在網站根目錄即可 代碼如下&#xff1a; <?php /*** 最終版服務器性能測試工具* 測試項目&#xff1a;CPU運算性能、內存讀寫速度、硬盤IO速度、網絡下載速度*/// 配置參數&#xff…

UE5 Grid3D 學習筆記

一、Neighbor Grid 3D 的核心作用 NeighborGrid3D 是一種基于位置的哈希查找結構&#xff0c;將粒子按空間位置劃分到網格單元&#xff08;Cell&#xff09;中&#xff0c;實現快速鄰近查詢&#xff1a; 空間劃分&#xff1a;將模擬空間劃分為多個三維網格單元&#xff08;Cel…

Spring AI ——在springboot應用中實現基本聊天功能

文章目錄 前言測試環境項目構建依賴引入指定openai 相關配置基于 application.yml 配置 Open AI 屬性application.yml編寫測試類測試請求基于讀取后配置請求編寫測試接口測試效果展示流式輸出前言 AI 技術越來越火爆,作為Java開發人員也不能拖了后腿。 前段時間使用LangChain…

條件概率:不確定性決策的基石

條件概率是概率論中的核心概念&#xff0c;用于描述在已知某一事件發生的條件下&#xff0c;另一事件發生的概率。它量化了事件之間的關聯性&#xff0c;是貝葉斯推理、統計建模和機器學習的基礎。 本文由「大千AI助手」原創發布&#xff0c;專注用真話講AI&#xff0c;回歸技術…

搭建Flink分布式集群

1. 基礎環境&#xff1a; 1.1 安裝JDK 本次使用 jdk-11.0.26_linux-x64_bin.tar.gz 解壓縮 tar -zxvf jdk-11.0.26_linux-x64_bin.tar.gz -C /usr/local/java/ 配置環境變量&#xff1a; vi /etc/profileJAVA_HOME/usr/local/java/jdk-11.0.26 CLASSPATH.:${JAVA_HOME}/li…

基于ssm校園綜合服務系統微信小程序源碼數據庫文檔

摘 要 隨著我國經濟迅速發展&#xff0c;人們對手機的需求越來越大&#xff0c;各種手機軟件也都在被廣泛應用&#xff0c;但是對于手機進行數據信息管理&#xff0c;對于手機的各種軟件也是備受用戶的喜愛&#xff0c;校園綜合服務被用戶普遍使用&#xff0c;為方便用戶能夠可…

桌面小屏幕實戰課程:DesktopScreen 17 HTTPS

飛書文檔http://https://x509p6c8to.feishu.cn/docx/doxcn8qjiNXmw2r3vBEdc7XCBCh 源碼參考&#xff1a; /home/kemp/work/esp/esp-idf/examples/protocols/https_request 源碼下載方式參考&#xff1a; 源碼下載方式 獲取網站ca證書 openssl s_client -showcerts -connec…

uniapp上傳gitee

右鍵點擊項目&#xff0c;選擇git提交&#xff0c;會彈出這樣的彈窗 在Message輸入框里面輸入更新的內容&#xff0c;選擇更新過的文件&#xff0c;然后點擊commit 然后點擊push 后面會讓你填寫gitee的用戶名和密碼 用戶名就是郵箱 密碼就是登錄gitee的密碼

重寫(Override)與重載(Overload)深度解析

在Java面向對象編程中&#xff0c;多態性是一個核心概念&#xff0c;它允許我們以統一的方式處理不同類型的對象。而實現多態性的兩種重要機制便是方法的“重寫”&#xff08;Override&#xff09;與“重載”&#xff08;Overload&#xff09;。透徹理解這兩者之間的區別與聯系…

Go 語言中操作 SQLite

sqlite以其無需安裝和配置&#xff1a;直接使用數據庫文件&#xff0c;無需啟動獨立的數據庫服務進程。 單文件存儲&#xff1a;整個數據庫&#xff08;包括表、索引、數據等&#xff09;存儲在單個跨平臺文件中&#xff0c;便于遷移和備份。 在應對的小型應用軟件中.有著不可…

【硬核數學】2.3 AI的“想象力”:概率深度學習與生成模型《從零構建機器學習、深度學習到LLM的數學認知》

歡迎來到本系列的第八篇文章。在前七章中&#xff0c;我們已經構建了一個強大的深度學習工具箱&#xff1a;我們用張量來處理高維數據&#xff0c;用反向傳播來高效地計算梯度&#xff0c;用梯度下降來優化模型參數。我們訓練出的模型在分類、回歸等任務上表現出色。 但它們有…

華為云Flexus+DeepSeek征文|Dify平臺開發搭建口腔牙科24小時在線問診系統(AI知識庫系統)

引言&#xff1a;為什么需要口腔牙科24小時在線問診系統&#xff1f; 在口腔醫療領域&#xff0c;“時間”是患者最敏感的需求之一——深夜牙齒突發疼痛、周末想提前了解治療方案、異地患者無法及時到院……傳統“工作時間在線”的咨詢模式已無法滿足用戶需求。同時&#xff0…

嵌入式硬件中電容的基本原理與詳解

大家好我們今天重討論點知識點如下: 1.電容在電路中的作用 2.用生活中水缸的例子來比喻電容 3.電容存儲能力原理 4.電容封裝的種類介紹電容種類圖片辨識 5.X 電容的作用介紹 6.Y 電容的作用介紹7.鉭電容的優點及特性 7.鉭電容的缺點及特性 8. 鋁電解電容的優點及特性…

中央空調控制系統深度解析:從原理到智能AIOT運維

——附水冷式系統全電路圖解與技術參數 一、中央空調系統架構與技術演進 1. 兩大主流系統對比 技術趨勢&#xff1a;2023年全球冷水機組市場占比達68%&#xff08;BSRIA數據&#xff09;&#xff0c;其核心優勢在于&#xff1a; - 分區控溫精度&#xff1a;0.5℃&#…

document.write 和 innerHTML、innerText 的區別

document.write 與 innerHTML、innerText 的區別 document.write 直接寫入 HTML 文檔流&#xff0c;若在頁面加載完成后調用會覆蓋整個文檔。常用于動態生成內容&#xff0c;但會破壞現有 DOM 結構&#xff0c;不推薦在現代開發中使用。 document.write("<p>直接寫…

日志分析與實時監控:Elasticsearch在DevOps中的核心作用

引言 在現代DevOps實踐中&#xff0c;日志分析與實時監控是保障系統穩定性與性能的關鍵。Elasticsearch作為分布式搜索與分析引擎&#xff0c;憑借其高效的索引與查詢能力&#xff0c;成為構建日志管理與監控系統的核心組件。本文將深入探討Elasticsearch在DevOps中的應用&…

Unity Catalog 三大升級:Data+AI 時代的統一治理再進化

在剛剛落幕的 2025 Databricks Data AI Summit 上&#xff0c;Databricks 重磅發布了多項 Lakehouse 相關功能更新。其中&#xff0c;面向數據湖治理場景的統一數據訪問與管理方案 —— Unity Catalog&#xff0c;迎來了三大關鍵升級&#xff1a;全面支持 Apache Iceberg、面向…

電容屏觸摸不靈敏及跳點問題分析

在電容屏的使用過程中&#xff0c;觸摸不靈敏和觸點不精準是極為常見且讓人困擾的問題。這些問題不僅影響用戶的操作體驗&#xff0c;在一些對觸摸精度要求較高的場景&#xff0c;如工業控制、繪圖設計等領域&#xff0c;還可能導致嚴重的后果。下面我們就來深入剖析一下這兩個…

小程序學習筆記:導航、刷新、加載、生命周期

在小程序開發的領域中&#xff0c;掌握視圖與邏輯相關的技能是打造功能完備、用戶體驗良好應用的關鍵。今天&#xff0c;咱們就來深入梳理一下小程序視圖與邏輯的學習要點&#xff0c;并結合代碼示例&#xff0c;讓大家有更直觀的理解。 一、頁面之間的導航跳轉 在小程序里實…