Minio入門+適配器模式(實戰教程)

一、安裝Minio

1.1 拉取鏡像

docker pull minio/minio

docker images

1.2創建掛載目錄

1.2.1 創建數據目錄

mkdir -p /docker-minio/data

1.2.2 創建配置文件目錄

mkdir -p /docker-minio/config

1.2.3 設置權限

chmod -R 777 /docker-minio/data /docker-minio/config

1.3啟動MinIO容器

docker run -d --name minio \-p 9000:9000 -p 9090:9090 \-e "MINIO_ROOT_USER=minioAdmin" \-e "MINIO_ROOT_PASSWORD=minioAdmin" \-v /docker-minio/data:/data \-v /docker-minio/config:/root/.minio \minio/minio server /data \--console-address ":9090" \--address ":9000"

注意:MinIO 規定 Access key 長度至少為 3,Secret key 長度至少為 8。

這個 Docker 命令用于啟動一個?MinIO 對象存儲服務器容器。MinIO 是一個高性能、與 Amazon S3 API 兼容的開源對象存儲解決方案。下面是詳細解釋:

1.?docker run

  • 作用:?Docker 命令的核心部分,用于創建并啟動一個新的容器。

2.?-d

  • 作用:?detach?的縮寫。以后臺(守護進程)模式運行容器。容器啟動后,控制臺會立即返回,你可以繼續使用終端,而容器在后臺運行。要查看容器日志,可以使用?docker logs minio

3.?--name minio

  • 作用:?為容器指定一個名稱?minio。這使得后續管理容器(如啟動、停止、查看日志)更加方便,無需使用復雜的容器 ID。例如:

    • docker stop minio

    • docker start minio

    • docker logs minio

4.?-p 9000:9000 -p 9090:9090

  • 作用:?將容器內部的端口映射到宿主機的端口。

    • -p 9000:9000: 將容器內部的?9000 端口映射到宿主機的?9000 端口。這個端口是?MinIO API 服務端口,用于客戶端(SDK、命令行工具?mc、應用程序)與 MinIO 服務進行交互(上傳、下載、管理對象等),兼容 S3 API。

    • -p 9090:9090: 將容器內部的?9090 端口映射到宿主機的?9090 端口。這個端口是?MinIO 控制臺(Web UI)端口,用于通過瀏覽器訪問圖形化管理界面來管理存儲桶、用戶、策略等。

5.?-e "MINIO_ROOT_USER=minioAdmin"

  • 作用:?設置容器內的環境變量?MINIO_ROOT_USER。這個變量定義了 MinIO 的?根用戶(管理員)用戶名。這里設置為?minioAdmin非常重要!

6.?-e "MINIO_ROOT_PASSWORD=minioAdmin"

  • 作用:?設置容器內的環境變量?MINIO_ROOT_PASSWORD。這個變量定義了 MinIO 的?根用戶(管理員)密碼。這里設置為?minioAdmin非常重要!強烈建議在生產環境中使用強密碼替代這個示例密碼。

7.?-v /docker-minio/data:/data

  • 作用:?創建一個數據卷,將宿主機上的目錄?/docker-minio/data?掛載到容器內部的目錄?/data

    • /docker-minio/data: 宿主機上的目錄路徑,這個目錄將持久化存儲 MinIO 對象(文件)本身

    • /data: 容器內部的路徑。MinIO 服務器會將所有上傳的對象存儲在這個目錄下。

    • 意義:?這個掛載確保了 MinIO 存儲的實際文件數據不會丟失。即使容器被刪除或重啟,宿主機?/docker-minio/data?下的數據仍然存在。下次啟動新容器并掛載同一目錄,數據即可恢復。

8.?-v /docker-minio/config:/root/.minio

  • 作用:?創建另一個數據卷,將宿主機上的目錄?/docker-minio/config?掛載到容器內部的目錄?/root/.minio

    • /docker-minio/config: 宿主機上的目錄路徑,這個目錄將持久化存儲 MinIO 的服務器配置、用戶信息、策略等元數據

    • /root/.minio: 容器內部 MinIO 服務默認存儲其配置文件和狀態的路徑。

    • 意義:?這個掛載確保了 MinIO 的配置、用戶賬號、訪問策略等關鍵元數據不會丟失。刪除或重建容器后,只要掛載回這個目錄,所有配置和用戶信息都會保留。

