ApplicationArguments 接口提供了对用于访问运行 SpringApplication 程序传递的参数。Spring Boot 提供了它的默认实现 DefaultApplicationArguments。例如:
public static void main(String[] args) {
System.out.println(Arrays.toString(args));
ConfigurableApplicationContext context = SpringApplication.run(
ApplicationargumentsDemoApplication.class, args);
Environment environment = context.getEnvironment();
System.out.println("key1=" + environment.getProperty("key1"));
System.out.println("key2=" + environment.getProperty("key2"));
}其中,args 是运行程序时动态传递过来的。如下图:

运行成功后将输出如下信息:
2020-11-09 13:01:51.141 INFO 12612 --- [ restartedMain] .s.a.ApplicationargumentsDemoApplication : Started ApplicationargumentsDemoApplication in 4.313 seconds (JVM running for 10.254) key1=val1 key2=val2
注意:上面 IDEA 的 “Run/Debug Configurations” 界面中的 “Program arguments” 输入框中输入的参数必须遵循 “--键=值” 的格式。
上面代码演示了使用 Environment 获取 run() 方法传递的 args 参数。下面将介绍通过注入 ApplicationArguments 对象来访问参数,如下:
package com.huangx.springboot.applicationarguments_demo2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Arrays;
@RestController
@SpringBootApplication
public class ApplicationargumentsDemo2Application {
@Autowired
private ApplicationArguments arguments;
public static void main(String[] args) {
SpringApplication.run(ApplicationargumentsDemo2Application.class, args);
}
@RequestMapping("/")
public String index() {
return "key1=" + Arrays.toString(arguments.getOptionValues(
"key1").toArray(new String[]{})) + "<br/>" +
"key2=" + Arrays.toString(arguments.getOptionValues(
"key2").toArray(new String[]{}));
}
}启动应用程序后,使用浏览器访问 http://localhost:8080 ,效果如下图:

接下来,将介绍实现自己的 ApplicationRunner 类来获取参数。代码如下:
package com.huangx.springboot.applicationarguments_demo2;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import java.util.Arrays;
@Component
public class MyApplicationRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("========= MyApplicationRunner =========");
for(String name : args.getOptionNames()) {
System.out.println(name + "=" + Arrays.toString(
args.getOptionValues(name).toArray(new String[]{})));
}
}
}启动 Spring Boot 程序,输出结果如下:
========= MyApplicationRunner ========= key1=[val1] key2=[val2]
我们先从 SpringApplication.run() 方法开始查看,源代码如下:

源代码中,是直接 new 了一个 DefaultApplicationArguments 默认实现类作为 ApplicationArguments 的对象。继续点进去,查看 DefaultApplicationArguments 类的源代码,如下:
package org.springframework.boot;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.springframework.core.env.SimpleCommandLinePropertySource;
import org.springframework.util.Assert;
/**
* Default implementation of {@link ApplicationArguments}.
*
* @author Phillip Webb
* @since 1.4.1
*/
public class DefaultApplicationArguments implements ApplicationArguments {
private final Source source;
private final String[] args;
public DefaultApplicationArguments(String... args) {
Assert.notNull(args, "Args must not be null");
this.source = new Source(args);
this.args = args;
}
@Override
public String[] getSourceArgs() {
return this.args;
}
// 获取所有选项名集合
@Override
public Set<String> getOptionNames() {
String[] names = this.source.getPropertyNames();
return Collections.unmodifiableSet(new HashSet<>(Arrays.asList(names)));
}
// 判断给定的选项是否存在
@Override
public boolean containsOption(String name) {
return this.source.containsProperty(name);
}
// 获取指定key的选项值列表
@Override
public List<String> getOptionValues(String name) {
List<String> values = this.source.getOptionValues(name);
return (values != null) ? Collections.unmodifiableList(values) : null;
}
// 返回在命令行上指定的非选项参数的列表。
@Override
public List<String> getNonOptionArgs() {
return this.source.getNonOptionArgs();
}
private static class Source extends SimpleCommandLinePropertySource {
Source(String[] args) {
super(args);
}
@Override
public List<String> getNonOptionArgs() {
return super.getNonOptionArgs();
}
@Override
public List<String> getOptionValues(String name) {
return super.getOptionValues(name);
}
}
}假如我们启动 Spring Boot 程序传递的参数为 “--key1=val1 --key2=val2 hello world”,则:
getOptionNames() 返回的 key1 和 key2
getOptionValues(String name) 如果你传递 key1 作为name,那么将返回仅包含 val1 的 List
getNonOptionArgs() 返回包含了 hello 和 world 字符串的 List
我们关注的重点应该是 Source 内部类,该类继承了 SimpleCommandLinePropertySource 类,而 SimpleCommandLinePropertySource 类继承了 CommandLinePropertySource 类。