@Value 读取环境变量配置

在项目开发过程中,有必要使用一些灰色规则(即仅用于开发使用过程中的逻辑控制变量)。
比如,本地开发中,一些业务逻辑需要调用第三方代码,但又在本地调不通,怎么办。只能通过 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,那么以上代码则会生效。
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

手拉手springboot整合kafka发送消息

环境介绍技术栈springbootmybatis-plusmysqlrocketmq软件版本mysql8IDEAIntelliJ IDEA 2022.2.1JDK17Spring Boot3.1.7kafka2.13-3.7.0 创建topic时,若不指定topic的分区(Partition主题分区数)数量使,则默认为1个分区(partition) springboot加入依赖kafk…

HTML静态网页成品作业(HTML+CSS)——企业装饰公司介绍网页(4个页面)

🎉不定期分享源码,关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 🏷️本套采用HTMLCSS,未使用Javacsript代码,共有4个页面。 二、作品演示 三、代…

热电子光探测器的电磁场空间分布与FDTD材料折射率的导出

仿真实例 金属薄膜中金纳米孔阵列透射与反射, 并考虑其近场电磁分布 利用脚本进行电磁场及其光学响应的可视化 设置EOT型超表面结构,以及Structure library的使用 结构的参数化扫描与结果可视化 利用脚本计算峰值增强因子 多层平面结构激发T…

Spark 核心编程之 RDD 介绍

一、Spark 分布式计算模拟 Driver 端将数据拆分成 n 个 Task 发送给 Executor,n 为 Executor 个数,Task 包含数据和计算逻辑,Executor 接收到 Task 后进行计算并将计算后的结果返回给 Driver 定义封装整体数据和逻辑的资源类 class Resource …

高性能服务器网络模型详解

1999年Dan Kegel在发表的论文中提出了The C10K problem,这篇论文对传统服务器架构处理大规模并发连接时的挑战进行了详细描述,并提出了一些解决方案和优化技术。这里的C指的是Concurrent(并发)的缩写,C10K问题是指怎么在单台服务器上并发一万…

buidldroot musl uclib库 编译

buildroot 修改 编译工具链 原本编译器相关信息: Incorrect selection of the C library buidroot编译 注意相关选项,后续使用CUSTOM TOOLCHAIN 时对应 UCLIB 能将生成IMAGE 从2.9K变为2.3K MUSL 能将生成IMAGE 从2.9K变为2.7K 变大了 arm-linux-…

【运维项目经历|025】企业高效邮件系统部署与运维项目

目录 项目名称 项目背景 项目目标 项目成果 我的角色与职责 我主要完成的工作内容 本次项目涉及的技术 本次项目遇到的问题与解决方法 本次项目中可能被面试官问到的问题 问题1:项目周期为多长时间? 问题2:服务器部署架构方式及数量…

ubuntu 18.04 ros1学习

总结了一下,学习内容主要有: 1.ubuntu的基础命令 pwd: 获得当前路径 cd: 进入或者退出一个目录 ls:列举该文件夹下的所有文件名称 mv 移动一个文件到另一个目录中 cp 拷贝一个文件到另一个目录中 rm -r 删除文件 gedit sudo 给予管理员权限 sudo apt-…

uniapp实现图片上传——支持APP、微信小程序

uniapp实现图片、视频上传 文章目录 uniapp实现图片、视频上传效果图组件templatejs 使用 相关文档: 结合 uView 插件 uni.uploadFile 实现 u-upload uploadfile 效果图 组件 简单封装,还有很多属性…,自定义样式等…根据个人所需调整 te…

DNF手游攻略:勇士进阶指南!

在即将到来的6月5日,《DNF手游》将迎来一场盛大的更新,此次更新带来了大量新内容和玩法,极大丰富了游戏的体验。本文将为广大玩家详细解析此次更新的亮点,包括新增的组队挑战玩法“罗特斯入门团本”、新星使宠物的推出、宠物进化功…

ADB日常使用命令

【ADB全称 Android Debug Bridge】 是Android SDK中的一个命令行工具adb命令可以直接操作管理Android模拟器或真实的Android设备(手机) 建立PC和模拟器连接 # 建立连接 adb connect 127.0.1: 模拟器端口号〈逍遥模拟器21503〉 # 验证是否连接成功 adb d…

NFS p.1 服务器的部署以及客户端与服务端的远程挂载

目录 介绍 应用 NFS的工作原理 NFS的使用 步骤 1、两台机子 2、安装 3、配置文件 4、实验 服务端 准备 启动服务: 客户端 准备 步骤 介绍 NFS(Network File System,网络文件系统)是一种古老的用于在UNIX/Linux主…

使用 Apache Commons Exec 管理外部进程

😄 19年之后由于某些原因断更了三年,23年重新扬帆起航,推出更多优质博文,希望大家多多支持~ 🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志 🎐 个人CSND主页——Mi…

基于 Apache Doris 的实时/离线一体化架构,赋能中国联通 5G 全连接工厂解决方案

作者:田向阳,联通西部创新研究院 大数据专家 共创:SelectDB 技术团队 导读: 数据是 5G 全连接工厂的核心要素,为支持全方位的数据收集、存储、分析等工作的高效进行,联通 5G 全连接工厂从典型的 Lambda 架…

使用PNP管控制MCU是否需要复位

这两台用到一款芯片带电池,希望电池还有电芯片在工作的时候插入电源不要给芯片复位,当电池没电,芯片不在工作的时候,插入电源给芯片复位所以使用一个PNP三极管,通过芯片IO控制是否打开复位,当芯片正常工作的…

在长窗口时代,RAG技术是否仍然必要?

自从谷歌推出 Gemini 1.5 Pro,行业内部对于 RAG 的讨论就不绝于耳。 Gemini 1.5 Pro 的性能确实令人瞩目。根据谷歌公布的技术文档,该系统能够稳定处理长达 100 token 的内容,相当于一小时的视频、十一小时的音频、超过三万行的代码或七十万…

Spring Cloud Alibaba-09-Seata分布式事务

Lison <dreamlison163.com>, v1.0.0, 2024.5.03 Spring Cloud Alibaba-09-Seata分布式事务 文章目录 Spring Cloud Alibaba-09-Seata分布式事务分布式事务基础事务本地事务分布式事务分布式事务的场景 分布式事务的解决方案全局事务可靠消息服务最大努力通知TCC事务 Se…

Java实现数据结构---数组

文章目录 概念存储原理数组的操作完整代码 概念 数组是&#xff08;Array&#xff09;是有限个相同类型的变量所组成的有序集合&#xff0c;数组中的每一个变量为称为元素。数组是最简单、最常用的数据结构。 数组下标从零开始。 存储原理 数组用一组连续的内存空间来存储一…

蓝桥杯第17135题 不完整的算式 C++ Java Python

目录 题目 思路和解题方法 步骤 1&#xff1a;识别缺失的部分 步骤 2&#xff1a;根据已知条件计算或推断 步骤 3&#xff1a;处理特殊情况和验证 c 代码 Java 版本 Python 版本&#xff08;仅供参考&#xff09; 代码和解题细节&#xff1a; 题目 题目链接&#xff…

STM32自己从零开始实操03:输出部分原理图

一、继电器电路 1.1指路 延续使用 JZC-33F-012-ZS3 继电器&#xff0c;设计出以小电流撬动大电流的继电器电路。 &#xff08;提示&#xff09;电路需要包含&#xff1a;三极管开关电路、续流二极管、滤波电容、指示灯、输出部分。 1.2数据手册重要信息提炼 联系排列&…