Top Description Fields Constructors Methods
org.springframework.core.env

public abstract Class CommandLinePropertySource<T>

extends EnumerablePropertySource<T>
Class Inheritance
Known Direct Subclasses
org.springframework.core.env.JOptCommandLinePropertySource, org.springframework.core.env.SimpleCommandLinePropertySource
Type Parameters
<T>
the source type
Imports
java.util.Collection, .List, org.springframework.lang.Nullable, org.springframework.util.StringUtils

Abstract base class for PropertySource implementations backed by command line arguments. The parameterized type T represents the underlying source of command line options. For instance, SimpleCommandLinePropertySource uses a String array.

Purpose and General Usage

For use in standalone Spring-based applications, i.e. those that are bootstrapped via a traditional main method accepting a String[] of arguments from the command line. In many cases, processing command-line arguments directly within the main method may be sufficient, but in other cases, it may be desirable to inject arguments as values into Spring beans. It is this latter set of cases in which a CommandLinePropertySource becomes useful. A CommandLinePropertySource will typically be added to the Environment of the Spring ApplicationContext, at which point all command line arguments become available through the Environment#getProperty(String) family of methods. For example:
public static void main(String[] args) {
    CommandLinePropertySource clps = ...;
    AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
    ctx.getEnvironment().getPropertySources().addFirst(clps);
    ctx.register(AppConfig.class);
    ctx.refresh();
}
With the bootstrap logic above, the AppConfig class may @Inject the Spring Environment and query it directly for properties:
@Configuration
public class AppConfig {

    @Inject Environment env;

    @Bean
    public void DataSource dataSource() {
        MyVendorDataSource dataSource = new MyVendorDataSource();
        dataSource.setHostname(env.getProperty("db.hostname", "localhost"));
        dataSource.setUsername(env.getRequiredProperty("db.username"));
        dataSource.setPassword(env.getRequiredProperty("db.password"));
        // ...
        return dataSource;
    }
}
Because the CommandLinePropertySource was added to the Environment's set of MutablePropertySources using the #addFirst method, it has the highest search precedence, meaning that while "db.hostname" and other properties may exist in other property sources such as the system environment variables, it will be chosen from the command line property source first. This is a reasonable approach given that arguments specified on the command line are naturally more specific than those specified as environment variables.

As an alternative to injecting the Environment, Spring's @Value annotation may be used to inject these properties, given that a PropertySourcesPropertyResolver bean has been registered, either directly or through using the <context:property-placeholder> element. For example:

@Component
public class MyComponent {

    @Value("my.property:defaultVal")
    private String myProperty;

    public void getMyProperty() {
        return this.myProperty;
    }

    // ...
}

Working with option arguments

Individual command line arguments are represented as properties through the usual PropertySource#getProperty(String) and PropertySource#containsProperty(String) methods. For example, given the following command line:

--o1=v1 --o2
'o1' and 'o2' are treated as "option arguments", and the following assertions would evaluate true:
CommandLinePropertySource<?> ps = ...
assert ps.containsProperty("o1") == true;
assert ps.containsProperty("o2") == true;
assert ps.containsProperty("o3") == false;
assert ps.getProperty("o1").equals("v1");
assert ps.getProperty("o2").equals("");
assert ps.getProperty("o3") == null;
Note that the 'o2' option has no argument, but getProperty("o2") resolves to empty string ("") as opposed to null, while getProperty("o3") resolves to null because it was not specified. This behavior is consistent with the general contract to be followed by all PropertySource implementations.

Note also that while "--" was used in the examples above to denote an option argument, this syntax may vary across individual command line argument libraries. For example, a JOpt- or Commons CLI-based implementation may allow for single dash ("-") "short" option arguments, etc.

Working with non-option arguments

Non-option arguments are also supported through this abstraction. Any arguments supplied without an option-style prefix such as "-" or "--" are considered "non-option arguments" and available through the special "nonOptionArgs" property. If multiple non-option arguments are specified, the value of this property will be a comma-delimited string containing all the arguments. This approach ensures a simple and consistent return type (String) for all properties from a CommandLinePropertySource and at the same time lends itself to conversion when used in conjunction with the Spring Environment and its built-in ConversionService. Consider the following example:

--o1=v1 --o2=v2 /path/to/file1 /path/to/file2
In this example, "o1" and "o2" would be considered "option arguments", while the two filesystem paths qualify as "non-option arguments". As such, the following assertions will evaluate true:
CommandLinePropertySource<?> ps = ...
assert ps.containsProperty("o1") == true;
assert ps.containsProperty("o2") == true;
assert ps.containsProperty("nonOptionArgs") == true;
assert ps.getProperty("o1").equals("v1");
assert ps.getProperty("o2").equals("v2");
assert ps.getProperty("nonOptionArgs").equals("/path/to/file1,/path/to/file2");

As mentioned above, when used in conjunction with the Spring Environment abstraction, this comma-delimited string may easily be converted to a String array or list:

Environment env = applicationContext.getEnvironment();
String[] nonOptionArgs = env.getProperty("nonOptionArgs", String[].class);
assert nonOptionArgs[0].equals("/path/to/file1");
assert nonOptionArgs[1].equals("/path/to/file2");

The name of the special "non-option arguments" property may be customized through the setNonOptionArgsPropertyName(String) method. Doing so is recommended as it gives proper semantic value to non-option arguments. For example, if filesystem paths are being specified as non-option arguments, it is likely preferable to refer to these as something like "file.locations" than the default of "nonOptionArgs":

public static void main(String[] args) {
    CommandLinePropertySource clps = ...;
    clps.setNonOptionArgsPropertyName("file.locations");

    AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
    ctx.getEnvironment().getPropertySources().addFirst(clps);
    ctx.register(AppConfig.class);
    ctx.refresh();
}

