Commit 889d43dd authored by Phillip Webb's avatar Phillip Webb

Refine SpringApplication source types

Update `SpringApplication` so that the `run` methods and constructors
now require `Class<?>` arguments, rather than `Objects`. String based
sources can still be loaded, but must now be set on the `getSources()`
collections. `Package` and `Resource` types are no longer directly
supported.

This change should help IDEs offer better content assist, and will
help integrations with alternative languages such as Ceylon.

Users currently passing in Class references or using the
`spring.main.sources` property should not be affected by this change. If
an XML resource is being used, some refactoring may be required (see the
changes to `SampleSpringXmlApplication` in this commit).

Fixes gh-9170
parent 302f038e
...@@ -56,12 +56,12 @@ public class SpringApplicationLauncher { ...@@ -56,12 +56,12 @@ public class SpringApplicationLauncher {
* @return The application's {@code ApplicationContext} * @return The application's {@code ApplicationContext}
* @throws Exception if the launch fails * @throws Exception if the launch fails
*/ */
public Object launch(Object[] sources, String[] args) throws Exception { public Object launch(Class<?>[] sources, String[] args) throws Exception {
Map<String, Object> defaultProperties = new HashMap<>(); Map<String, Object> defaultProperties = new HashMap<>();
defaultProperties.put("spring.groovy.template.check-template-location", "false"); defaultProperties.put("spring.groovy.template.check-template-location", "false");
Class<?> applicationClass = this.classLoader Class<?> applicationClass = this.classLoader
.loadClass(getSpringApplicationClassName()); .loadClass(getSpringApplicationClassName());
Constructor<?> constructor = applicationClass.getConstructor(Object[].class); Constructor<?> constructor = applicationClass.getConstructor(Class[].class);
Object application = constructor.newInstance((Object) sources); Object application = constructor.newInstance((Object) sources);
applicationClass.getMethod("setDefaultProperties", Map.class).invoke(application, applicationClass.getMethod("setDefaultProperties", Map.class).invoke(application,
defaultProperties); defaultProperties);
......
...@@ -51,7 +51,7 @@ public final class PackagedSpringApplicationLauncher { ...@@ -51,7 +51,7 @@ public final class PackagedSpringApplicationLauncher {
new SpringApplicationLauncher(classLoader).launch(getSources(classLoader), args); new SpringApplicationLauncher(classLoader).launch(getSources(classLoader), args);
} }
private Object[] getSources(URLClassLoader classLoader) throws Exception { private Class<?>[] getSources(URLClassLoader classLoader) throws Exception {
Enumeration<URL> urls = classLoader.getResources("META-INF/MANIFEST.MF"); Enumeration<URL> urls = classLoader.getResources("META-INF/MANIFEST.MF");
while (urls.hasMoreElements()) { while (urls.hasMoreElements()) {
URL url = urls.nextElement(); URL url = urls.nextElement();
......
...@@ -98,7 +98,7 @@ public class SpringApplicationRunner { ...@@ -98,7 +98,7 @@ public class SpringApplicationRunner {
synchronized (this.monitor) { synchronized (this.monitor) {
try { try {
stop(); stop();
Object[] compiledSources = compile(); Class<?>[] compiledSources = compile();
monitorForChanges(); monitorForChanges();
// Run in new thread to ensure that the context classloader is setup // Run in new thread to ensure that the context classloader is setup
this.runThread = new RunThread(compiledSources); this.runThread = new RunThread(compiledSources);
...@@ -125,8 +125,8 @@ public class SpringApplicationRunner { ...@@ -125,8 +125,8 @@ public class SpringApplicationRunner {
} }
} }
private Object[] compile() throws IOException { private Class<?>[] compile() throws IOException {
Object[] compiledSources = this.compiler.compile(this.sources); Class<?>[] compiledSources = this.compiler.compile(this.sources);
if (compiledSources.length == 0) { if (compiledSources.length == 0) {
throw new RuntimeException( throw new RuntimeException(
"No classes found in '" + Arrays.toString(this.sources) + "'"); "No classes found in '" + Arrays.toString(this.sources) + "'");
...@@ -148,7 +148,7 @@ public class SpringApplicationRunner { ...@@ -148,7 +148,7 @@ public class SpringApplicationRunner {
private final Object monitor = new Object(); private final Object monitor = new Object();
private final Object[] compiledSources; private final Class<?>[] compiledSources;
private Object applicationContext; private Object applicationContext;
...@@ -156,10 +156,10 @@ public class SpringApplicationRunner { ...@@ -156,10 +156,10 @@ public class SpringApplicationRunner {
* Create a new {@link RunThread} instance. * Create a new {@link RunThread} instance.
* @param compiledSources the sources to launch * @param compiledSources the sources to launch
*/ */
RunThread(Object... compiledSources) { RunThread(Class<?>... compiledSources) {
super("runner-" + (runnerCounter++)); super("runner-" + (runnerCounter++));
this.compiledSources = compiledSources; this.compiledSources = compiledSources;
if (compiledSources.length != 0 && compiledSources[0] instanceof Class) { if (compiledSources.length != 0) {
setContextClassLoader(((Class<?>) compiledSources[0]).getClassLoader()); setContextClassLoader(((Class<?>) compiledSources[0]).getClassLoader());
} }
setDaemon(true); setDaemon(true);
......
...@@ -73,7 +73,7 @@ public class SpringApplicationLauncherTests { ...@@ -73,7 +73,7 @@ public class SpringApplicationLauncherTests {
public void sourcesDefaultPropertiesAndArgsAreUsedToLaunch() throws Exception { public void sourcesDefaultPropertiesAndArgsAreUsedToLaunch() throws Exception {
System.setProperty("spring.application.class.name", System.setProperty("spring.application.class.name",
TestSpringApplication.class.getName()); TestSpringApplication.class.getName());
Object[] sources = new Object[0]; Class<?>[] sources = new Class<?>[0];
String[] args = new String[0]; String[] args = new String[0];
new SpringApplicationLauncher(getClass().getClassLoader()).launch(sources, args); new SpringApplicationLauncher(getClass().getClassLoader()).launch(sources, args);
...@@ -88,7 +88,7 @@ public class SpringApplicationLauncherTests { ...@@ -88,7 +88,7 @@ public class SpringApplicationLauncherTests {
private Set<String> launch() { private Set<String> launch() {
TestClassLoader classLoader = new TestClassLoader(getClass().getClassLoader()); TestClassLoader classLoader = new TestClassLoader(getClass().getClassLoader());
try { try {
new TestSpringApplicationLauncher(classLoader).launch(new Object[0], new TestSpringApplicationLauncher(classLoader).launch(new Class<?>[0],
new String[0]); new String[0]);
} }
catch (Exception ex) { catch (Exception ex) {
...@@ -129,7 +129,7 @@ public class SpringApplicationLauncherTests { ...@@ -129,7 +129,7 @@ public class SpringApplicationLauncherTests {
private static String[] args; private static String[] args;
public TestSpringApplication(Object[] sources) { public TestSpringApplication(Class<?>[] sources) {
TestSpringApplication.sources = sources; TestSpringApplication.sources = sources;
} }
......
...@@ -398,10 +398,10 @@ The `Application.java` file would declare the `main` method, along with the basi ...@@ -398,10 +398,10 @@ The `Application.java` file would declare the `main` method, along with the basi
[[using-boot-configuration-classes]] [[using-boot-configuration-classes]]
== Configuration classes == Configuration classes
Spring Boot favors Java-based configuration. Although it is possible to call Spring Boot favors Java-based configuration. Although it is possible to use
`SpringApplication.run()` with an XML source, we generally recommend that your primary `SpringApplication` with an XML sources, we generally recommend that your primary
source is a `@Configuration` class. Usually the class that defines the `main` method source is a single `@Configuration` class. Usually the class that defines the `main`
is also a good candidate as the primary `@Configuration`. method is also a good candidate as the primary `@Configuration`.
TIP: Many Spring configuration examples have been published on the Internet that use XML TIP: Many Spring configuration examples have been published on the Internet that use XML
configuration. Always try to use the equivalent Java-based configuration if possible. configuration. Always try to use the equivalent Java-based configuration if possible.
......
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
package sample.xml; package sample.xml;
import java.util.Collections;
import sample.xml.service.HelloWorldService; import sample.xml.service.HelloWorldService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
...@@ -24,6 +26,8 @@ import org.springframework.boot.SpringApplication; ...@@ -24,6 +26,8 @@ import org.springframework.boot.SpringApplication;
public class SampleSpringXmlApplication implements CommandLineRunner { public class SampleSpringXmlApplication implements CommandLineRunner {
private static final String CONTEXT_XML = "classpath:/META-INF/application-context.xml";
@Autowired @Autowired
private HelloWorldService helloWorldService; private HelloWorldService helloWorldService;
...@@ -33,7 +37,9 @@ public class SampleSpringXmlApplication implements CommandLineRunner { ...@@ -33,7 +37,9 @@ public class SampleSpringXmlApplication implements CommandLineRunner {
} }
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
SpringApplication.run("classpath:/META-INF/application-context.xml", args); SpringApplication application = new SpringApplication();
application.setSources(Collections.singleton(CONTEXT_XML));
application.run(args);
} }
} }
...@@ -91,9 +91,20 @@ public class SpringBootContextLoader extends AbstractContextLoader { ...@@ -91,9 +91,20 @@ public class SpringBootContextLoader extends AbstractContextLoader {
@Override @Override
public ApplicationContext loadContext(MergedContextConfiguration config) public ApplicationContext loadContext(MergedContextConfiguration config)
throws Exception { throws Exception {
Class<?>[] configClasses = config.getClasses();
String[] configLocations = config.getLocations();
Assert.state(
!ObjectUtils.isEmpty(configClasses)
|| !ObjectUtils.isEmpty(configLocations),
"No configuration classes "
+ "or locations found in @SpringApplicationConfiguration. "
+ "For default configuration detection to work you need "
+ "Spring 4.0.3 or better (found " + SpringVersion.getVersion()
+ ").");
SpringApplication application = getSpringApplication(); SpringApplication application = getSpringApplication();
application.setMainApplicationClass(config.getTestClass()); application.setMainApplicationClass(config.getTestClass());
application.setSources(getSources(config)); application.addPrimarySources(Arrays.asList(configClasses));
application.getSources().addAll(Arrays.asList(configLocations));
ConfigurableEnvironment environment = new StandardEnvironment(); ConfigurableEnvironment environment = new StandardEnvironment();
if (!ObjectUtils.isEmpty(config.getActiveProfiles())) { if (!ObjectUtils.isEmpty(config.getActiveProfiles())) {
setActiveProfiles(environment, config.getActiveProfiles()); setActiveProfiles(environment, config.getActiveProfiles());
...@@ -137,17 +148,6 @@ public class SpringBootContextLoader extends AbstractContextLoader { ...@@ -137,17 +148,6 @@ public class SpringBootContextLoader extends AbstractContextLoader {
return new SpringApplication(); return new SpringApplication();
} }
private Set<Object> getSources(MergedContextConfiguration mergedConfig) {
Set<Object> sources = new LinkedHashSet<>();
sources.addAll(Arrays.asList(mergedConfig.getClasses()));
sources.addAll(Arrays.asList(mergedConfig.getLocations()));
Assert.state(!sources.isEmpty(), "No configuration classes "
+ "or locations found in @SpringApplicationConfiguration. "
+ "For default configuration detection to work you need "
+ "Spring 4.0.3 or better (found " + SpringVersion.getVersion() + ").");
return sources;
}
private void setActiveProfiles(ConfigurableEnvironment environment, private void setActiveProfiles(ConfigurableEnvironment environment,
String[] profiles) { String[] profiles) {
EnvironmentTestUtils.addEnvironment(environment, "spring.profiles.active=" EnvironmentTestUtils.addEnvironment(environment, "spring.profiles.active="
......
...@@ -65,7 +65,6 @@ import org.springframework.core.env.PropertySource; ...@@ -65,7 +65,6 @@ import org.springframework.core.env.PropertySource;
import org.springframework.core.env.SimpleCommandLinePropertySource; import org.springframework.core.env.SimpleCommandLinePropertySource;
import org.springframework.core.env.StandardEnvironment; import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader; import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.SpringFactoriesLoader; import org.springframework.core.io.support.SpringFactoriesLoader;
import org.springframework.util.Assert; import org.springframework.util.Assert;
...@@ -92,7 +91,7 @@ import org.springframework.web.context.support.StandardServletEnvironment; ...@@ -92,7 +91,7 @@ import org.springframework.web.context.support.StandardServletEnvironment;
* <li>Trigger any {@link CommandLineRunner} beans</li> * <li>Trigger any {@link CommandLineRunner} beans</li>
* </ul> * </ul>
* *
* In most circumstances the static {@link #run(Object, String[])} method can be called * In most circumstances the static {@link #run(Class, String[])} method can be called
* directly from your {@literal main} method to bootstrap your application: * directly from your {@literal main} method to bootstrap your application:
* *
* <pre class="code"> * <pre class="code">
...@@ -122,18 +121,13 @@ import org.springframework.web.context.support.StandardServletEnvironment; ...@@ -122,18 +121,13 @@ import org.springframework.web.context.support.StandardServletEnvironment;
* *
* {@link SpringApplication}s can read beans from a variety of different sources. It is * {@link SpringApplication}s can read beans from a variety of different sources. It is
* generally recommended that a single {@code @Configuration} class is used to bootstrap * generally recommended that a single {@code @Configuration} class is used to bootstrap
* your application, however, any of the following sources can also be used: * your application, however, you may also set {@link #getSources() sources} from:
*
* <ul> * <ul>
* <li>{@link Class} - A Java class to be loaded by {@link AnnotatedBeanDefinitionReader} * <li>The fully qualified class name to be loaded by
* </li> * {@link AnnotatedBeanDefinitionReader}</li>
* <li>{@link Resource} - An XML resource to be loaded by {@link XmlBeanDefinitionReader}, * <li>The location of an XML resource to be loaded by {@link XmlBeanDefinitionReader}, or
* or a groovy script to be loaded by {@link GroovyBeanDefinitionReader}</li> * a groovy script to be loaded by {@link GroovyBeanDefinitionReader}</li>
* <li>{@link Package} - A Java package to be scanned by * <li>The name of a package to be scanned by {@link ClassPathBeanDefinitionScanner}</li>
* {@link ClassPathBeanDefinitionScanner}</li>
* <li>{@link CharSequence} - A class name, resource handle or package name to loaded as
* appropriate. If the {@link CharSequence} cannot be resolved to class and does not
* resolve to a {@link Resource} that exists it will be considered a {@link Package}.</li>
* </ul> * </ul>
* *
* Configuration properties are also bound to the {@link SpringApplication}. This makes it * Configuration properties are also bound to the {@link SpringApplication}. This makes it
...@@ -152,9 +146,9 @@ import org.springframework.web.context.support.StandardServletEnvironment; ...@@ -152,9 +146,9 @@ import org.springframework.web.context.support.StandardServletEnvironment;
* @author Michael Simons * @author Michael Simons
* @author Madhura Bhave * @author Madhura Bhave
* @author Brian Clozel * @author Brian Clozel
* @see #run(Object, String[]) * @see #run(Class, String[])
* @see #run(Object[], String[]) * @see #run(Class[], String[])
* @see #SpringApplication(Object...) * @see #SpringApplication(Class...)
*/ */
public class SpringApplication { public class SpringApplication {
...@@ -214,9 +208,9 @@ public class SpringApplication { ...@@ -214,9 +208,9 @@ public class SpringApplication {
private static final Log logger = LogFactory.getLog(SpringApplication.class); private static final Log logger = LogFactory.getLog(SpringApplication.class);
private Set<Object> primarySources; private Set<Class<?>> primarySources;
private Set<Object> sources = new LinkedHashSet<>(); private Set<String> sources = new LinkedHashSet<>();
private Class<?> mainApplicationClass; private Class<?> mainApplicationClass;
...@@ -256,12 +250,12 @@ public class SpringApplication { ...@@ -256,12 +250,12 @@ public class SpringApplication {
* documentation for details. The instance can be customized before calling * documentation for details. The instance can be customized before calling
* {@link #run(String...)}. * {@link #run(String...)}.
* @param primarySources the primary bean sources * @param primarySources the primary bean sources
* @see #run(Object, String[]) * @see #run(Class, String[])
* @see #SpringApplication(ResourceLoader, Object...) * @see #SpringApplication(ResourceLoader, Class...)
* @see #setSources(Set) * @see #setSources(Set)
*/ */
public SpringApplication(Object... primarySources) { public SpringApplication(Class<?>... primarySources) {
initialize(primarySources); this(null, primarySources);
} }
/** /**
...@@ -271,17 +265,12 @@ public class SpringApplication { ...@@ -271,17 +265,12 @@ public class SpringApplication {
* {@link #run(String...)}. * {@link #run(String...)}.
* @param resourceLoader the resource loader to use * @param resourceLoader the resource loader to use
* @param primarySources the primary bean sources * @param primarySources the primary bean sources
* @see #run(Object, String[]) * @see #run(Class, String[])
* @see #SpringApplication(ResourceLoader, Object...)
* @see #setSources(Set) * @see #setSources(Set)
*/ */
public SpringApplication(ResourceLoader resourceLoader, Object... primarySources) {
this.resourceLoader = resourceLoader;
initialize(primarySources);
}
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
private void initialize(Object[] primarySources) { public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null"); Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources)); this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
this.webApplicationType = deduceWebApplication(); this.webApplicationType = deduceWebApplication();
...@@ -1131,12 +1120,12 @@ public class SpringApplication { ...@@ -1131,12 +1120,12 @@ public class SpringApplication {
* should consider using {@link #getSources()}/{@link #setSources(Set)} rather than * should consider using {@link #getSources()}/{@link #setSources(Set)} rather than
* this calling method. * this calling method.
* @param additionalPrimarySources the additional primary sources to add * @param additionalPrimarySources the additional primary sources to add
* @see #SpringApplication(Object...) * @see #SpringApplication(Class...)
* @see #getSources() * @see #getSources()
* @see #setSources(Set) * @see #setSources(Set)
* @see #getAllSources() * @see #getAllSources()
*/ */
public void addPrimarySources(Collection<Object> additionalPrimarySources) { public void addPrimarySources(Collection<Class<?>> additionalPrimarySources) {
this.primarySources.addAll(additionalPrimarySources); this.primarySources.addAll(additionalPrimarySources);
} }
...@@ -1147,24 +1136,24 @@ public class SpringApplication { ...@@ -1147,24 +1136,24 @@ public class SpringApplication {
* Sources set here will be used in addition to any primary sources set in the * Sources set here will be used in addition to any primary sources set in the
* constructor. * constructor.
* @return the application sources. * @return the application sources.
* @see #SpringApplication(Object...) * @see #SpringApplication(Class...)
* @see #getAllSources() * @see #getAllSources()
*/ */
public Set<Object> getSources() { public Set<String> getSources() {
return this.sources; return this.sources;
} }
/** /**
* Set additional sources that will be used to create an ApplicationContext. A source * Set additional sources that will be used to create an ApplicationContext. A source
* can be: a class, class name, package, package name, or an XML resource location. * can be: a class name, package name, or an XML resource location.
* <p> * <p>
* Sources set here will be used in addition to any primary sources set in the * Sources set here will be used in addition to any primary sources set in the
* constructor. * constructor.
* @param sources the application sources to set * @param sources the application sources to set
* @see #SpringApplication(Object...) * @see #SpringApplication(Class...)
* @see #getAllSources() * @see #getAllSources()
*/ */
public void setSources(Set<Object> sources) { public void setSources(Set<String> sources) {
Assert.notNull(sources, "Sources must not be null"); Assert.notNull(sources, "Sources must not be null");
this.sources = new LinkedHashSet<>(sources); this.sources = new LinkedHashSet<>(sources);
} }
...@@ -1284,9 +1273,9 @@ public class SpringApplication { ...@@ -1284,9 +1273,9 @@ public class SpringApplication {
* @param args the application arguments (usually passed from a Java main method) * @param args the application arguments (usually passed from a Java main method)
* @return the running {@link ApplicationContext} * @return the running {@link ApplicationContext}
*/ */
public static ConfigurableApplicationContext run(Object primarySource, public static ConfigurableApplicationContext run(Class<?> primarySource,
String... args) { String... args) {
return run(new Object[] { primarySource }, args); return run(new Class<?>[] { primarySource }, args);
} }
/** /**
...@@ -1296,7 +1285,7 @@ public class SpringApplication { ...@@ -1296,7 +1285,7 @@ public class SpringApplication {
* @param args the application arguments (usually passed from a Java main method) * @param args the application arguments (usually passed from a Java main method)
* @return the running {@link ApplicationContext} * @return the running {@link ApplicationContext}
*/ */
public static ConfigurableApplicationContext run(Object[] primarySources, public static ConfigurableApplicationContext run(Class<?>[] primarySources,
String[] args) { String[] args) {
return new SpringApplication(primarySources).run(args); return new SpringApplication(primarySources).run(args);
} }
...@@ -1307,14 +1296,14 @@ public class SpringApplication { ...@@ -1307,14 +1296,14 @@ public class SpringApplication {
* argument. * argument.
* <p> * <p>
* Most developers will want to define their own main method and call the * Most developers will want to define their own main method and call the
* {@link #run(Object, String...) run} method instead. * {@link #run(Class, String...) run} method instead.
* @param args command line arguments * @param args command line arguments
* @throws Exception if the application cannot be started * @throws Exception if the application cannot be started
* @see SpringApplication#run(Object[], String[]) * @see SpringApplication#run(Class[], String[])
* @see SpringApplication#run(Object, String...) * @see SpringApplication#run(Class, String...)
*/ */
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
SpringApplication.run(new Object[0], args); SpringApplication.run(new Class<?>[0], args);
} }
/** /**
......
...@@ -73,7 +73,7 @@ public class SpringApplicationBuilder { ...@@ -73,7 +73,7 @@ public class SpringApplicationBuilder {
private final AtomicBoolean running = new AtomicBoolean(false); private final AtomicBoolean running = new AtomicBoolean(false);
private final Set<Object> sources = new LinkedHashSet<>(); private final Set<Class<?>> sources = new LinkedHashSet<>();
private final Map<String, Object> defaultProperties = new LinkedHashMap<>(); private final Map<String, Object> defaultProperties = new LinkedHashMap<>();
...@@ -85,7 +85,7 @@ public class SpringApplicationBuilder { ...@@ -85,7 +85,7 @@ public class SpringApplicationBuilder {
private boolean configuredAsChild = false; private boolean configuredAsChild = false;
public SpringApplicationBuilder(Object... sources) { public SpringApplicationBuilder(Class<?>... sources) {
this.application = createSpringApplication(sources); this.application = createSpringApplication(sources);
} }
...@@ -97,7 +97,7 @@ public class SpringApplicationBuilder { ...@@ -97,7 +97,7 @@ public class SpringApplicationBuilder {
* @return The {@link org.springframework.boot.SpringApplication} instance * @return The {@link org.springframework.boot.SpringApplication} instance
* @since 1.1.0 * @since 1.1.0
*/ */
protected SpringApplication createSpringApplication(Object... sources) { protected SpringApplication createSpringApplication(Class<?>... sources) {
return new SpringApplication(sources); return new SpringApplication(sources);
} }
...@@ -176,7 +176,7 @@ public class SpringApplicationBuilder { ...@@ -176,7 +176,7 @@ public class SpringApplicationBuilder {
* @param sources the sources for the application (Spring configuration) * @param sources the sources for the application (Spring configuration)
* @return the child application builder * @return the child application builder
*/ */
public SpringApplicationBuilder child(Object... sources) { public SpringApplicationBuilder child(Class<?>... sources) {
SpringApplicationBuilder child = new SpringApplicationBuilder(); SpringApplicationBuilder child = new SpringApplicationBuilder();
child.sources(sources); child.sources(sources);
...@@ -205,7 +205,7 @@ public class SpringApplicationBuilder { ...@@ -205,7 +205,7 @@ public class SpringApplicationBuilder {
* @param sources the sources for the application (Spring configuration) * @param sources the sources for the application (Spring configuration)
* @return the parent builder * @return the parent builder
*/ */
public SpringApplicationBuilder parent(Object... sources) { public SpringApplicationBuilder parent(Class<?>... sources) {
if (this.parent == null) { if (this.parent == null) {
this.parent = new SpringApplicationBuilder(sources).web(false) this.parent = new SpringApplicationBuilder(sources).web(false)
.properties(this.defaultProperties).environment(this.environment); .properties(this.defaultProperties).environment(this.environment);
...@@ -245,7 +245,7 @@ public class SpringApplicationBuilder { ...@@ -245,7 +245,7 @@ public class SpringApplicationBuilder {
* @param sources the sources for the application (Spring configuration) * @param sources the sources for the application (Spring configuration)
* @return the new sibling builder * @return the new sibling builder
*/ */
public SpringApplicationBuilder sibling(Object... sources) { public SpringApplicationBuilder sibling(Class<?>... sources) {
return runAndExtractParent().child(sources); return runAndExtractParent().child(sources);
} }
...@@ -258,7 +258,7 @@ public class SpringApplicationBuilder { ...@@ -258,7 +258,7 @@ public class SpringApplicationBuilder {
* parent * parent
* @return the new sibling builder * @return the new sibling builder
*/ */
public SpringApplicationBuilder sibling(Object[] sources, String... args) { public SpringApplicationBuilder sibling(Class<?>[] sources, String... args) {
return runAndExtractParent(args).child(sources); return runAndExtractParent(args).child(sources);
} }
...@@ -273,23 +273,13 @@ public class SpringApplicationBuilder { ...@@ -273,23 +273,13 @@ public class SpringApplicationBuilder {
return this; return this;
} }
/**
* Add more sources to use in this application.
* @param sources the sources to add
* @return the current builder
*/
public SpringApplicationBuilder sources(Object... sources) {
this.sources.addAll(new LinkedHashSet<>(Arrays.asList(sources)));
return this;
}
/** /**
* Add more sources (configuration classes and components) to this application. * Add more sources (configuration classes and components) to this application.
* @param sources the sources to add * @param sources the sources to add
* @return the current builder * @return the current builder
*/ */
public SpringApplicationBuilder sources(Class<?>... sources) { public SpringApplicationBuilder sources(Class<?>... sources) {
this.sources.addAll(new LinkedHashSet<Object>(Arrays.asList(sources))); this.sources.addAll(new LinkedHashSet<>(Arrays.asList(sources)));
return this; return this;
} }
......
...@@ -47,7 +47,7 @@ import org.springframework.web.context.WebApplicationContext; ...@@ -47,7 +47,7 @@ import org.springframework.web.context.WebApplicationContext;
* <p> * <p>
* To configure the application either override the * To configure the application either override the
* {@link #configure(SpringApplicationBuilder)} method (calling * {@link #configure(SpringApplicationBuilder)} method (calling
* {@link SpringApplicationBuilder#sources(Object...)}) or make the initializer itself a * {@link SpringApplicationBuilder#sources(Class...)}) or make the initializer itself a
* {@code @Configuration}. If you are using {@link SpringBootServletInitializer} in * {@code @Configuration}. If you are using {@link SpringBootServletInitializer} in
* combination with other {@link WebApplicationInitializer WebApplicationInitializers} you * combination with other {@link WebApplicationInitializer WebApplicationInitializers} you
* might also want to add an {@code @Ordered} annotation to configure a specific startup * might also want to add an {@code @Ordered} annotation to configure a specific startup
...@@ -126,7 +126,8 @@ public abstract class SpringBootServletInitializer implements WebApplicationInit ...@@ -126,7 +126,8 @@ public abstract class SpringBootServletInitializer implements WebApplicationInit
+ "configure method or add an @Configuration annotation"); + "configure method or add an @Configuration annotation");
// Ensure error pages are registered // Ensure error pages are registered
if (this.registerErrorPageFilter) { if (this.registerErrorPageFilter) {
application.getSources().add(ErrorPageFilterConfiguration.class); application.addPrimarySources(
Collections.singleton(ErrorPageFilterConfiguration.class));
} }
return run(application); return run(application);
} }
......
...@@ -46,7 +46,7 @@ public class OverrideSourcesTests { ...@@ -46,7 +46,7 @@ public class OverrideSourcesTests {
@Test @Test
public void beanInjectedToMainConfiguration() { public void beanInjectedToMainConfiguration() {
this.context = SpringApplication.run(new Object[] { MainConfiguration.class }, this.context = SpringApplication.run(new Class<?>[] { MainConfiguration.class },
new String[] { "--spring.main.web_environment=false" }); new String[] { "--spring.main.web_environment=false" });
assertThat(this.context.getBean(Service.class).bean.name).isEqualTo("foo"); assertThat(this.context.getBean(Service.class).bean.name).isEqualTo("foo");
} }
...@@ -54,7 +54,7 @@ public class OverrideSourcesTests { ...@@ -54,7 +54,7 @@ public class OverrideSourcesTests {
@Test @Test
public void primaryBeanInjectedProvingSourcesNotOverridden() { public void primaryBeanInjectedProvingSourcesNotOverridden() {
this.context = SpringApplication.run( this.context = SpringApplication.run(
new Object[] { MainConfiguration.class, TestConfiguration.class }, new Class<?>[] { MainConfiguration.class, TestConfiguration.class },
new String[] { "--spring.main.web_environment=false", new String[] { "--spring.main.web_environment=false",
"--spring.main.sources=org.springframework.boot.OverrideSourcesTests.MainConfiguration" }); "--spring.main.sources=org.springframework.boot.OverrideSourcesTests.MainConfiguration" });
assertThat(this.context.getBean(Service.class).bean.name).isEqualTo("bar"); assertThat(this.context.getBean(Service.class).bean.name).isEqualTo("bar");
......
...@@ -160,7 +160,7 @@ public class SpringApplicationTests { ...@@ -160,7 +160,7 @@ public class SpringApplicationTests {
public void sourcesMustNotBeNull() throws Exception { public void sourcesMustNotBeNull() throws Exception {
this.thrown.expect(IllegalArgumentException.class); this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("PrimarySources must not be null"); this.thrown.expectMessage("PrimarySources must not be null");
new SpringApplication((Object[]) null).run(); new SpringApplication((Class<?>[]) null).run();
} }
@Test @Test
...@@ -576,20 +576,22 @@ public class SpringApplicationTests { ...@@ -576,20 +576,22 @@ public class SpringApplicationTests {
@Test @Test
public void loadSources() throws Exception { public void loadSources() throws Exception {
Object[] sources = { ExampleConfig.class, "a", TestCommandLineRunner.class }; Class<?>[] sources = { ExampleConfig.class, TestCommandLineRunner.class };
TestSpringApplication application = new TestSpringApplication(sources); TestSpringApplication application = new TestSpringApplication(sources);
application.getSources().add("a");
application.setWebApplicationType(WebApplicationType.NONE); application.setWebApplicationType(WebApplicationType.NONE);
application.setUseMockLoader(true); application.setUseMockLoader(true);
this.context = application.run(); this.context = application.run();
Set<Object> allSources = application.getAllSources(); Set<Object> allSources = application.getAllSources();
assertThat(allSources.toArray()).isEqualTo(sources); assertThat(allSources).contains(ExampleConfig.class, TestCommandLineRunner.class,
"a");
} }
@Test @Test
public void wildcardSources() { public void wildcardSources() {
Object[] sources = { TestSpringApplication application = new TestSpringApplication();
"classpath:org/springframework/boot/sample-${sample.app.test.prop}.xml" }; application.getSources().add(
TestSpringApplication application = new TestSpringApplication(sources); "classpath:org/springframework/boot/sample-${sample.app.test.prop}.xml");
application.setWebApplicationType(WebApplicationType.NONE); application.setWebApplicationType(WebApplicationType.NONE);
this.context = application.run(); this.context = application.run();
} }
...@@ -603,7 +605,7 @@ public class SpringApplicationTests { ...@@ -603,7 +605,7 @@ public class SpringApplicationTests {
@Test @Test
public void runComponents() throws Exception { public void runComponents() throws Exception {
this.context = SpringApplication.run( this.context = SpringApplication.run(
new Object[] { ExampleWebConfig.class, Object.class }, new String[0]); new Class<?>[] { ExampleWebConfig.class, Object.class }, new String[0]);
assertThat(this.context).isNotNull(); assertThat(this.context).isNotNull();
} }
...@@ -970,12 +972,12 @@ public class SpringApplicationTests { ...@@ -970,12 +972,12 @@ public class SpringApplicationTests {
private Banner.Mode bannerMode; private Banner.Mode bannerMode;
TestSpringApplication(Object... sources) { TestSpringApplication(Class<?>... primarySources) {
super(sources); super(primarySources);
} }
TestSpringApplication(ResourceLoader resourceLoader, Object... sources) { TestSpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
super(resourceLoader, sources); super(resourceLoader, primarySources);
} }
public void setUseMockLoader(boolean useMockLoader) { public void setUseMockLoader(boolean useMockLoader) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment