@Value 读取环境变量配置

news2024/12/26 17:45:18

在项目开发过程中,有必要使用一些灰色规则(即仅用于开发使用过程中的逻辑控制变量)。
比如,本地开发中,一些业务逻辑需要调用第三方代码,但又在本地调不通,怎么办。只能通过 if(本地开发) {mock数据或直接不调用} else {实际三方接口调用}。
这种方式可以使用@Value注解读取环境变量的方式来实现。

@Value属于spring的注解,在spring-beans包下,可以在 字段 或 方法参数 或 构造函数参数 上使用,通常用于属性注入。支持SpEL (Spring Expression Language)表达式来注入值,同时也支持属性占位符注入值。

使用@Value前提:
不能直接作用于静态变量(static);
不能直接作用于常量(final);
不能在非注册的类中使用(类需要被注册在spring上下文中,如用@Service,@RestController,@Component等);
使用这个类时,只能通过依赖注入的方式,用new的方式是不会自动注入这些配置的

@Value("${spring.application.name:somnus}") 代表的是假如application当中读不到值,那么就使用somnus。这样可以完全避免没有设置值而启动报错的问题。当然也可以不设置默认值,比如@Value("${spring.application.name:}") 这样同样可以避免没有设置值启动报错的问题!

使用@Value(“${环境变量名}”)就可以直接读取到操作系统的环境变量,就算在properties或者yaml中指定同名属性值也会被系统环境变量值所覆盖,所以在平常自定义属性时避免与系统环境变量重名,最好加上前缀。

笔者定义了这个字段注解

@Value("${test.ptVerify:}")
private String pressureTestVerify;

但是又不想在 application.yaml中定义,想直接通过 环境变量注入。
这里的问题在于,这里的ptVerify是 驼峰命名[破涕为笑],又有点号

在k8s的configMap里,先定义了
test.ptVerify,发现不行(在控制台也查不到这个环境变量,应该是 环境变量里不允许有 点)
test_ptVerify 不行,spring不识别
test_pt_verify 不行

最后可以工作的为
TEST_PTVERIFY
即全大写形式

SpringBoot的解释如下:

Binding From Environment Variables
Most operating systems impose strict rules around the names that can be used for environment variables. For example, Linux shell variables can contain only letters (a to z or A to Z), numbers (0 to 9) or the underscore character (_). By convention, Unix shell variables will also have their names in UPPERCASE.

Spring Boot’s relaxed binding rules are, as much as possible, designed to be compatible with these naming restrictions.

To convert a property name in the canonical-form to an environment variable name you can follow these rules:

Replace dots (.) with underscores (_).

Remove any dashes (-).

Convert to uppercase.

For example, the configuration property spring.main.log-startup-info would be an environment variable named SPRING_MAIN_LOGSTARTUPINFO.

debug了下 代码,相应的处理逻辑在类SystemEnvironmentPropertySource

	protected final String resolvePropertyName(String name) {
		Assert.notNull(name, "Property name must not be null");
		String resolvedName = checkPropertyName(name);
		if (resolvedName != null) {
			return resolvedName;
		}
		String uppercasedName = name.toUpperCase();
		if (!name.equals(uppercasedName)) {
			resolvedName = checkPropertyName(uppercasedName);
			if (resolvedName != null) {
				return resolvedName;
			}
		}
		return name;
	}

	@Nullable
	private String checkPropertyName(String name) {
		// Check name as-is
		if (this.source.containsKey(name)) {
			return name;
		}
		// Check name with just dots replaced
		String noDotName = name.replace('.', '_');
		if (!name.equals(noDotName) && this.source.containsKey(noDotName)) {
			return noDotName;
		}
		// Check name with just hyphens replaced
		String noHyphenName = name.replace('-', '_');
		if (!name.equals(noHyphenName) && this.source.containsKey(noHyphenName)) {
			return noHyphenName;
		}
		// Check name with dots and hyphens replaced
		String noDotNoHyphenName = noDotName.replace('-', '_');
		if (!noDotName.equals(noDotNoHyphenName) && this.source.containsKey(noDotNoHyphenName)) {
			return noDotNoHyphenName;
		}
		// Give up
		return null;
	}

组件类,@Value必须在SpringBoot的组件中使用

@Component
public class ProfileValueInit {

