本文介绍下Spring Boot工程传递命令行参数的一些说明。

启动Spring Boot项目时传递参数,有三种参数形式:

选项参数

选项参数,比如通过–-server.port来设置应用程序的端口。基本格式为--name=value(“–”为连续两个减号)。

其配置作用等价于在application.properties中配置的server.port=8081。

选项参数,也可以直接通过@Value在类中获取,如下:

@RestController
public class ParamController {

    @Value("${server.port}")
    private String serverPort;
}

选项参数和非选项参数均可以通过ApplicationArguments接口获取,具体获取方法直接在使用参数的类中注入该接口即可。

@RestController
public class ArgumentsController {
    @Resource
    private ApplicationArguments arguments;
}

通过ApplicationArguments接口提供的方法即可获得对应的参数。关于该接口后面会详细讲解。

非选项参数

非选项参数的使用示例如下:

java -jar xxx.jar abc def

上述示例中,“abc”和“def”便是非选项参数。

系统参数

系统参数,该参数会被设置到系统变量中,使用示例如下:

java -jar -Dserver.port=8081 xxx.jar

系统参数可以通过java.lang.System提供的方法获取:

String systemServerPort = System.getProperty("server.port");

关于参数值区别

重点看选项参数和系统参数。通过上面的示例我们已经发现使用选项参数时,参数在命令中是位于xxx.jar之后传递的,而系统参数是紧随java -jar之后。

如果不按照该顺序进行执行,比如使用如下方式使用选项参数:

java -jar --server.port=8081 xxx.jar

则会抛出如下异常:

Unrecognized option: --server.port=8081

Error: Could not create the Java Virtual Machine.

Error: A fatal exception has occurred. Program will exit.

如果将系统参数放在jar包后面,问题会更严重。会出现可以正常启动,但参数无法生效。这也是为什么有时候明明传递了参数但是却未生效,那很可能是因为把参数的位置写错了。

一定谨记,通过-D传递系统参数时,务必放置在待执行的jar包之前。

另外一个重要的不同是:通过@Value形式可以获得系统参数和选项参数,但通过System.getProperty方法只能获得系统参数。

ApplicationArguments接口获得相关参数的例子

上面提到了可以通过注入ApplicationArguments接口获得相关参数,下面看一下具体的使用示例:

@RestController
public class ArgumentsController {

  @Resource
  private ApplicationArguments arguments;

  @GetMapping("/args")
  public String getArgs() {
    System.out.println("# 非选项参数数量: " + arguments.getNonOptionArgs().size());

    System.out.println("# 选项参数数量: " + arguments.getOptionNames().size());

    System.out.println("# 非选项具体参数:");

    arguments.getNonOptionArgs().forEach(System.out::println);

    System.out.println("# 选项参数具体参数:");

    arguments.getOptionNames().forEach(optionName -> {
        System.out.println("--" + optionName + "=" + arguments.getOptionValues(optionName));
    });

    return "success";
  }

}

通过注入ApplicationArguments接口,然后在方法中调用该接口的方法即可获得对应的参数信息。

ApplicationArguments接口中封装了启动时原始参数的数组、选项参数的列表、非选项参数的列表以及选项参数获得和检验。

关于系统变量与application.properties参数

系统变量可以覆盖application.properties参数

参考

https://blog.csdn.net/weixin_39613692/article/details/114801158