[Java SE] 彻底搞懂Java程序的三大参数配置途径:系统变量与JVM参数(VM Option)/环境变量/启动程序参数args

这篇具有很好参考价值的文章主要介绍了[Java SE] 彻底搞懂Java程序的三大参数配置途径:系统变量与JVM参数(VM Option)/环境变量/启动程序参数args。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

0 序言

一次没搞懂,处处受影响。这个问题属于基础问题,但又经常踩坑,不得不重视一下了。

1 Java程序动态参数的配置途径:系统变量与JVM参数(VM Option) vs 环境变量 vs 启动程序参数args

[Java SE] 彻底搞懂Java程序的三大参数配置途径:系统变量与JVM参数(VM Option)/环境变量/启动程序参数args

IDEA中的配置位置文章来源地址https://www.toymoban.com/news/detail-476910.html

参数 使用方式 示例 代码获取方式
系统属性 由操作系统、JVM、应用程序主动设置 System.setProperties(Properties propes) / System.setProperties(String key,String value) / System.getProperties().load(String filename) / ... String value = System.getProperty(propertyName);
VM Options(JVM参数) 优先级高于系统变量。必须以-D-X-XX 开头,每个参数用空格隔开 -Dvm.key=VmKey -Dvm.key2=VmKey2 String key = System.getProperty(vm.key);
Program Arguments(程序启动参数) 每个参数用空格隔开 p.key=Program_Key p.name=ProgramName p.age=18 main(String[] args)
Environment Variable(环境变量) 我的电脑-属性-高级环境设置-环境变量内配置系统属性。其优先级低于 VM options ,即如果VM options 有一个变量和 Environment variable中的变量的key相同,则以VM options 中为准, 以分号分割多个 env.key=env_james;server.servlet.context-path=/test;server.port=8080 String envKey = System.getenv(“env.key”);

2 工具类:SystemVariableTool

import cn.xx.bd.xx.common.debug.Print;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.DefaultApplicationArguments;
import org.springframework.util.ObjectUtils;

import java.util.*;

/**
 * @author johnny-zen
 * @version v1.0
 * @create-time 2023/6/9 9:57
 * @description 系统属性读取工具
 *  [VM options]
 *      VM options其实就是我们在程序中需要的运行时环境变量,它需要以-D或-X或-XX开头,每个参数使用空格分隔
 *      使用最多的就是-Dkey=value设定系统属性值,比如-Dspring.profiles.active=dev3
 *  [Program arguments]
 *      Program arguments为我们传入main方法的字符串数组args[],它通常以--开头,如--spring.profiles.active=dev3
 *      等价于-Dspring.profiles.active=dev3如果同时存在,以Program arguments配置优先
 * @refrence-doc
 * @gpt-promt
 */
public class SystemVariableTool {
    private final static Logger logger = LoggerFactory.getLogger(SystemVariableTool.class);

    public static final String SYSTEM_PROPERTY_PARAM = "SYSTEM_PROPERTY";

    public static final String ENVIRONMENT_VARIABLE_PARAM = "ENVIRONMENT_VARIABLE";

    /** args **/
    public static final String ARGS_PARAM = "ARGS_PARAM";
    // 可选参数
    public static final String OPTION_ARG_PARAM = "OPTION_ARG_VARIABLE";
    // 非可选参数
    public static final String NON_OPTION_ARG_PARAM = "NON_OPTION_ARG_PARAM";

    private ApplicationArguments applicationArguments;

    public SystemVariableTool(ApplicationArguments applicationArguments){
        this.applicationArguments = applicationArguments;
    }

    /**
     * 读取系统属性
     * @param propertyName
     * @config-method 配置方法
     *  1 ) IDEA - (Select one Program) - Edit Configurations - VM Options - ( "-Dserver.port=8088" / "-Xmx239m" )
     * @sample
     * server.port
     * -----------------------------
     * java.version Java 运行时环境版本
     * java.vendor Java 运行时环境供应商
     * java.vendor.url Java 供应商的 URL
     * java.home Java 安装目录
     * java.vm.specification.version Java 虚拟机规范版本
     * java.vm.specification.vendor Java 虚拟机规范供应商
     * java.vm.specification.name Java 虚拟机规范名称
     * java.vm.version Java 虚拟机实现版本
     * java.vm.vendor Java 虚拟机实现供应商
     * java.vm.name Java 虚拟机实现名称
     * java.specification.version Java 运行时环境规范版本
     * java.specification.vendor Java 运行时环境规范供应商
     * java.specification.name Java 运行时环境规范名称
     * java.class.version Java 类格式版本号
     * java.class.path Java 类路径
     * java.library.path 加载库时搜索的路径列表
     * java.io.tmpdir 默认的临时文件路径
     * java.compiler 要使用的 JIT 编译器的名称
     * java.ext.dirs 一个或多个扩展目录的路径
     * os.name 操作系统的名称
     * os.arch 操作系统的架构 例如: "amd64"
     * os.version 操作系统的版本 例如: "10.0"
     * file.separator 文件分隔符(在 UNIX 系统中是"/")
     * path.separator 路径分隔符(在 UNIX 系统中是":")
     * line.separator 行分隔符(在 UNIX 系统中是"/n")
     * user.country 用户所在国家
     * user.name 用户的账户名称
     * user.home 用户的主目录 例如: "C:\Users\Johnny"
     * user.dir 用户的当前工作目录 例如: "E:\source_code\BigData\bdp_common_data_service"
     * user.language 用户当前的语言 例如: "zh"
     * user.timezone 用户所在时区 例如: "Asia/Shanghai"
     * @return
     */
    public static String getSystemProperty(String propertyName){
        Map enviromentProperties = System.getProperties();
        return (String) enviromentProperties.get(propertyName);
    }

    /**
     * 读取环境变量
     * @config-method 配置方式 :
     *  优先级 : 方式1 < 方式2
     *  1) My Computer - 属性 - 高级系统设置 - 环境变量 - ...
     *  2) IDEA - (Select one Program) - Edit Configurations - Environment Variables - ( ENV_VAR="env-var-demo" server.port=8090 ...)
     *
     * @sample
     * USERPROFILE        :用户目录
     * USERDNSDOMAIN      :用户域
     * PATHEXT            :可执行后缀
     * JAVA_HOME          :Java安装目录
     * TEMP               :用户临时文件目录
     * SystemDrive        :系统盘符
     * ProgramFiles       :默认程序目录
     * USERDOMAIN         :帐户的域的名称
     * ALLUSERSPROFILE    :用户公共目录
     * SESSIONNAME        :Session名称
     * TMP                :临时目录
     * Path               :path环境变量
     * CLASSPATH          :classpath环境变量
     * PROCESSOR_ARCHITECTURE :处理器体系结构
     * OS                     :操作系统类型
     * PROCESSOR_LEVEL    :处理级别
     * COMPUTERNAME       :计算机名
     * Windir             :系统安装目录
     * SystemRoot         :系统启动目录
     * USERNAME           :用户名
     * ComSpec            :命令行解释器可执行程序的准确路径
     * APPDATA            :应用程序数据目录
     * @return
     */
    public static String getEnvironmentVariable(String variableName){
        Map enviromentProperties = System.getenv();
        return (String) enviromentProperties.get(variableName);
    }