    @Value("${spring.profiles.active:}")
    private String profile;

    @Value("${test.verify:}")
    private String verifyTest;

    @Value("${test.ptVerify:}")
    private String pressureTestVerify;

    @PostConstruct
    public void init() {
        if (profile != null && profile.contains("local")) {
            ProfileUtils.MOCK_VALUE = true;
        }

        if ("true".equals(verifyTest)) {
            ProfileUtils.TEST_VERIFY = true;
        }

        if ("true".equals(pressureTestVerify)) {
            ProfileUtils.PRESSURE_TEST_VERIFY = true;
        }
    }
}

方法类

public class ProfileUtils {

    public static boolean MOCK_VALUE;

    public static boolean TEST_VERIFY;

    public static boolean PRESSURE_TEST_VERIFY;

    public static boolean isMockEnv() {
        return MOCK_VALUE;
    }

    public static boolean isTestVerify() {
        return TEST_VERIFY;
    }

    public static boolean isPressureTestVerify() {
        return PRESSURE_TEST_VERIFY;
    }
}

业务类

// 压测模拟
boolean pt = ProfileUtils.isPressureTestVerify();
if (pt) {
   //做模拟逻辑处理
}

使用set | grep PT查看环境变量,发现有环境变量TEST_PTVERIFY=true,那么以上代码则会生效。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1718514.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Facebook的创新实验室:人工智能与新技术探索

Facebook作为全球领先的社交媒体平台之一,一直在不断探索和应用最新的技术来改善用户体验、推动创新和拓展业务边界。其创新实验室更是探索人工智能(AI)和新技术的前沿,为未来的社交媒体发展开辟了新的可能性。本文将深入探讨Face…

《广告数据定量分析》第3版读书笔记之统计原理

1.点估计与区间估计:可用于求指标误差区间;(不常用) (1)总体比例的置信区间: 通过样本数据计算的比例,估计总体的对应比例的取值范围。主要适用于用户转化漏斗各环节的转化率估计,比如点击率、点击下载率、下载安装率、安装激活率等。 我们可以得到总体百分比的一个…

iOS组件化 方案 实现

iOS组件化 组件化的原因现在流行的组件化方案方案一、url-block (基于 URL Router)方案二、protocol调用方式解读 方案三、target-action调用方式解读 gitHub代码链接参考 组件化的原因 模块间解耦模块重用提高团队协作开发效率单元测试 当项目App处于…

例子:Triton + TensorRT-LLM

Deploy an AI Coding Assistant with NVIDIA TensorRT-LLM and NVIDIA Triton | NVIDIA Technical Blog https://github.com/triton-inference-server/tutorials/blob/main/Conceptual_Guide/Part_1-model_deployment/README.md 1. 想用onnx-runtime来做推理backend&#xff1…

React + Taro 项目 实际书写 感受

之前我总结了部分react 基础 根据官网的内容 以及Taro 框架的内容 今天我试着开始写了一下页面和开发 说一下我的感受 我之前写的是vue3 今天是第一次真正根据需求做页面开发 和逻辑功能 代码的书写 主体就是开发了这个页面 虽说这个页面 很简单 但是如果你要是第一次写 难说…

Facebook的算法揭秘:如何塑造我们的信息

在当今数字化时代,Facebook已经成为人们日常生活中不可或缺的一部分。其信息流算法不仅决定着我们在平台上看到的内容,还对我们的观点、行为和体验产生了深远的影响。本文将深入探讨Facebook的算法运作方式,以及它对我们信息获取和社交行为的…

神器!!Python热重载调试【送源码】

在 Python 开发的路上,调试是我们不可避免的一环。 而今天推荐的开源项目Reloadium ,让你在不重启程序的情况下实现代码的即时更新和调试。 🔄 Reloadium 功能亮点: 1. 热重载魔法: Reloadium 不仅仅能够实现代码的…

Android高通 12/13 录屏流程代码位置

需求如下图 实现系统录屏功能 frameworks/base/packages/SystemUI/src/com/android/systemui/screenrecord 涉及代码 ScreenRecordDialog # startBtn RecordingService # startRecording# stopRecording ScreenMediaRecorder # start # end #save 1、点击开始录屏framewo…

停车场车位引导系统方案升级实施步骤流程是什么,有什么注意事项

