Support SpringApplicationBuilder with bound sources

Update `SpringApplicationBuilder` so that the `sources(...)` method
updates the primary sources. Prior to this commit, the fix for #8910
had the unfortunate side effect of stopping the
`SpringApplicationBuilder` from being used with
`spring.application.main` properties.

Fixes gh-9053
pull/9050/merge
Phillip Webb 8 years ago
parent 5ae1798ec5
commit 00c67f1962

@ -70,6 +70,7 @@ import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.SpringFactoriesLoader;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StopWatch;
@ -213,9 +214,9 @@ public class SpringApplication {
private static final Log logger = LogFactory.getLog(SpringApplication.class);
private final Object[] primarySources;
private Set<Object> primarySources;
private Set<Object> additionalSources = new LinkedHashSet<>();
private Set<Object> sources = new LinkedHashSet<>();
private Class<?> mainApplicationClass;
@ -261,7 +262,6 @@ public class SpringApplication {
*/
public SpringApplication(Object... primarySources) {
initialize(primarySources);
this.primarySources = primarySources;
}
/**
@ -277,12 +277,13 @@ public class SpringApplication {
*/
public SpringApplication(ResourceLoader resourceLoader, Object... primarySources) {
this.resourceLoader = resourceLoader;
this.primarySources = primarySources;
initialize(primarySources);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private void initialize(Object[] sources) {
private void initialize(Object[] primarySources) {
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
this.webApplicationType = deduceWebApplication();
setInitializers((Collection) getSpringFactoriesInstances(
ApplicationContextInitializer.class));
@ -1122,18 +1123,35 @@ public class SpringApplication {
this.environment = environment;
}
/**
* Add additional items to the primary sources that will be added to an
* ApplicationContext when {@link #run(String...)} is called.
* <p>
* The sources here are added to those that were set in the constructor. Most users
* should consider using {@link #getSources()}/{@link #setSources(Set)} rather than
* this calling method.
* @param additionalPrimarySources the additional primary sources to add
* @see #SpringApplication(Object...)
* @see #getSources()
* @see #setSources(Set)
* @see #getAllSources()
*/
public void addPrimarySources(Collection<Object> additionalPrimarySources) {
this.primarySources.addAll(additionalPrimarySources);
}
/**
* Returns a mutable set of the sources that will be added to an ApplicationContext
* when {@link #run(String...)} is called.
* <p>
* Sources set here will be used in addition to any primary sources set in the
* constructor.
* @return the sources the application sources.
* @return the application sources.
* @see #SpringApplication(Object...)
* @see #getAllSources()
*/
public Set<Object> getSources() {
return this.additionalSources;
return this.sources;
}
/**
@ -1142,13 +1160,13 @@ public class SpringApplication {
* <p>
* Sources set here will be used in addition to any primary sources set in the
* constructor.
* @param sources the sources to set
* @param sources the application sources to set
* @see #SpringApplication(Object...)
* @see #getAllSources()
*/
public void setSources(Set<Object> sources) {
Assert.notNull(sources, "Sources must not be null");
this.additionalSources = new LinkedHashSet<>(sources);
this.sources = new LinkedHashSet<>(sources);
}
/**
@ -1160,10 +1178,12 @@ public class SpringApplication {
*/
public Set<Object> getAllSources() {
Set<Object> allSources = new LinkedHashSet<>();
if (!ObjectUtils.isEmpty(this.primarySources)) {
allSources.addAll(Arrays.asList(this.primarySources));
if (!CollectionUtils.isEmpty(this.primarySources)) {
allSources.addAll(this.primarySources);
}
if (!CollectionUtils.isEmpty(this.sources)) {
allSources.addAll(this.sources);
}
allSources.addAll(this.additionalSources);
return Collections.unmodifiableSet(allSources);
}

@ -61,6 +61,7 @@ import org.springframework.core.io.ResourceLoader;
*
* @author Dave Syer
* @author Andy Wilkinson
* @see SpringApplication
*/
public class SpringApplicationBuilder {
@ -165,7 +166,7 @@ public class SpringApplicationBuilder {
*/
public SpringApplication build(String... args) {
configureAsChildIfNecessary(args);
this.application.setSources(this.sources);
this.application.addPrimarySources(this.sources);
return this.application;
}
@ -193,7 +194,7 @@ public class SpringApplicationBuilder {
bannerMode(Banner.Mode.OFF);
// Make sure sources get copied over
this.application.setSources(this.sources);
this.application.addPrimarySources(this.sources);
return child;
}

@ -16,6 +16,8 @@
package org.springframework.boot.web.servlet.support;
import java.util.Collections;
import javax.servlet.Filter;
import javax.servlet.Servlet;
import javax.servlet.ServletContext;
@ -115,11 +117,11 @@ public abstract class SpringBootServletInitializer implements WebApplicationInit
builder.contextClass(AnnotationConfigServletWebServerApplicationContext.class);
builder = configure(builder);
SpringApplication application = builder.build();
if (application.getSources().isEmpty() && AnnotationUtils
if (application.getAllSources().isEmpty() && AnnotationUtils
.findAnnotation(getClass(), Configuration.class) != null) {
application.getSources().add(getClass());
application.addPrimarySources(Collections.singleton(getClass()));
}
Assert.state(!application.getSources().isEmpty(),
Assert.state(!application.getAllSources().isEmpty(),
"No SpringApplication sources have been defined. Either override the "
+ "configure method or add an @Configuration annotation");
// Ensure error pages are registered

@ -157,7 +157,7 @@ public class SpringApplicationTests {
@Test
public void sourcesMustNotBeNull() throws Exception {
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("Sources must not be empty");
this.thrown.expectMessage("PrimarySources must not be null");
new SpringApplication((Object[]) null).run();
}

@ -304,6 +304,16 @@ public class SpringApplicationBuilderTests {
assertThat(application.application().getInitializers()).hasSize(5);
}
@Test
public void sourcesWithBoundSources() throws Exception {
SpringApplicationBuilder application = new SpringApplicationBuilder()
.web(WebApplicationType.NONE).sources(ExampleConfig.class)
.properties("spring.main.sources=" + ChildConfig.class.getName());
this.context = application.run();
this.context.getBean(ExampleConfig.class);
this.context.getBean(ChildConfig.class);
}
@Configuration
static class ExampleConfig {

@ -66,14 +66,14 @@ public class SpringBootServletInitializerTests {
public void withConfigurationAnnotation() throws Exception {
new WithConfigurationAnnotation()
.createRootApplicationContext(this.servletContext);
assertThat(this.application.getSources()).containsOnly(
assertThat(this.application.getAllSources()).containsOnly(
WithConfigurationAnnotation.class, ErrorPageFilterConfiguration.class);
}
@Test
public void withConfiguredSource() throws Exception {
new WithConfiguredSource().createRootApplicationContext(this.servletContext);
assertThat(this.application.getSources()).containsOnly(Config.class,
assertThat(this.application.getAllSources()).containsOnly(Config.class,
ErrorPageFilterConfiguration.class);
}

Loading…
Cancel
Save