    public Map<String, Object> getVariables(String variableName){
        Map<String, Object> resultMap = new HashMap<>();
        String systemProperty = getSystemProperty(variableName);
        resultMap.put(SYSTEM_PROPERTY_PARAM, systemProperty);

        String environmentVariable = getEnvironmentVariable(variableName);
        resultMap.put(ENVIRONMENT_VARIABLE_PARAM, environmentVariable);

        //解析 args
        String argsValue = null;
        String[] args = applicationArguments.getSourceArgs();
        if(!ObjectUtils.isEmpty(args)){
            for(int i = 0; i < args.length; i++){
                if(args[i].toLowerCase().contains(variableName.toLowerCase())){
                    argsValue = args[i];
                }
            }
        }
        resultMap.put(ARGS_PARAM, argsValue);
        /**
         * 解析选项参数
         * @description
         *  1. 不同框架 对 args 的解析策略均不同。例如 Flink 的 ParameterTool 与 SpringBoot 的 DefaultApplicationArguments,解析规则和解析结果有很大差异
         *  1. 基于 SpringBoot 的 ApplicationArguments 接口, DefaultApplicationArguments 。 如果是以”--“为前缀,则判定为选项参数;反之,被判定为 非选项参数
         * @sample
         * [1] 选项参数的有效示例
         *  --foo
         *  --foo=
         *  --foo=""
         *  --foo=bar
         *  --foo="bar then baz"
         *  --foo=bar,baz,biz
         * [2] 选项参数的无效示例
         *  -foo
         *  --foo bar
         *  --foo = bar
         *  --foo=bar --foo=baz --foo=biz
         */
        List<String> optionArgs = applicationArguments.getOptionValues(variableName);// args = { "--foo="bar then baz" } , variableName = "foo" => optionArgs = {"bar then baz"}
        resultMap.put(OPTION_ARG_PARAM, optionArgs);

        List<String> allNonOptionArgs = applicationArguments.getNonOptionArgs();// { "server.port=8089" , "server.port=8090", "boo=bar,then,baz" , "foo=bar then baz" }
        List<String> nonOptionArgs = new ArrayList<>();
        for(int i=0;i<allNonOptionArgs.size();i++){
            if(allNonOptionArgs.get(i).toLowerCase().contains(variableName.toLowerCase())){
                nonOptionArgs.add( allNonOptionArgs.get(i) );
            }
        }
        resultMap.put(NON_OPTION_ARG_PARAM, nonOptionArgs);
        return resultMap;
    }

    public static void main(String[] args) {
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        SystemVariableTool systemPropertiesUtil = new SystemVariableTool(applicationArguments);
        Map<String, Object> map = systemPropertiesUtil.getVariables("server.port");
        Print.print(map);
    }
}

X 参考文献

  • Java中System.getProperty()的作用及使用 - CSDN
  • Idea中的VM Options、Program Arguments、Environment Variable全解析 - CSDN
  • java 获取系统变量(环境变量和设置变量) - CSDN
  • idea为java程序添加启动参数(program arguments,vm arguments,Environment variable),并在程序中获取使用 - CSDN
  • 【Flink】关于ParameterTool - CSDN
  • 如何使用 Flink ParameterTool 读取配置 - CSDN