停车场车位引导系统是一种现代化的停车管理系统,它通过实时监测车位占用情况,并向驾驶员提供准确的空闲车位导航信息,从而提高停车场的使用效率和用户体验。随着城市交通的快速发展和车辆数量的不断增加,停车场车位引导系统已成为…

【数据分享】中国科技统计年鉴Excel版(1991-2023年)

大家好!今天我要向大家介绍一份重要的中国科技统计数据资源——《中国科技统计年鉴》。这份年鉴涵盖了从1991年到2023年中国科技统计全面数据,并提供限时免费下载。 数据介绍 在数字化时代的浪潮中,数据的重要性日益凸显。对于研究人员、政…

AutoSQT 2024汽车软件质量与测试峰会开启注册 | 智能汽车软件如何卷出差异化?

在汽车行业向智能化、网联化转型的大趋势下,软件在汽车系统中扮演着越来越核心的角色。基于“软件定义汽车”的行业共识,各主机厂正在不断押注软件开发,以实现品牌差异化竞争。 例如,大众集团正在开发下一代汽车操作系统和应用软…

Spring MVC 应⽤分层

什么是应用分层 引用分层是一种软件开发思想 将应用程序分为N个层次每个层次负责各个职责 其中MVC是常见的设计模式这就是应用分层的具体体现 目前主流的开发方式是前后段分离后端开发工程师不再需要关注前端的实现,对此就需要分为表现层,数据层,业务逻…

LM2733升压芯片

具有 40V 内部 FET 开关且采用 SOT-23 封装的 LM2733 0.6MHz 和 1.6MHz 升压转换器 外观 参考价格 1 特性 电路原理图 基于LM2733升压电路设计-CSDN博客https://blog.csdn.net/qq_31251431/article/details/107479885 特此记录 anlog 2024年5月31日 高压方案 此方案经过更多…

数据结构 | 二叉树(基本概念、性质、遍历、C代码实现)

1.树的基本概念 树是一种 非线性 的数据结构,它是由n(n>0)个有限结点组成一个具有层次关系的集合。 把它叫做树是因 为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。 有一个特殊的结点,称为根…

ChatGPT的逆袭历程:核心技术深度解析

在ChatGPT问世之前,已有许多大模型存在,但为何只有它成为了AI时代的“iPhone时刻”?这不仅得益于其技术优势,还在于其发展过程中所采用的一系列创新策略。本文将深度复盘ChatGPT的逆袭历程,分析其核心技术,…

GIS毕业薪资从2K到20K究竟要多久?

同大多数行业一样,GIS毕业生薪资跟行业有密切关系。 测绘地理信息行业紧跟时代步伐,随着测绘地理信息技术的变革和进步,测绘产品也逐渐升级发展。 经过三个阶段的发展,测绘地理信息产品初步实现从抽象到真实、从平面到立体、从静…

npm run dev 同时运行vue前端项目和node后端项目

将两个项目放到一个目录下 项目拖进vscode中,安装包依赖,修改配置 npm i concurrently "dev": "concurrently \"vite --mode development\" \"nodemon app.js\"" 命令行 npm run dev 运行 没有运行成功排查 …

window11 设置 ubuntu2204 至最佳体验(安装/右键菜单/root用户/docker)

前言 在 window 中如果不使用 ubuntu 命令行会非常不方便,还好微软提供了 ubuntu 的终端,下载安装后简单设置下就可以愉快的使用了。 本文会涉及的方面 安装右键菜单设置root 用户设置docker 设置 安装 ubuntu 到微软的软件商店中下载安装即可&…

探索python数据可视化的奥秘:打造专业绘图环境

新书上架~👇全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我👆,收藏下次不迷路┗|`O′|┛ 嗷~~ 目录 一、搭建专业绘图环境 二、掌握绘图基本原理 三、解锁绘图高级技巧 四、总结与展望 在数据…

taskENTER_CRITICAL()分析

1. 临界段代码 //任务级的临界段代码保护 taskENTER_CRITICAL() taskEXIT_CRITICAL()//中断级的临界段代码保护 taskENTER_CRITICAL_FROM_ISR() taskEXIT_CRITICAL_FROM_ISR()2. 以STM32为例 (1)STM32有0~15,共16级中断,可嵌套…