9.?minio/minio

  • 作用:?指定要運行的?Docker 鏡像。這里是官方 MinIO 鏡像,從 Docker Hub 的?minio/minio?倉庫拉取。如果本地沒有,Docker 會自動從 Hub 下載。

10.?server /data

  • 作用:?這是傳遞給?minio/minio?鏡像的?啟動命令

    • server: 告訴 MinIO 可執行文件以服務器模式運行。

    • /data: 指定 MinIO 服務器在容器內部存儲對象數據的路徑。這必須與第 7 條 (-v ...:/data) 中掛載到容器內部的路徑一致。MinIO 會使用這個目錄來保存上傳的文件。

11.?--console-address ":9090"

  • 作用:?MinIO 服務器啟動參數。顯式指定 MinIO 控制臺(Web UI)監聽的地址和端口

    • :9090: 表示綁定到容器內的所有網絡接口 (0.0.0.0) 的 9090 端口。這直接對應了第 4 條 (-p 9090:9090) 中映射的端口。訪問?http://<宿主機IP>:9090?即可打開管理控制臺。

12.?--address ":9000"

  • 作用:?MinIO 服務器啟動參數。顯式指定 MinIO API 服務(S3 兼容接口)監聽的地址和端口

    • :9000: 表示綁定到容器內的所有網絡接口 (0.0.0.0) 的 9000 端口。這直接對應了第 4 條 (-p 9000:9000) 中映射的端口。客戶端(如?mc,AWS SDK, 應用程序)通過?http://<宿主機IP>:9000?來訪問存儲服務。

1.4 訪問Minio控制臺

啟動容器后,可以通過瀏覽器訪問 MinIO 控制臺:

http://<宿主機IP>:9001

使用之前設置的用戶名和密碼(minioAdmin?和?minioAdmin)登錄。

二、SpringBoot集成minio

2.1 導入maven做標

        <dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.2.0</version></dependency>

2.2 自定義配置

在yml添加如下配置:

minio:url: http://121.40.159.231:9000#minio賬戶accessKey: minioAdmin#minio密碼secretKey: minioAdminbucketName: nbsjfx

然后創建對應的配置類:

@Data
@Component
@ConfigurationProperties(prefix = "minio")
public class MinioProp {/*** Minio存儲服務服務的地址*/private String url;/*** Minio的訪問賬號*/private String accessKey;/*** Minio的訪問密碼*/private String secretKey;/*** Minio的存儲桶名稱*/private String bucketName;}

2.3 創建MinioClient(向 Spring 容器中注冊一個 MinioClient 類型的 Bean),并創建Bucket

@Configuration
@RequiredArgsConstructor
public class MinioConfig {private final MinioProp minioProp;/*** 創建MinioClient實例*/@Beanpublic MinioClient minioClient() {MinioClient minioClient = MinioClient.builder().endpoint(minioProp.getUrl()).credentials(minioProp.getAccessKey(), minioProp.getSecretKey()).build();return minioClient;}/*** 創建Bucket*/@SneakyThrows@PostConstructpublic void createBucket() {MinioClient minioClient = minioClient();boolean bucketExists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(minioProp.getBucketName()).build());if (!bucketExists) {minioClient.makeBucket(MakeBucketArgs.builder().bucket(minioProp.getBucketName()).build());}}}

2.4 自定義工具類

自定義的MinioUtil代碼如下:

@Component
@RequiredArgsConstructor
public class MinioUtil {private final MinioClient minioClient;private final MinioProp minioProp;private final HttpServletResponse httpServletResponse;/*** 檢查bucket是否存在,不存在則創建** @param bucketName bucket名稱* @return 是否創建成功*/@SneakyThrowspublic Boolean createBucket(String bucketName) {boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());if (!exists) {minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());}return Boolean.TRUE;}/*** 獲取所有bucket列表** @return bucket列表*/@SneakyThrowspublic List<Bucket> getAllBuckets() {List<Bucket> bucketList = minioClient.listBuckets();return bucketList;}/*** 刪除bucket (桶為空時,才能刪除)** @param bucketName bucket名稱* @return 是否刪除成功*/@SneakyThrowspublic Boolean deleteBucket(String bucketName) {minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());return Boolean.TRUE;}/*** 獲取bucket中的所有文件列表** @param bucketName bucket名稱* @return 文件列表*/@SneakyThrowspublic List<Item> getAllFilesByBucket(String bucketName) {Iterable<Result<Item>> iterable = minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).build());List<Item> itemList = new ArrayList<>();for (Result<Item> result : iterable) {Item item = result.get();itemList.add(item);}return itemList;}/*** 上傳文件** @param inputStream 文件輸入流* @param bucketName  bucket名稱* @param fileName    文件名稱* @return 是否上傳成功*/@SneakyThrowspublic Boolean uploadFile(InputStream inputStream, String bucketName, String fileName) {minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(fileName).stream(inputStream, -1, 5242889L).build());return Boolean.TRUE;}/*** 上傳文件** @param multipartFile 文件對象* @return 是否上傳成功*/@SneakyThrowspublic Boolean uploadFile(MultipartFile multipartFile) {return uploadFile(multipartFile.getInputStream(), minioProp.getBucketName(), multipartFile.getOriginalFilename());}/*** 刪除文件** @param bucketName bucket名稱* @param fileName   文件名稱* @return 是否刪除成功*/@SneakyThrowspublic Boolean deleteFile(String bucketName, String fileName) {minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(fileName).build());return Boolean.TRUE;}/*** 刪除文件** @param fileName 文件名稱* @return 是否刪除成功*/public Boolean deleteFile(String fileName) {return deleteFile(minioProp.getBucketName(), fileName);}/*** 下載文件** @param bucketName bucket名稱* @param fileName   文件名稱*/@SneakyThrowspublic void downloadFile(String bucketName, String fileName) {GetObjectResponse getObjectResponse = minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(fileName).build());byte[] buf = new byte[1024];int len;try (FastByteArrayOutputStream os = new FastByteArrayOutputStream()) {while ((len = getObjectResponse.read(buf)) != -1) {os.write(buf, 0, len);}os.flush();byte[] bytes = os.toByteArray();httpServletResponse.setCharacterEncoding("utf-8");// 設置強制下載不打開//httpServletResponse.setContentType("application/force-download");httpServletResponse.addHeader("Access-Control-Expose-Headers", "Content-Disposition");httpServletResponse.addHeader("Content-Disposition", "attachment;filename=".concat(URLEncoder.encode(fileName, "UTF-8")));try (ServletOutputStream stream = httpServletResponse.getOutputStream()) {stream.write(bytes);stream.flush();}}}/*** 下載文件** @param fileName 文件名稱*/public void downloadFile(String fileName) {downloadFile(minioProp.getBucketName(), fileName);}/*** 獲取預覽文件url (預覽鏈接默認7天后過期)** @param bucketName bucket名稱* @param fileName   文件名稱* @return 文件url*/@SneakyThrowspublic String getPreviewFileUrl(String bucketName, String fileName) {GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs.builder().method(Method.GET).bucket(bucketName).object(fileName).build();return minioClient.getPresignedObjectUrl(args);}/*** 獲取預覽文件url (預覽鏈接默認7天后過期)** @param fileName 文件名稱* @return 文件url*/public String getPreviewFileUrl(String fileName) {return getPreviewFileUrl(minioProp.getBucketName(), fileName);}}

三、nginx代理minio的文件鏈接

3.1 前置說明

當我們創建桶后,Minio會在數據掛載目錄下,創建一個和桶同名的文件夾。

上面的過程中,我們創建了一個為nbsjfx的桶,對應的文件夾如下:

目前桶里有一個文件,為1.jpg:

3.2 反向代理

