Sets a system property value. The property variable is a string with no spaces that represents the name of the property. The value variable is a string that represents the value of the property. If value is a string with spaces, then enclose it in quotation marks (for example -Dfoo=”foo bar”).
可以看到,在文档中并没有规定 args 的写法,那么为什么在案例中需要在参数前加上--呢。由于启动的是一个Spring Boot项目,尝试去Spring Boot文档中寻找答案。 在4.2.2. Accessing Command Line Properties中有说明,Spring Boot的参数均以-- 开头,成为 Command Line Properties,作为外部化参数的一种。说到外部化参数,那是不是Spring Boot还有其他的外部化参数? Spring Boot 允许外部化配置,以便在不同的环境中使用相同的应用程序代码。可以使用属性文件、 YAML 文件、环境变量和命令行参数来外部化配置,也可以使用@value注释将属性值直接注入 bean,可以通过 Spring 的 Environment 抽象访问属性值,也可以通过@configurationproperties绑定到结构化对象。 对于这么多的外部化配置,就会存在相同的属性覆盖的情况,而Spring Boot按照17种不同的外部化配置规约了不同的优先级,这里引用和本篇文章相关的参数。
4.Command line arguments 9.Java System properties(System.getProperties()). 10.OS environment variables. 15.Application properties packaged inside your jar (application.properties and YAML variants). 17.Default properties (specified by setting SpringApplication.setDefaultProperties).
2020-09-17 23:34:02.392 INFO 6774 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8082 (http) with context path '' 2020-09-17 23:34:02.400 INFO 6774 --- [ main] c.l.p.c.demo.CommandDemoApplication : Started CommandDemoApplication in 1.988 seconds (JVM running for 2.659) 2020-09-17 23:34:02.401 INFO 6774 --- [ main] c.l.p.c.demo.CommandDemoApplication : COMMAND ARGS:args:org.springframework.boot.DefaultApplicationArguments@456abb66 2020-09-17 23:34:02.403 INFO 6774 --- [ main] c.l.p.c.demo.CommandDemoApplication : COMMAND ARGS:SourceArgs:--server.port=8082 2020-09-17 23:34:02.403 INFO 6774 --- [ main] c.l.p.c.demo.CommandDemoApplication : COMMAND ARGS:OptionNames:[server.port] 2020-09-17 23:34:02.403 INFO 6774 --- [ main] c.l.p.c.demo.CommandDemoApplication : COMMAND ARGS:NonOptionArgs:[] 2020-09-17 23:34:02.403 INFO 6774 --- [ main] c.l.p.c.demo.CommandDemoApplication : COMMAND ARGS:OptionValues for server.port :[8082] 2020-09-17 23:34:02.403 INFO 6774 --- [ main] c.l.p.c.demo.CommandDemoApplication : --------------------------------------- 2020-09-17 23:34:02.403 INFO 6774 --- [ main] c.l.p.c.demo.CommandDemoApplication : SYSTEM PROPERTIES: server.port:8081 2020-09-17 23:34:02.403 INFO 6774 --- [ main] c.l.p.c.demo.CommandDemoApplication : --------------------------------------- 2020-09-17 23:34:02.403 INFO 6774 --- [ main] c.l.p.c.demo.CommandDemoApplication : SPRING ENV:server.port:8082 2020-09-17 23:34:06.942 INFO 6774 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'
Think more…
如果仔细看开头的案例,会发现-Dsun.net.inetaddr.ttl=3是作为Program arguments 传入应用的,那么这个参数会生效吗?按以上的说法,Spring Boot虽然可以接收这样的Program arguments,但由于其使用的是 -D 的写法,Spring Boot应该是不认识这个参数的。那么如果传入的是--sun.net.inetaddr.ttl=3会不会生效呢,笔者通过实验,发现的确通过获取Spring的环境参数,的确能获取到这个值,但从System properties 中则是null的。在文档中,对于sun.net.inetaddr.ttl的描述是This is a sun private system property,这是一个私有的System properties,笔者认为虽然能从Spring 的环境参数中获取到这个值,但这个值应该是不会生效的,因为在System properties中这个值依旧是null。
privatevoidinitialize()throws WebServerException { //从getPortsDescription(false)获得port logger.info("Tomcat initialized with port(s): " + getPortsDescription(false)); ... } publicintgetPort() { // 可以看到是从protocolHandler中拿出来的,实际通常是Http11NioProtocol,而它又委托给了AbstractEndpoint if (protocolHandler instanceof AbstractProtocol<?>) { return ((AbstractProtocol<?>) protocolHandler).getPort(); } // Fall back for custom protocol handlers not based on AbstractProtocol Objectport= getProperty("port"); if (port instanceof Integer) { return ((Integer) port).intValue(); } // Usually means an invalid protocol has been configured return -1; } /** * Server socket port. */ privateintport= -1; publicintgetPort() { return port; } publicvoidsetPort(int port ) { this.port=port; }