Spring Boot 静态访问配置属性的解决方案
前言
在Spring Boot开发中,静态访问配置信息是一个常见需求,尤其是在工具类、常量类或非Bean类中直接获取配置值。
问题背景
假设我们的应用需要从application.yml
中读取配置项app.logotype
,并在工具类、静态方法或非Bean类中直接访问该值。传统依赖注入方式(如@Autowired
)存在以下局限:
- 非Bean类无法直接注入:如工具类、静态方法无法通过
@Autowired
获取配置类。 - 频繁获取Bean的性能开销:每次通过
ApplicationContext.getBean()
获取Bean可能影响性能。 - 代码耦合性:配置类与业务逻辑的强依赖可能降低代码可维护性。
因此,我们需要一种无需依赖注入、可静态访问配置的解决方案。
解决方案
方案一:通过Setter方法绑定静态变量
核心思想:利用Spring的@ConfigurationProperties
自动绑定机制,将配置值通过setter方法直接赋值给静态变量。
实现步骤
-
定义配置类:
@Component @ConfigurationProperties(prefix = "app") public class AppConfig {// 静态变量public static String logotype;// 静态方法public static String getLogotype() {return logotype;}// Spring通过setter注入配置值public void setLogotype(String logotype) {AppConfig.logotype = logotype; // 直接赋值静态变量} }
-
配置文件:
app:logotype: "MyLogo"
-
使用方式:
public class Util {public static void printLogo() {System.out.println(AppConfig.getLogotype()); // 直接调用静态方法} }
原理分析
-
Spring的属性绑定机制:
@ConfigurationProperties
的作用:该注解会扫描配置类的属性(字段或setter方法),并根据配置前缀(如app
)将application.yml
中的键值对映射到Bean的属性上。- setter方法调用:Spring通过反射调用
setLogotype
方法,并将配置值(如"MyLogo"
)作为参数传入。此时,setter方法直接将值赋给静态变量logotype
,而非实例变量。 - 静态变量的共享性:由于
logotype
是类级别的静态变量,所有调用AppConfig.getLogotype()
的代码都能访问到同一份值。
-
为何可行:
- Spring的依赖注入机制仅关注方法签名(如
setLogotype
),而不关心方法内部如何处理参数。因此,即使setter方法直接操作静态变量,Spring仍会正常调用该方法完成赋值。
- Spring的依赖注入机制仅关注方法签名(如
优缺点
- 优点:
- 简单直接:无需额外工具类或缓存,代码量最少。
- 自动绑定:Spring自动处理配置文件的解析和赋值,无需手动操作。
- 缺点:
- 破坏封装性:静态变量可能被其他代码随意修改,存在潜在风险。
- 线程安全问题:若静态变量可变,需确保线程安全。
- 初始化顺序依赖:需确保Spring容器初始化完成后访问静态变量。
适用场景
- 配置项较少且需快速实现。
- 项目规模较小,对代码封装性要求不高。
方案二:通过Environment工具类
核心思想:利用Spring的Environment
对象直接获取配置值,并通过工具类静态方法封装访问。
实现步骤
-
创建工具类:
@Component public class ConfigUtil {private static Environment env;// 通过@Autowired注入Environment@Autowiredpublic void setEnvironment(Environment environment) {env = environment;}// 静态方法获取配置值public static String getLogotype() {return env.getProperty("app.logotype");} }
-
使用方式:
public class Util {public static void printLogo() {System.out.println(ConfigUtil.getLogotype());} }
原理分析
- Environment的作用:
Environment
是Spring的核心接口,提供获取所有配置信息的能力(包括application.yml
、系统属性、JVM参数等)。getProperty
方法:通过键名(如app.logotype
)直接查询配置值。
- 静态缓存机制:
- 工具类通过
@Autowired
注入Environment
,并缓存为静态变量。后续调用静态方法时,直接通过env.getProperty()
获取值,无需重复注入。
- 工具类通过
优缺点
- 优点:
- 灵活扩展:可直接通过键名获取任意配置项,无需修改配置类。
- 类型安全:支持
getProperty("key", Class<T> requiredType)
等泛型方法。
- 缺点:
- 键名硬编码:需手动维护配置项的完整键名(如
app.logotype
),可能引入拼写错误。 - 线程安全依赖:
Environment
本身是线程安全的,但需确保容器初始化完成。
- 键名硬编码:需手动维护配置项的完整键名(如
适用场景
- 需频繁访问不同配置项(如
app.logotype
、app.timeout
等)。 - 希望通过键名直接获取值,避免配置类的过度设计。
方案三:通过ApplicationContext获取Bean
核心思想:利用Spring的ApplicationContext
静态引用直接获取配置Bean,并通过静态方法封装访问。
实现步骤
-
保存ApplicationContext:
@SpringBootApplication public class Application {public static ConfigurableApplicationContext context;public static void main(String[] args) {context = SpringApplication.run(Application.class, args);} }
-
配置类添加静态方法:
@Component @ConfigurationProperties(prefix = "app") public class AppConfig {private String logotype;public String getLogotype() {return logotype;}// 静态方法获取配置值public static String getLogotypeStatic() {return Application.context.getBean(AppConfig.class).getLogotype();} }
-
使用方式:
public class Util {public static void printLogo() {System.out.println(AppConfig.getLogotypeStatic());} }
原理分析
- ApplicationContext的作用:
ApplicationContext
是Spring容器的核心接口,管理所有Bean的生命周期和依赖关系。- 静态引用
Application.context
:在应用启动时,将ApplicationContext
保存为静态变量,后续可通过getBean()
直接获取Bean。
- 静态方法封装:
- 配置类提供静态方法,通过
getBean()
获取自身实例(单例Bean),并调用实例方法获取配置值。
- 配置类提供静态方法,通过
优缺点
- 优点:
- 灵活访问:可直接访问配置类的所有属性,无需为每个字段编写静态方法。
- 兼容Spring生态:配置类仍通过
@ConfigurationProperties
自动绑定,无需手动处理。
- 缺点:
- 性能开销:每次调用静态方法都会从容器中获取Bean(但Spring的Bean是单例的,实际影响极小)。
- 依赖关系:需确保应用已启动,
ApplicationContext
已初始化。
适用场景
- 配置项较多且需复用配置类。
- 希望保持配置类的封装性,避免直接暴露静态变量。
方案对比与选择建议
方案 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
方案一(Setter绑定静态变量) | - 简单直接,无需额外代码。 - 利用Spring的自动绑定机制。 | - 可能破坏封装性。 - 静态变量需手动维护。 | 配置项少且需快速实现时。 |
方案二(Environment工具类) | - 灵活获取任意配置项。 - 支持类型安全。 | - 需硬编码配置键名。 | 需频繁访问不同配置项时。 |
方案三(ApplicationContext引用) | - 灵活访问所有配置属性。 - 兼容Spring生态。 | - 每次调用需获取Bean。 | 配置项多且需复用配置类时。 |
深度思考与注意事项
1. 静态变量的线程安全
- 只读场景:若静态变量仅在初始化时赋值(如方案一),则无需额外处理。
- 可变场景:若需动态修改配置,需加锁或使用
volatile
关键字:public class AppConfig {private static volatile String logotype; // 使用volatile保证可见性// ... }
2. 初始化顺序问题
- 确保容器初始化完成:在静态方法调用前,必须保证Spring应用已启动。
- 使用
@PostConstruct
:在配置类中添加初始化方法,确保静态变量已赋值:@PostConstruct public void init() {System.out.println("Config initialized: " + logotype); }
3. 配置刷新
- 动态刷新:若需热更新配置,可结合
@RefreshScope
或Spring Cloud Config:@Component @RefreshScope public class AppConfig {// 配置类实现动态刷新 }
- 静态变量的同步:配置刷新时需重新赋值静态变量。
最佳实践建议
-
优先选择方案三:
- 通过
ApplicationContext
获取Bean,既灵活又兼容Spring的配置管理。 - 示例代码:
public static String getLogotypeStatic() {return Application.context.getBean(AppConfig.class).getLogotype(); }
- 通过
-
方案二的适用场景:
- 需要频繁访问不同配置项时,通过
Environment
工具类可减少重复代码。
- 需要频繁访问不同配置项时,通过
-
慎用方案一:
- 仅在配置项极少且对代码简洁性要求较高时使用,避免破坏封装性。
总结
静态访问配置的解决方案本质是在Spring的依赖注入机制与静态变量的共享性之间找到平衡。
- 方案一:快速实现,但需注意静态变量的维护。
- 方案二:灵活但需硬编码键名。
- 方案三:灵活且兼容Spring生态,推荐作为首选。
相关文章:
Spring Boot 静态访问配置属性的解决方案
前言 在Spring Boot开发中,静态访问配置信息是一个常见需求,尤其是在工具类、常量类或非Bean类中直接获取配置值。 问题背景 假设我们的应用需要从application.yml中读取配置项app.logotype,并在工具类、静态方法或非Bean类中直接访问该值。…...
NLP高频面试题(四)——BN和LN的区别与联系,为什么attention要用LN
在深度学习模型中,Normalization是一种极为重要的技巧,Batch Normalization(BN)和Layer Normalization(LN)是其中最为常用的两种方法。然而,二者在实际应用中有着明显的区别与联系,尤…...
深度学习定义与分类【详细易懂 初学者友好~】
深度学习(Deep Learning)是机器学习的一个子领域,它基于人工神经网络(Artificial Neural Networks,ANN)的理论和架构,通过构建多层(即“深度”)的神经网络结构来学习数据…...
二、小白学JAVA-认识数据类型【变量】
1、实际案例类比 初中以上数学,就知道有有理数、正数、负数、0、小数、大写的数字、语文。 2、数据类型介绍 public class Main {public static void main(String[] args) {// 数据类型byte i_byte 12; // 标识数据范围小,但是节省内存>网络传输…...
UNI-APP uts插件 支持ANDROID 监听手机状态
插件地址 https://ext.dcloud.net.cn/plugin?id22646 模块 import {startPhoneListener,stopPhoneListener,checkIsAutoRecord,toCallAutoRecorderPage,navigateToCallRecordingSettings,jumpToPermissionPage,makePhoneCall,allRecorderFilesAction,registerSmsReceiver,} f…...
AI入门7:python三种API方式调用本地Ollama+DeepSeek
回顾 书接上篇:各种方式搭建了本地知识库: AI入门:AI模型管家婆ollama的安装和使用-CSDN博客 AI入门2:本地AI部署,用ollama部署deepseek(私有化部署)-CSDN博客 AI入门3:给本地d…...
SQL SERVER日常运维巡检系列—结构设计
前言 做好日常巡检是数据库管理和维护的重要步骤,而且需要对每次巡检日期、结果进行登记,同时可能需要出一份巡检报告。 本系列旨在解决一些常见的困扰: 不知道巡检哪些东西 不知道怎么样便捷体检 机器太多体检麻烦 生成报告…...
前端剪贴板操作:从传统方法到现代方案
一、传统复制实现原理 这个copy函数展示了经典的剪贴板操作方案: function copy(color) {const input document.createElement("input");input.value color;document.body.appendChild(input);input.select();document.execCommand("copy")…...
E1-数组的平衡点2(前缀和)
题目描述 给定一个长度为 n 的数组 nums,若其中存在某个位置 index,使得 [0, index - 1] 范围的元素之积 等于 [index 1, n - 1] 范围的元素之积,则称 index 位置是数组 nums 的平衡点。 请你找出数组 nums 的平衡点位置,若存在…...
【Maven-plugin】有多少官方插件?
之前疏理了容器底层原理,现在回归主题,在阅读 next-public时发现 parent 将从多基础插件集成到 parent 仓库中单独维护,数量众多,故在此将所有插件分类整理。以达观其全貌,心中有数。 以下是 Apache Maven 官方维护的核心插件列表…...
10-BST(二叉树)-建立二叉搜索树,并进行前中后遍历
题目 来源 3540. 二叉搜索树 - AcWing题库 思路 建立二叉搜索树(注意传参时用到了引用,可以直接对root进行修改),同时进行递归遍历;遍历可以分前中后三种写,也可以用标志来代替合在一起。其余详见代码。…...
企业培训APP如何迈向AI时代?智能化在线教育系统源码开发解析
2025年,AI驱动的企业培训系统将成为主流,企业可以借助智能化在线教育系统源码构建高效的培训体系,提高员工学习效率,优化培训成本。本文将详细解析AI如何赋能企业培训,并探讨智能化在线教育系统源码的关键技术与开发实…...
CXSMILES介绍
Chemaxon 扩展 SMILES/SMARTS 用于在 SMILES 字符串后存储分子的特殊特征。任何信息都可以存储在 SMILES 字符串后,只要它们由空格或制表符字符分隔,因为 SMILES 解析器会忽略这些信息,或者将它们作为注释使用。扩展特征以以下格式存储: SMILES_String |<feature1>,…...
麒麟服务器操作系统Sqlite部署手册
软件简介 SQLite****介绍 SQLite是一个进程内的轻量级嵌入式数据库,它的数据库就是一个文件,实现了自给自足、无服务器、零配置的、事务性的SQL数据库引擎。它是一个零配置的数据库,这就体现出来SQLite与其他数据库的最大的区别:SQLite不需要在系统中配置,直接可以使用。…...
【GPT-SoVITS】GPT-SoVITSAPI调用:让二次元角色开口说话,打造专属语音合成系统
介绍 GPT-SoVITS 是一个强大的语音合成系统,它结合了 GPT(生成式预训练转换器)和 SoVITS(Soft-VC VITS)两种先进技术: GPT: 负责文本理解和语音生成的控制,能够根据上下文生成自然的语音内容S…...
Deepseek API+Python测试用例一键生成与导出-V1.0.2【实现需求文档图片识别与用例生成自动化】
在测试工作中,需求文档中的图片(如界面设计图、流程图)往往是测试用例生成的重要参考。然而,手动提取图片并识别内容不仅耗时,还容易出错。本文将通过一个自研小工具,结合 PaddleOCR 和大模型,自…...
防火墙双机热备(主备分担)
目录 引言 主备备份实验 1、基本配置 2、双机热备配置 查看双机热备状态 主备切换 路由影响 引言 传统VRRP方式无法实现主、备用防火墙状态信息和多组VRRP状态的一致性,所以可能会导致流量的回包不从首包通过的防火墙回包,防火墙会因为状态检测机…...
记Redis集群挂掉后,尝试重启集群但失败问题
前期尝试解决:将redis集群中所有redis节点都关闭后,又重新启动服务并且试图用命令建立集群通讯,报错[ERR] Node 192.168.75.128:7001 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some…...
c++--vector
1.定义vector vector的定义分为四种 (1)vector() ——————无参构造 (2)vector(size_t n,const value_type& val value_type()) ——————构造并初始化n个val (3)vector(const vector& v1) ———————拷贝构造 (4)vector(inputiterator first,inpu…...
计算机视觉——深入理解卷积神经网络与使用卷积神经网络创建图像分类算法
引言 卷积神经网络(Convolutional Neural Networks,简称 CNNs)是一种深度学习架构,专门用于处理具有网格结构的数据,如图像、视频等。它们在计算机视觉领域取得了巨大成功,成为图像分类、目标检测、图像分…...
c++题目_翻译家
题目描述 grang是一个帅气的翻译家他的任务是把摩斯密码翻译成2进制数,他要上课所以想请你帮他一下,他会给你 一段摩斯密码有“.”和“-”组成让你输出个二进制数。 翻译规则是:不用管-,看每一个.有几个"."组成如果有奇…...
【解析 ECharts 图表样式继承与自定义】
解析 ECharts 图表样式继承与自定义 本文将详细介绍 ECharts 的样式继承机制,从其原理、演进到实际应用场景,并结合实际开发经验分享一些实战技巧,帮助开发者在构建数据可视化页面时实现更统一、灵活的样式管理与高效开发。 一、背景与来龙…...
Python IP解析器 ip2region使用
说明:最近需要在python项目内使用IP定位所在城市的需求,没有采用向外部ISP服务商API请求获取信息的方案,则翻了翻,在搞Java时很多的方案,在Python端反而可选择范围很小。 # 示例查询 ips ["106.38.188.214"…...
Java Stream 流的介绍
介绍 在 Java 8 中,引入了 Stream API,它为处理集合(如 List、Set 等)提供了一种更简洁、声明式的方式。Stream 流的设计目标是支持对数据集合的高效操作,尤其是能够进行链式操作、并行处理等,极大地提升了…...
C++从入门到入土(八)——多态的原理
目录 前言 多态的原理 动态绑定与静态绑定 虚函数表 小结 前言 在前面的文章中,我们介绍了C三大特性之一的多态,我们主要介绍了多态的构成条件,但是对于多态的原理我们探讨的是不够深入的,下面这这一篇文章,我们将…...
BFS,DFS带图详解+蓝桥杯算法题+经典例题
1.BFS和DFS的定义与实现方式 1.1 深度优先搜索(DFS) 基本概念:DFS 是一种用于遍历或搜索图或树的算法。它从起始节点开始,沿着一条路径尽可能深地探索下去,直到无法继续或者达到目标节点,然后回溯到上一个…...
【RHCE实验】搭建主从DNS、WEB等服务器
目录 需求 环境搭建 配置nfs服务器 配置web服务器 配置主从dns服务器 主dns服务器 从dns服务器 配置客户端 客户端测试 需求 客户端通过访问 www.nihao.com 后,能够通过 dns 域名解析,访问到 nginx 服务中由 nfs 共享的首页文件,内容…...
有哪些开源的智慧园区项目?
作为专注于数字孪生技术的开发者团队,我们一直在数字孪生圈分享开源项目。但最近一次与AI助手Deepseek的对话,却让我们“又惊又喜”。 ——当询问“有哪些开源的智慧园区项目”时,Deepseek的回答中竟包含了我们自己的开源项目! 这…...
prometheusalert对阿里云短信服务不适配问题处理
背景 想通过prometheusalert实现阿里云短信告警。结果在配置完altermanager和prometheusalert,以及阿里云短信服务中的各种签名和短信模板之后,在prometheusalert web ui上测试模板时一直报“模板变量JSON格式错误 或 JSON变量属性与模板占位符不一致”…...
NFC 碰一碰发视频源码搭建,支持OEM
一、引言 NFC(Near Field Communication)近场通信技术,以其便捷、快速的数据交互特性,正广泛应用于各个领域。其中,NFC 碰一碰发视频这一应用场景,为用户带来了新颖且高效的视频分享体验。想象一下&#x…...
浅谈鸿蒙跨平台开发框架ArkUI-X
之前写过使用uniapp的跨平台开发鸿蒙项目,今天分享一下开发体验更友好的跨平台开发框架ArkUI-X。 ArkUI-X看起来像是鸿蒙官方的框架,在DevEco中就可以安装和使用,而且会ArkUI就可以开发安卓和、iOS和鸿蒙三个平台的app,下面简单介…...
LLVM学习-- 构建和安装
一 LLVM版本 二 适用预构建的二进制文件安装LLVM 三 适用包管理器安装LLVM 四 从源码构建用于Linux的LLVM 五 从源码构建用于Windows和Visual Studio的LLVM 六 从源码构建用于MacOS 和XCode的LLVM 1.1 LLVM项目从10年前第一次发布到版本3.4,其SVN存储库包含了超过20…...
总结Solidity 的数据类型
数据类型 在 Solidity 中,类型系统非常丰富,主要分为 值类型(Value Types)和 引用类型(Reference Types)。此外,还有一些特殊类型和全局变量。 一.值类型 布尔型(bool)…...
C# 中泛型(Generics)的核心概念
在 C# 中,泛型(Generics) 是一种强大的编程特性,允许你编写可重用、类型安全的代码,而无需为不同类型重复编写相似的逻辑。泛型的核心思想是参数化类型,即通过占位符(如 T)表…...
ubuntu 根据src 包从新打包
下边以onnxruntime示例: 1. 安装必要的依赖 确保你的系统已安装 devscripts、dpkg-dev 和 build-essential: sudo apt update sudo apt install devscripts dpkg-dev build-essential equivs2. 解压源码 进入存放源码包的目录,并解压: #c…...
如何启用 HTTPS 并配置免费的 SSL 证书
引言 HTTPS 已成为现代网站安全性的基础要求。通过 SSL/TLS 证书对数据进行加密,不仅可以保护用户隐私,还能提升搜索引擎排名并增强用户信任。本指南将详细介绍如何通过 Lets Encrypt(免费、自动化的证书颁发机构)为您的网站启用…...
Python数据与变量、进制转换、输入输出函数、基本运算,基础语法编程练习
第一节 数据与变量 程序 数据 指令 1.1 内置基本数据类型 (1)数值型 整数(int):用于表示整数,注意一点Python中int数据可以存储任意大小整数,不会像其他语言(C\C Java࿰…...
联邦学习(Federated Learning)
1. 概念 联邦学习(Federated Learning, FL)是一种分布式机器学习技术,它允许多个参与方(如设备、机构或企业)在不共享原始数据的情况下协同训练机器学习模型。联邦学习通过本地计算模型参数聚合的方式,保护…...
AI大模型核心原理(二)
一、人工智能的兴起。 1、前序。 艾伦麦席森图灵; 是计算机科学之父。 著名英国数学家、计算机科学家、逻辑学家和密码分析学家,被誉为计算机科学与人工智能之父。 阿兰・图灵(Alan Turing) 是译名(简称)…...
数据结构篇——线索二叉树
一、引入 遍历二叉树是按一定规则将二叉树结点排成线性序列,得到先序、中序或后序序列,本质是对非线性结构线性化,使结点(除首尾)在线性序列中有唯一前驱和后继;但以二叉链表作存储结构时,只能获…...
【蓝桥杯】742合唱队形(DP LIS)
思路 借这题复习一下LIS,实际上是LIS的升级版,求一个\/形或者/\行,用两次最长上升子串即可。 先从前往后求递增,再从后往前求递减。 先把满足要求的最长队形求出来,总人数减去队形人数就是要出列的数目。 code impo…...
MySQL二进制日志格式有哪几种
目录 一、二进制日志格式类型1. **STATEMENT 格式(SBR: Statement-Based Replication)**2. **ROW 格式(RBR: Row-Based Replication)**3. **MIXED 格式(混合模式)**二、二进制日志事件详解三、如何选择二进制日志格式?四、配置与查看二进制日志格式五、注意事项在 MySQL…...
VUE管理后台开发-vue-element-admin
# 克隆项目 git clone https://github.com/PanJiaChen/vue-element-admin.git # 进入项目目录 cd vue-element-admin # 安装依赖 npm install # 速度过慢可以使用下面方法进行指定下载镜像原 # 也可以使用nrm选择下载镜像原 # 建议不要用 cnpm 安装 会有各种诡异的bug 可以通…...
计算机网络原理
网络发展史 起初,计算机之间是相互独立的,分别完成不同的工作,效率较为低下.随着时代的发展,计算机开始协同完成任务,就有了网络互连.网络互连是指将多台计算机连接在一起,完成数据共享.根据网络互联的规模不同,可以划分为局域网和广域网.局域网,简称LAN.局域网内的主机可以互相…...
速盾:如何利用CDN静态加速匹配尾缀提升网站性能?
在当前数字化时代,网站性能对于用户体验至关重要。尤其是对于包含大量静态资源(如图片、CSS、JavaScript文件等)的网站来说,如何高效地管理和加速这些资源成为了一个重要课题。本文将介绍如何利用CDN静态加速匹配尾缀的方法来提升…...
【H2O2 | 软件开发】前端深拷贝的实现
目录 前言 开篇语 准备工作 正文 概述 JSON方法 递归 其他 结束语 前言 开篇语 本系列为短篇,每次讲述少量知识点,无需一次性灌输太多的新知识点。该主题文章主要是围绕前端、全栈开发相关面试常见问题撰写的,希望对诸位有所帮助。…...
C#语法基础总结
输入和输出 输入 Console.Read(); 从屏幕读取一个字符,并返回该字符所对应的整型数字 Console.ReadLine(); 从屏幕读取一串字符,并返回该字符串 输出 Console.WriteLine(); 输出内容,并换行 Console.Write(); 输出内容,不换行…...
《深度学习》—— 模型部署
文章目录 模型部署模型准备选择部署平台部署配置与服务化测试与验证优化与维护常用工具与框架Flask本地部署模型 模型部署 模型部署是将训练好的机器学习或深度学习模型投入实际生产环境,使其能够处理实时数据并提供预测或推理服务的过程。 模型准备 模型格式转换…...
E902基于bash与VCS的仿真环境建立
网上看见很多E902仿真的文章,但用到的编译器是类似于这种Xuantie-900-gcc-elf-newlib-x86_64-V3.0.1-20241120,而我按照相应的步骤与对应的编译器,仿真总会报错。后面将编译器换成riscv64-elf-x86_64-20210512,反而成功了。现在开…...
挖矿------获取以太坊测试币
文章目录 挖矿------获取以太坊测试币通过水龙头获取以太坊测试币了解Sepolia是什么?水龙头(Faucet)是什么?Gitcoin Passport是什么? 操作1.MetaMask钱包2.将MetaMask切换到Sepolia测试网络3.用MetaMask连接Gitcoin Pa…...