system property 和 environment property

系统变量(system property)

是java应用程序自身指定的变量,通常我们可以在启动应用的时候指定,指定方式可以有以下两种

输入java -jar -help 回顾一下java启动jar文件的命令

java [-options] -jar jarfile [args…]

其中选项options中包括-Dkey=value,对应vm options中的标准参数

其中args即为自定义参数,对应program arguments

前者可以直接通过System.getProperty(key)获取到,后者作为文本传入main函数中,需要进一步处理才能使用,下面进一步介绍

vm options

VM options : JVM虚拟机启动命令可选项,在这里可以设置一些运行参数。

参数大致可分为标准(-D等)和非标准(-X、-XX)两种,非标准的可选项不保证在所有平台上都实现,并且未来的版本中可能会被修改且不告知,总之就是不稳定(Unstable)。不过有的非标准可选项还是非常有用的。(这里不做详细介绍,参考另一文章)

在设置VM参数时,如果我们需要自定义一些参数信息(这个行为称之为,设置系统属性),则必须使用-Dkey=value这种形式,多组参数之间使用空格分隔
在这里插入图片描述
通过这里设置的参数,JVM在初始化时,会对System中的Properties进行对应赋值,所以我们也可以通过System.getProperty(String key)获取到(仅限-D形式的键值对标准参数可获取,其他格式以及非标准参数无法读取到)。

非标准参数示例

-Xms1024m,设置JVM初始堆内存为1024m。此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。
-Xmx1024m,设置JVM最大堆内存为1024m。
-Xss512k,设置每个线程的栈大小。JDK5.0以后每个线程栈大小为1M,之前每个线程栈大小为256K。在相同物理内存下,减小这个值能生成更多的线程,当然操作系统对一个进程内的线程数还是有限制的,不能无限生成。线程栈的大小是个双刃剑,如果设置过小,可能会出现栈溢出,特别是在该线程内有递归、大的循环时出现溢出的可能性更大,如果该值设置过大,就有影响到创建栈的数量,如果是多线程的应用,就会出现内存溢出的错误。
-Xmn341m,设置年轻代大小为341m。在整个堆内存大小确定的情况下,增大年轻代将会减小年老代,反之亦然。此值关系到JVM垃圾回收,对系统性能影响较大,官方推荐配置为整个堆大小的3/8。
-XX:NewSize=341m,设置年轻代初始值为341M。
-XX:MaxNewSize=341m,设置年轻代最大值为341M。
-XX:PermSize=512m,设置持久代初始值为512M,但在java8及之后就不支持了,改用-XX:MetaspaceSize=512m。
-XX:MaxPermSize=512m,设置持久代最大值为512M,同样在java8及之后就不支持了,改用-XX:MaxMetaspaceSize=512m。
-XX:NewRatio=2,设置年轻代(包括1个Eden和2个Survivor区)与年老代的比值。表示年轻代比年老代为1:2。
-XX:SurvivorRatio=8,设置年轻代中Eden区与Survivor区的比值。表示2个Survivor区(JVM堆内存年轻代中默认有2个大小相等的Survivor区)与1个Eden区的比值为1:1:8,即1个Survivor区占整个年轻代大小的1/10。
-XX:MaxTenuringThreshold=15,具体参看JVM系列之内存分配和回收策略中对象的衰老过程。
-XX:ReservedCodeCacheSize=256m,设置代码缓存的大小,用来存储已编译方法生成的本地代码。

program arguments

在这里设置的参数是作为main方法的参数String[] args传入的

-Dkey=value属于自动设置环境变量,格式固定,局限性较大

program arguments中的参数,具有很大的灵活性,可以自定义代码进行解析,

下面简单介绍spring中的部分属性解析代码CommandLinePropertySource

CommandLinePropertySource

我们在启动项目时,是可以指定命令行参数 的,诸如:

此类将命令行参数定义为两种:
option arguments:指定方式通常如下 --k=v
non-option arguments:不以诸如 – 之类前缀修饰的属性,被解析为 non-option arguments,诸如 a b c 会被解析为 a,b,c,其 key 为 nonOptionArgs,当然我们也可以通过 setNonOptionArgsPropertyName 方法修改该 key 值

Spring 针对 CommandLinePropertySource 提供了两个实现(当然我们也可以自己实现),分别为 SimpleCommandLinePropertySource 和 JOptCommandLinePropertySource,基本我们用到的也就是 SimpleCommandLinePropertySource 了

SimpleCommandLinePropertySource

在该类中,命令行参数 被解析为 CommandLineArgs,负责解析工作的类是 SimpleCommandLineArgsParser,见其构造方法:

public class SimpleCommandLinePropertySource extends CommandLinePropertySource<CommandLineArgs> {
	public SimpleCommandLinePropertySource(String... args) {
		super(new SimpleCommandLineArgsParser().parse(args));
	}
}

属性获取测试代码

    public void command() {
        String[] command = {"--o1=v1", "--o2", "a", "b", "c"};
        SimpleCommandLinePropertySource propertySource
                = new SimpleCommandLinePropertySource("command", command);
        // v1
        String o1 = propertySource.getProperty("o1");
        // ""
        String o2 = propertySource.getProperty("o2");
        // null
        String o3 = propertySource.getProperty("o3");
        // "a,b,c"
        String nonOptionArgs = propertySource.getProperty("nonOptionArgs");
    }

实际应用,将args解析到系统变量中

    public void source(String... args) {
        simpleCommandLinePropertySource = new SimpleCommandLinePropertySource(args);
        Set<String> stringSet = simpleCommandLinePropertySource.getSource().getOptionNames();
        if (CollectionUtils.isNotEmpty(stringSet)) {
            for (String key : stringSet) {
                String values = simpleCommandLinePropertySource.getProperty(key);
                if (StringUtils.isNotEmpty(key) && StringUtils.isNotEmpty(values)) {
                    String oldValue = System.setProperty(key, values);
                    LOGGER.info("设置系统环境变量为:{}={}  原来的值为:{}", key, values, oldValue);
                }
            }
        }
    }

环境变量(environment property)

可以通过idea的启动参数设置

在spring项目中,同样可以通过@value注解获取到environment property,但是假如存在同名的system property,则会读取后者
另外,spirng项目中,定义了自己的一套解析Program arguments参数的规则,如果有符合格式的Program arguments,
如–serverId=8080,会将此参数解析成对应的system property,且其优先级大于VM options中的同名属性

总之,在spring项目中,三者的优先级
Program arguments (–priority=program-agrs) >
VM options (-Dpriority=vm-options) >
Environment variable (priority=environment-variables)

system property 和 environment property_第1张图片
这里的环境变量并不是系统级别的环境变量,应该是仅针对此进程,通过System.getEnv(key)可以获取

    public static void main(String[] args) {
        Map<String, String> env = System.getenv();
        env.entrySet().forEach(System.out::println);
    }

扩展文章
springboot环境之Properties加载详解
https://blog.csdn.net/qq_31086797/article/details/107395108?

spring是如何把environment中的属性值使用@Value注入到字段中的
https://blog.csdn.net/qq_31086797/article/details/124136140

你可能感兴趣的:(spring,Java基础,java,VM,options)