到了这里,关于[Java SE] 彻底搞懂Java程序的三大参数配置途径:系统变量与JVM参数(VM Option)/环境变量/启动程序参数args的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Day1】零基础学java--》记事本运行java程序,通熟语言让你彻底明白为什么配置java环境变量

    前言: 大家好,我是 良辰丫 ,从今天开始我将协同大家一起从零基础学习Java,期待与君为伴,走向海的彼岸。💕💕💕 🧑个人主页:良辰针不戳 📖所属专栏:EveryDay零基础学java 🍎励志语句:生活也许会让我们遍体鳞伤,但最终这些伤口会成为我们一辈子的财富。 💦期

    2024年02月11日
    浏览(29)
  • 【Java SE语法篇】4.程序逻辑控制

    📚博客主页:爱敲代码的小杨. ✨专栏:《Java SE语法》 ❤️感谢大家点赞👍🏻收藏⭐评论✍🏻,您的三连就是我持续更新的动力❤️ 顺序结构 比较简单,按照代码书写的顺序一行一行执行。 如果调整代码的书写顺序, 则执行顺序也发生变化。 它的作用是根据判断的条件

    2024年02月01日
    浏览(25)
  • 一文彻底搞懂JSON数据

    什么是JSON,为什么需要JSON,JSON的3种形式,JSON常用的方法等 TIP JSON指的是全称是:javascript对象表示法 JSON是Ajax发送和接收数据的一种格式 JSON是一种轻量级的数据交互格式, 其为字符串类型 (面试题会考到) JSON是一种语法,用来序列化对象、数组、数值、字符串、布尔值和

    2024年02月06日
    浏览(34)
  • 【算法】一文彻底搞懂ZAB算法

    最近需要设计一个分布式系统,需要一个中间件来存储共享的信息,来保证多个系统之间的数据一致性,调研了两个主流框架Zookeeper和ETCD,发现都能满足我们的系统需求。 其中ETCD是K8s中采用的分布式存储,而其底层采用了RAFT算法来保证一致性,之前已经详细分析了Raft算法

    2024年02月02日
    浏览(44)
  • 【多图警告】彻底搞懂浮点数

    float类型,在很多地方没有看明白,多文字也看得人心烦。 最近不是很愿意看多文字的博客和技术文章了,但确实不是什么好事。 要改。 本文用大量图片讲解了浮点数在计算机中的存储方式以及浮点数的最值、精度等问题,文末有测试用的C++程序。 我们先不让小数点“浮动

    2024年02月15日
    浏览(33)
  • 20,000+ 字,彻底搞懂 Kafka!

    1、解耦合 2、异步处理 例如电商平台,秒杀活动。 一般流程会分为: 风险控制 库存锁定 生成订单 短信通知 更新数据 通过消息系统将秒杀活动业务拆分开,将不急需处理的业务放在后面慢慢处理; 流程改为: 风险控制 库存锁定 消息系统 生成订单 短信通知 更新数据 3、

    2024年02月11日
    浏览(21)
  • 2分钟彻底搞懂“高内聚,低耦合”

    💗推荐阅读文章💗 🌸 JavaSE系列 🌸👉1️⃣《JavaSE系列教程》 🌺 MySQL系列 🌺👉2️⃣《MySQL系列教程》 🍀 JavaWeb系列 🍀👉3️⃣《JavaWeb系列教程》 🌻 SSM框架系列 🌻👉4️⃣《SSM框架系列教程》 🎉本博客知识点收录于🎉👉🚀《SSM框架系列教程》🚀—✈️01【高内聚

    2024年03月23日
    浏览(40)
  • 彻底搞懂 PHP 运算符 ?: 和 ??

    ?: 称之为短三元运算符,它是我们熟悉的三元运算符(也叫做条件运算符)的一种特殊写法,也就是省略了三元运算符中间的部分。 复习一下三元表达式的语法: (expr1) ? (expr2) : (expr3) 在 expr1 求值为 true 时的值为 expr2,在 expr1 求值为 false 时的值为 expr3。 省略三元运算符中间

    2024年02月11日
    浏览(29)
  • 一文彻底搞懂ssh的端口转发

    端口转发是突破网络域隔离的一个手段。在学习这个知识的时候需要不断自问 为什么需要端口转发? 应用场景是什么呢? SSH 隧道或 SSH 端口转发可以用来在 客户端和服务器之间建立一个加密的 SSH 连接 如下图,通过它来把本地流量转发到服务器端,或者把服务器端流量转发

    2023年04月22日
    浏览(30)
  • 3分钟带你彻底搞懂 Kafka

    实时数据处理 ,从名字上看,很好理解,就是将数据进行实时处理,在现在流行的微服务开发中,最常用实时数据处理平台有 RabbitMQ、RocketMQ 等消息中间件。 这些中间件,最大的特点主要有两个: 服务解耦 流量削峰 在早期的 web 应用程序开发中,当请求量突然上来了时候,

    2024年04月16日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包