Spring命令行参数封装CommandLineArgs

本文深入解析SpringBoot如何处理命令行参数,介绍CommandLineArgs类的使用,区分option与非option参数,展示如何通过SpringBoot读取和使用这些参数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文代码基于 Springboot 2.1.0

概述

Spring对应用程序运行的命令行参数进行了抽象,这个抽象是类CommandLineArgs

CommandLineArgs类将命令行参数分为两类:

  • option 参数
    • --开头
    • 可以认为是name/value对参数
    • 例子 : --foo, --foo=bar
  • 非 option 参数
    • 不以 --开头
    • 可以认为是只提供了value的参数(具体怎么理解这个值,看业务逻辑的需求)

源代码解析

其源码如下:

package org.springframework.core.env;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.lang.Nullable;

class CommandLineArgs {

	private final Map<String, List<String>> optionArgs = new HashMap<>();
	private final List<String> nonOptionArgs = new ArrayList<>();

	/**
	 * Add an option argument for the given option name and add the given value to the
	 * list of values associated with this option (of which there may be zero or more).
	 * The given value may be {@code null}, indicating that the option was specified
	 * without an associated value (e.g. "--foo" vs. "--foo=bar").
	 * 添加option参数,例如 --foo, --foo=bar 这样的参数
	 * 同名option参数可以有多个值,比如同时提供了 --id=1 --id=2 这样的参数
	 */
	public void addOptionArg(String optionName, @Nullable String optionValue) {
		if (!this.optionArgs.containsKey(optionName)) {
			this.optionArgs.put(optionName, new ArrayList<>());
		}
		if (optionValue != null) {
			this.optionArgs.get(optionName).add(optionValue);
		}
	}

	/**
	 * Return the set of all option arguments present on the command line.
	 * 获取所有option参数的名称列表
	 */
	public Set<String> getOptionNames() {
		return Collections.unmodifiableSet(this.optionArgs.keySet());
	}

	/**
	 * Return whether the option with the given name was present on the command line.
	 * 是否包含某个指定名称的option参数
	 */
	public boolean containsOption(String optionName) {
		return this.optionArgs.containsKey(optionName);
	}

	/**
	 * Return the list of values associated with the given option. null signifies
	 * that the option was not present; empty list signifies that no values were associated
	 * with this option.
	 * 获取指定名称的option参数的值,如果命令行中没有这个option参数,返回null;
	 * 因为一个option参数可能会被指定多个值,所以返回的是一个列表
	 */
	@Nullable
	public List<String> getOptionValues(String optionName) {
		return this.optionArgs.get(optionName);
	}

	/**
	 * Add the given value to the list of non-option arguments.
	 * 增加一个非option参数,一个非option参数可以被认为是只有value的一个参数,
	 */
	public void addNonOptionArg(String value) {
		this.nonOptionArgs.add(value);
	}

	/**
	 * Return the list of non-option arguments specified on the command line.
	 * 返回所有非option参数
	 */
	public List<String> getNonOptionArgs() {
		return Collections.unmodifiableList(this.nonOptionArgs);
	}

}

通过例子说明用途

当我们使用springboot开发一个应用时,假如我们为应用程序提供了命令行参数--pageNo=2 --pageSize=20 --id=1 --id=2 Beijing,通过这个命令行参数我们想告诉应用程序的是:找出Beijing地区,用户id为1或者2的所有订单记录,返回结果集中的第二页,每页容量为10行数据。针对该例子,实际上springboot就将其封装成了一个CommandLineArgs对象:

// SpringApplication 类源代码部分
public ConfigurableApplicationContext run(String... args) {
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
		ConfigurableApplicationContext context = null;
		Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
		configureHeadlessProperty();
		SpringApplicationRunListeners listeners = getRunListeners(args);
		listeners.starting();
		try {
			ApplicationArguments applicationArguments = new DefaultApplicationArguments(
					args);//<=== 构造一个应用程序参数对象,输入参数是命令行参数列表(String[]类型)
			ConfigurableEnvironment environment = prepareEnvironment(listeners,
					applicationArguments);
// DefaultApplicationArguments类代码片段
	public DefaultApplicationArguments(String[] args) {
		Assert.notNull(args, "Args must not be null");
		// Source 是一个 DefaultApplicationArguments 静态内部类,继承自 SimpleCommandLinePropertySource
		this.source = new Source(args); //<==== 继续传递原始命令行参数列表
		this.args = args;
	}
// SimpleCommandLinePropertySource 代码片段
public SimpleCommandLinePropertySource(String... args) {
		// 使用一个SimpleCommandLineArgsParser对象分析原始的命令行参数列表,返回结果类型为CommandLineArgs 
		super(new SimpleCommandLineArgsParser().parse(args));
	}

实际上,SimpleCommandLineArgsParser其实是Spring的一个命令行参数列表分析工具,它的目的就是将原始的命令行参数列表分析处理后保存为一个CommandLineArgs对象。就上面的例子而言,最终的CommandLineArgs对象如下:

在这里插入图片描述

留意上面例子中关于多值option参数的处理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值