mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-07-05 00:56:58 +08:00
[bs-47] Add default command line args to SpringApplication
* See SpringApplication.setDefaultCommandLineArgs * Assumes command line is in "simple" form (TODO: if we need JOpt etc. support then the command line args parsing from Spring needs to be exposed) * If defaults are provided the command line might be re-ordered slightly (non-option args come after option args) * Allows custom application.properties file names to be specified as a side effect (--spring.config.name=... or --spring.config.location=...}. [Fixes #48284369]
This commit is contained in:
parent
61fa55b524
commit
d6a670e13e
|
@ -19,7 +19,9 @@ package org.springframework.bootstrap;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
|
@ -33,7 +35,6 @@ import org.springframework.context.annotation.AnnotatedBeanDefinitionReader;
|
|||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigUtils;
|
||||
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
import org.springframework.context.support.AbstractApplicationContext;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.core.GenericTypeResolver;
|
||||
|
@ -41,6 +42,7 @@ import org.springframework.core.annotation.AnnotationAwareOrderComparator;
|
|||
import org.springframework.core.env.CommandLinePropertySource;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.core.env.SimpleCommandLinePropertySource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
|
@ -151,6 +153,8 @@ public class SpringApplication {
|
|||
|
||||
private List<ApplicationContextInitializer<?>> initializers;
|
||||
|
||||
private String[] defaultCommandLineArgs;
|
||||
|
||||
/**
|
||||
* Crate a new {@link SpringApplication} instance. The application context will load
|
||||
* beans from the specified sources (see {@link SpringApplication class-level}
|
||||
|
@ -316,13 +320,76 @@ public class SpringApplication {
|
|||
if (environment instanceof ConfigurableEnvironment) {
|
||||
ConfigurableEnvironment configurable = (ConfigurableEnvironment) environment;
|
||||
if (this.addCommandLineProperties) {
|
||||
CommandLinePropertySource<?> propertySource = new SimpleCommandLinePropertySource(
|
||||
args);
|
||||
PropertySource<?> propertySource = new SimpleCommandLinePropertySource(
|
||||
mergeCommandLineArgs(this.defaultCommandLineArgs, args));
|
||||
configurable.getPropertySources().addFirst(propertySource);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge two sets of command lines, the defaults and the ones passed in at run time.
|
||||
*
|
||||
* @param defaults the default values
|
||||
* @param args the ones passed in at runtime
|
||||
* @return a new command line
|
||||
*/
|
||||
protected String[] mergeCommandLineArgs(String[] defaults, String[] args) {
|
||||
|
||||
if (defaults == null || defaults.length == 0) {
|
||||
return args;
|
||||
}
|
||||
|
||||
List<String> result = new ArrayList<String>();
|
||||
Map<String, String> options = new LinkedHashMap<String, String>();
|
||||
|
||||
for (String arg : defaults) {
|
||||
if (isOptionArg(arg)) {
|
||||
addOptionArg(options, arg);
|
||||
} else {
|
||||
result.add(arg);
|
||||
}
|
||||
}
|
||||
for (String arg : args) {
|
||||
if (isOptionArg(arg)) {
|
||||
addOptionArg(options, arg);
|
||||
} else if (!result.contains(arg)) {
|
||||
result.add(arg);
|
||||
}
|
||||
}
|
||||
|
||||
List<String> optionsList = new ArrayList<String>();
|
||||
for (String key : options.keySet()) {
|
||||
String value = options.get(key);
|
||||
optionsList.add("--" + key + (value == null ? "" : "=" + value));
|
||||
}
|
||||
result.addAll(0, optionsList);
|
||||
|
||||
return result.toArray(new String[result.size()]);
|
||||
|
||||
}
|
||||
|
||||
private boolean isOptionArg(String arg) {
|
||||
return arg.startsWith("--");
|
||||
}
|
||||
|
||||
private void addOptionArg(Map<String, String> map, String arg) {
|
||||
String optionText = arg.substring(2, arg.length());
|
||||
String optionName;
|
||||
String optionValue = null;
|
||||
if (optionText.contains("=")) {
|
||||
optionName = optionText.substring(0, optionText.indexOf("="));
|
||||
optionValue = optionText.substring(optionText.indexOf("=") + 1,
|
||||
optionText.length());
|
||||
} else {
|
||||
optionName = optionText;
|
||||
}
|
||||
if (optionName.isEmpty()) {
|
||||
throw new IllegalArgumentException("Invalid argument syntax: " + arg);
|
||||
}
|
||||
map.put(optionName, optionValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load beans into the application context.
|
||||
* @param context the context to load beans into
|
||||
|
@ -394,6 +461,15 @@ public class SpringApplication {
|
|||
this.addCommandLineProperties = addCommandLineProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set some default command line arguments which can be overridden by those passed
|
||||
* into the run methods.
|
||||
* @param defaultCommandLineArgs the default command line args to set
|
||||
*/
|
||||
public void setDefaultCommandLineArgs(String... defaultCommandLineArgs) {
|
||||
this.defaultCommandLineArgs = defaultCommandLineArgs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the bean name generator that should be used when generating bean names.
|
||||
*/
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.springframework.beans.BeansException;
|
|||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.BeanNameGenerator;
|
||||
import org.springframework.beans.factory.support.DefaultBeanNameGenerator;
|
||||
import org.springframework.bootstrap.context.annotation.EnableAutoConfiguration;
|
||||
import org.springframework.bootstrap.context.embedded.AnnotationConfigEmbeddedWebApplicationContext;
|
||||
import org.springframework.bootstrap.context.embedded.jetty.JettyEmbeddedServletContainerFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
@ -37,6 +38,7 @@ import org.springframework.context.support.StaticApplicationContext;
|
|||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.env.CommandLinePropertySource;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.core.env.StandardEnvironment;
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
|
@ -67,6 +69,13 @@ public class SpringApplicationTests {
|
|||
|
||||
private ApplicationContext context;
|
||||
|
||||
private Environment getEnvironment() {
|
||||
if (this.context instanceof ConfigurableApplicationContext) {
|
||||
return ((ConfigurableApplicationContext) this.context).getEnvironment();
|
||||
}
|
||||
throw new IllegalStateException("No Environment available");
|
||||
}
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
if (this.context instanceof ConfigurableApplicationContext) {
|
||||
|
@ -250,6 +259,17 @@ public class SpringApplicationTests {
|
|||
assertNotNull(this.context);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultCommandLineArgs() throws Exception {
|
||||
SpringApplication application = new SpringApplication(ExampleConfig.class);
|
||||
application.setDefaultCommandLineArgs("--foo", "--bar=spam", "bucket");
|
||||
application.setWebEnvironment(false);
|
||||
this.context = application.run("--bar=foo", "bucket", "crap");
|
||||
assertThat(this.context, instanceOf(AnnotationConfigApplicationContext.class));
|
||||
assertThat(getEnvironment().getProperty("bar"), equalTo("foo"));
|
||||
assertThat(getEnvironment().getProperty("foo"), equalTo(""));
|
||||
}
|
||||
|
||||
private boolean hasPropertySource(ConfigurableEnvironment environment,
|
||||
Class<?> propertySourceClass) {
|
||||
for (PropertySource<?> source : environment.getPropertySources()) {
|
||||
|
@ -311,6 +331,7 @@ public class SpringApplicationTests {
|
|||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
static class ExampleWebConfig {
|
||||
|
||||
@Bean
|
||||
|
|
Loading…
Reference in New Issue
Block a user