Limitations

This abstraction is not intended to expose the full power of underlying command line parsing APIs such as JOpt or Commons CLI. Its intent is rather just the opposite: to provide the simplest possible abstraction for accessing command line arguments after they have been parsed. So the typical case will involve fully configuring the underlying command line parsing API, parsing the String[] of arguments coming into the main method, and then simply providing the parsing results to an implementation of CommandLinePropertySource. At that point, all arguments can be considered either 'option' or 'non-option' arguments and as described above can be accessed through the normal PropertySource and Environment APIs.
Author
Chris Beams
Since
3.1
See Also
PropertySource, SimpleCommandLinePropertySource

Field Summary

Modifier and TypeField and Description
public static final String
COMMAND_LINE_PROPERTY_SOURCE_NAME

The default name given to CommandLinePropertySource instances: commandLineArgs.

public static final String
DEFAULT_NON_OPTION_ARGS_PROPERTY_NAME

The default name of the property representing non-option arguments: nonOptionArgs.

private String

Constructor Summary

AccessConstructor and Description
public
CommandLinePropertySource(T source)

Create a new CommandLinePropertySource having the default name commandLineArgs and backed by the given source object.

public
CommandLinePropertySource(String name, T source)

Create a new CommandLinePropertySource having the given name and backed by the given source object.

Method Summary

Modifier and TypeMethod and Description
protected abstract boolean
containsOption(String name)

Return whether the set of option arguments parsed from the command line contains an option with the given name.

public final boolean
containsProperty(String
the name of the property to find
name
)

Overrides org.springframework.core.env.EnumerablePropertySource.containsProperty.

This implementation first checks to see if the name specified is the special "non-option arguments" property, and if so delegates to the abstract getNonOptionArgs() method checking to see whether it returns an empty collection.

protected abstract List<String>
getNonOptionArgs()

Return the collection of non-option arguments parsed from the command line.

protected abstract List<String>
getOptionValues(String name)

Return the collection of values associated with the command line option having the given name.

public final String
getProperty(String
the property to find
name
)

Implements abstract org.springframework.core.env.PropertySource.getProperty.

This implementation first checks to see if the name specified is the special "non-option arguments" property, and if so delegates to the abstract getNonOptionArgs() method.

public void
setNonOptionArgsPropertyName(String nonOptionArgsPropertyName)

Specify the name of the special "non-option arguments" property.

Inherited from org.springframework.core.env.EnumerablePropertySource:
getPropertyNames

Field Detail

COMMAND_LINE_PROPERTY_SOURCE_NAMEback to summary
public static final String COMMAND_LINE_PROPERTY_SOURCE_NAME

The default name given to CommandLinePropertySource instances: commandLineArgs.

DEFAULT_NON_OPTION_ARGS_PROPERTY_NAMEback to summary
public static final String DEFAULT_NON_OPTION_ARGS_PROPERTY_NAME

The default name of the property representing non-option arguments: nonOptionArgs.

nonOptionArgsPropertyNameback to summary
private String nonOptionArgsPropertyName

Constructor Detail

CommandLinePropertySourceback to summary
public CommandLinePropertySource(T source)

Create a new CommandLinePropertySource having the default name commandLineArgs and backed by the given source object.

CommandLinePropertySourceback to summary
public CommandLinePropertySource(String name, T source)

Create a new CommandLinePropertySource having the given name and backed by the given source object.

Method Detail

containsOptionback to summary
protected abstract boolean containsOption(String name)

Return whether the set of option arguments parsed from the command line contains an option with the given name.

containsPropertyback to summary
public final boolean containsProperty(String name)

Overrides org.springframework.core.env.EnumerablePropertySource.containsProperty.

This implementation first checks to see if the name specified is the special "non-option arguments" property, and if so delegates to the abstract getNonOptionArgs() method checking to see whether it returns an empty collection. Otherwise, delegates to and returns the value of the abstract containsOption(String) method.

Parameters
name:String

Doc from org.springframework.core.env.EnumerablePropertySource.containsProperty.

the name of the property to find

Annotations
@Override
getNonOptionArgsback to summary
protected abstract List<String> getNonOptionArgs()

Return the collection of non-option arguments parsed from the command line. Never null.

getOptionValuesback to summary
protected abstract List<String> getOptionValues(String name)

Return the collection of values associated with the command line option having the given name.

  • if the option is present and has no argument (e.g.: "--foo"), return an empty collection ([])
  • if the option is present and has a single value (e.g. "--foo=bar"), return a collection having one element (["bar"])
  • if the option is present and the underlying command line parsing library supports multiple arguments (e.g. "--foo=bar --foo=baz"), return a collection having elements for each value (["bar", "baz"])
  • if the option is not present, return null
Annotations
@Nullable
getPropertyback to summary
public final String getProperty(String name)

Implements abstract org.springframework.core.env.PropertySource.getProperty.

This implementation first checks to see if the name specified is the special "non-option arguments" property, and if so delegates to the abstract getNonOptionArgs() method. If so and the collection of non-option arguments is empty, this method returns null. If not empty, it returns a comma-separated String of all non-option arguments. Otherwise, delegates to and returns the result of the abstract getOptionValues(String) method.

Parameters
name:String

Doc from org.springframework.core.env.PropertySource.getProperty.

the property to find

Annotations
@Override
@Nullable
setNonOptionArgsPropertyNameback to summary
public void setNonOptionArgsPropertyName(String nonOptionArgsPropertyName)

Specify the name of the special "non-option arguments" property. The default is nonOptionArgs.