 server {listen 9999;server_name 127.0.0.1;location / {root /docker-minio/data;}

測試結果:

四、適配器模式(實戰教程)

百度百科對于適配器的介紹:適配器模式_百度百科

????????在計算機編程中,適配器模式(有時候也稱包裝樣式或者包裝)將一個類的接口適配成用戶所期待的。一個適配允許通常因為接口不兼容而不能在一起工作的類工作在一起,做法是將類自己的接口包裹在一個已存在的類中。

????????適配器模式(Adapter Pattern)是一種結構型設計模式,它允許接口不兼容的類能夠一起工作。適配器模式通過將一個類的接口轉換成客戶期望的另一個接口,使得原本由于接口不兼容而不能一起工作的類可以一起工作。

????????在這個場景中,我們需要實現一個統一的OSS(對象存儲服務)接口,然后為不同的云存儲服務(如minio、阿里云OSS、京東云OSS)提供適配器。這樣,客戶端就可以通過統一的接口來操作不同的云存儲服務,而無需關心底層不同服務的具體實現細節。

4.1 創建OSS適配器接口

/*** OSS適配器接口*/
public interface OssAdapter {/*** 上傳文件* @param multipartFile 上傳的文件* @return 上傳成功返回true,否則返回false*/Boolean uploadFile(MultipartFile multipartFile);}

我們這里通過上傳文件方法作為案例,希望不管什么廠商的Oss都通過這個接口的方式進行文件上傳

4.2 創建對應的適配器實現類

4.2.1 創建minio適配器實現類

/*** Minio Oss 適配器*/
@Slf4j
public class MinioOssAdapter implements OssAdapter {@Autowiredprivate MinioUtil minioUtil;@Overridepublic Boolean uploadFile(MultipartFile multipartFile) {log.info("Minio適配器實現文件上傳");return minioUtil.uploadFile(multipartFile);}}

注意到,此處我們沒有把該類注冊為spring的bean,所以@Autowired注解在提升錯誤。

因為我們的系統,一般都只使用一種文件存儲服務,使用我們這里預期是到時候通過配置類的形式交由spring容器進行管理。

4.2.2 創建aliyun適配器實現類

/*** 阿里云 OSS 適配器*/
@Slf4j
public class AliyunOssAdapter implements OssAdapter {//也是注入阿里云Oss相關的工具類和實現等@Overridepublic Boolean uploadFile(MultipartFile multipartFile) {log.info("阿里云適配器實現文件上傳");// TODO 阿里云 OSS 上傳文件return null;}}

4.2.3 創建配置類,按需注入

首先在yml文件中,自定義類型:

oss:oss-type: minio

然后創建配置類如下:(根據類型完成注入)

@Slf4j
@Configuration
public class OssConfig {@Value("${oss.oss-type}")private String ossType;@Beanpublic OssAdapter ossAdapter(){log.info("文件存儲ossType: {}", ossType);if ("minio".equals(ossType)){return new MinioOssAdapter();}else if ("aliyun".equals(ossType)){return new AliyunOssAdapter();}throw new IllegalArgumentException("未找到對應的Oss文件存儲適配器");}}

4.3 抽取文件服務類(根據自己的系統自定義)

@Service
public class FileService {@Autowiredprivate OssAdapter ossAdapter;public Boolean uploadFile(MultipartFile multipartFile) {return ossAdapter.uploadFile(multipartFile);}}

4.4 編寫控制層進行測試

@RestController
@RequestMapping("/file")
public class FileController {@Autowiredprivate FileService fileService;@RequestMapping("/uploadFile")public IResult uploadFile(MultipartFile multipartFile) {return new ResultBean<>(fileService.uploadFile(multipartFile));}}

當配置文件配置的類型為minio時,測試結果:

同時minio中也確實上傳了文件:

當我們把配置文件的類型改為aliyun時,測試結果:

4.5 總結

至此,我們實現將不同 OSS 提供商的接口抽象成一個統一的接口,從而實現解耦和靈活切換。

優勢:

  1. 統一接口:客戶端使用一致的API操作不同云存儲

  2. 解耦:業務代碼與具體云服務實現解耦

  3. 可擴展:新增云服務只需添加新適配器

  4. 易維護:各云服務實現相互隔離,修改互不影響

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

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

相關文章

LLaMA-Factory 對 omnisql 進行 ppo dpo grpo nl2sql任務 實現難度 時間 全面對比

在LLaMA-Factory框架下&#xff0c;針對omnisql任務&#xff08;自然語言到SQL生成&#xff09;應用PPO、DPO、GRPO三種算法的實現難度、時間及全面對比如下&#xff1a; 一、實現難度對比 1. PPO&#xff08;近端策略優化&#xff09; 難度&#xff1a;★★☆☆☆&#xff…

Kingbase 數據庫中的 sys_guid() 函數報錯

解決 Kingbase 數據庫中的 sys_guid() 函數報錯問題 問題背景 Kingbase 數據庫在遷移或使用過程中&#xff0c;可能會遇到 select sys_guid() 函數報錯 , 提示函數不存在的情況&#xff0c;這通常是由于以下幾種原因造成的&#xff1a; 函數未正確安裝或未啟用函數參數不符合…

零基礎RT-thread第五節:電容按鍵(2)

上一章的電容按鍵完全使用的HAL庫的代碼&#xff0c;并沒有使用線程。這里嘗試使用線程來控制電容按鍵。 依舊是 F767 本來以為會很容易實現&#xff0c;沒想到嘗試了很久&#xff0c;電容按鍵一直沒有反應。 static rt_uint32_t measure_charge_time(void) {// 步驟1: 放電 …

華為云Flexus+DeepSeek征文|單機部署 與 CCE 高可用部署下 Dify 性能實測

引言 在當今的 AI 應用開發領域&#xff0c;選擇合適的部署方式對于應用的性能表現、資源利用和成本控制至關重要。華為云為開發者提供了多樣化的部署選擇&#xff0c;其中基于單機 Flexus 實例的基礎版部署和基于 CCE 容器的高可用版部署是兩種常見的方式。本文將深入對比這兩…

釘釘小程序框架:Pinia 狀態管理與持久化存儲封裝

上一篇文章完成了 Pinia 在釘釘小程序中的引入與基礎配置 文章地址&#xff1a;釘釘小程序框架引入 Pinia 狀態管理-CSDN博客 本文將深入探討如何通過Pinia 結合持久化存儲 實現用戶狀態 在上一章節中&#xff0c;我們已經完成了 Pinia 在釘釘小程序中的引入與基礎配置。本章將…

云計算產業鏈

一、云計算定義與分類體系 本質特征 按需服務模式&#xff1a;以網絡化方式提供可配置的計算資源共享池&#xff08;網絡/服務器/存儲/應用&#xff09;。核心能力&#xff1a;快速彈性擴容、資源池化共享、按使用量付費、低管理開銷。技術原理&#xff1a;通過分布式計算將大型…

git使用詳解和示例

什么是 Git&#xff1f; Git 是一個 分布式版本控制系統&#xff08;DVCS&#xff09;&#xff0c;用于跟蹤文件的變化&#xff0c;協調多人協作開發。由 Linus Torvalds 開發&#xff0c;用于管理 Linux 內核代碼。 Git 的核心概念 名稱說明工作區 (Working Directory)你看到…

深度學習的引出

雖然我們的神經?絡給出了令?印象深刻的表現&#xff0c;但這樣的表現帶有?分神秘 ?絡中的權重和偏置是被?動發現的。這意味著我們不能?即解釋?絡怎么做的、做了什么。我們能否找 到?些?法來理解我們的?絡通過什么原理分類?寫數字&#xff1f;并且&#xff0c;在知道…

GEO(生成式引擎優化)—— 內容創作者與企業的生死新戰場

在搜索引擎優化&#xff08;SEO&#xff09;定義了互聯網信息獲取規則數十年后&#xff0c;一場由生成式人工智能&#xff08;AIGC&#xff09;驅動的風暴正悄然重塑整個格局。當ChatGPT、Claude、Gemini等AI助手能夠直接生成整合后的答案&#xff0c;而非僅僅提供鏈接列表時&a…

混合密度模型GMM的似然函數(二)

設 Θ { π k , θ k } k 1 K \varTheta \{ \pi_k, \boldsymbol {\theta}_k \}_{k1}^{K} Θ{πk?,θk?}k1K?為參數向量&#xff0c; X { x 1 , ? , x n } \mathcal {X} \{ {\bm x}_1, \cdots, {\bm x}_n \} X{x1?,?,xn?}為觀測數據&#xff0c;給定數據點的獨立性&a…

selenium元素定位

當我們可以打開瀏覽器后我們如果想要進行web測試我們自然要對網頁的一些功能進行單獨拿出來進行測試&#xff0c;但是我們要怎么才能拿到我們想要的元素&#xff0c;并且對其進行操作呢。 我們就以百度主頁的輸入框為例&#xff0c;如果我們想要王輸入框中輸入一些內容我們就需…

2025第十五屆上海生物發酵展:江蘇健達干燥盛裝赴會

2025 年 8 月 7 - 9 日&#xff0c;上海新國際博覽中心將迎來一場生物發酵行業的盛會 —— 第 15 屆上海國際生物發酵產品與技術裝備展覽會&#xff08;BIOCHINA 2025&#xff09;。作為國內干燥設備領域的領軍企業&#xff0c;江蘇健達干燥工程有限公司受邀盛裝參展&#xff0…

【效率工具】單機游戲修改方案:輕量管理器+全能平臺組合

大家好&#xff01;今天我要給大家介紹兩款超級實用的軟件&#xff0c;專門為喜歡玩單機游戲的小伙伴們準備。 一、風靈月影管理器 不想滿網翻修改器&#xff1f;這個 27M 的小工具直接幫你一鍵搞定&#xff0c;這款軟件是由B站UP鴉無量 開發。 收錄上千款游戲補丁&#xff0c;…

七天學會SpringCloud分布式微服務——01——基礎概念

重點是復習體系&#xff0c;從今天6.24開始&#xff0c;確保轉化為自己的東西心平氣和&#xff0c;腳踏實地學習的是尚硅谷微服務 1、從單體架構到集群架構再到分布式架構 單體架構 就是 所有的功能&#xff08;服務&#xff09;模塊 都部署在同一臺服務器&#xff08;一臺服…

三分鐘學會利用deepseek將復雜信息轉換成可視化圖表

數據可視化是傳達復雜信息的重要手段。通過將數據轉化為直觀的圖表、圖形和交互式界面,我們可以更高效地理解信息、發現趨勢并做出決策。對于普通人來說,要將數據可視化可謂千難萬難。但在AI工具飛速發展的今天,這個過程將會變得非常簡單。今天分享的內容就是如何使用生成式…

PDF處理控件Spire.PDF系列教程:Python中快速提取PDF文本、表格、圖像及文檔信息

在 Python 中讀取 PDF 文檔是實現文檔自動化、內容分析和數據提取的基礎操作之一。無論你處理的是合同、報告、發票&#xff0c;還是科研論文&#xff0c;能夠通過代碼訪問 PDF 內容&#xff0c;不僅能節省時間&#xff0c;還能帶來更高效的處理流程。 要在 Python 中準確提取…

微軟人工智能證書AI-102 | 如何快速通過?

微軟 AI-102 考試&#xff0c;全稱 “Designing and Implementing a Microsoft Azure AI Solution”&#xff0c;是微軟推出的用于驗證考生在 Azure 平臺上設計和實施 AI 解決方案核心能力的認證考試。以下是具體介紹&#xff1a; 考試描述&#xff1a; 考試主要衡量考生實施計…

github使用指南

1、生成SSH密鑰對 ssh-keygen -t ed25519 -C "你的github郵箱"然后根據提示保存路徑&#xff0c;設置密碼 2、將公鑰添加到github cat ~/.ssh/id_ed25519.pub復制輸出內容。 在gihub中點擊New SSH Key&#xff0c;添加密鑰 3、配置git使用SSH地址 git remote se…

AD22以上的基礎操作

1.檢測創建的原理圖器件庫 2.原理圖頁加大 Size&#xff1a;常規和自定義 推薦可視化柵格100mil 快捷鍵VG 3.原理圖器件器件號排序 自動排序&#xff1a;快捷鍵TAA 先解鎖 4.BOM(Bill of Material)物料表導出 description描述&#xff1a;類似精度。 導出各種類型bom表 5…

FastAPI技術深度解析與實戰指南

導讀&#xff1a;在Python Web開發領域經歷了Django和Flask多年統治后&#xff0c;FastAPI的崛起正在重新定義API開發的技術標準。這篇深度技術解析將為開發者揭示FastAPI如何通過獨特的架構設計解決傳統框架的核心痛點。 傳統Python Web框架在面對高并發場景時暴露出明顯的性能…