diff --git a/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java b/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java index 4a8e28c3a9..f1709cb5b2 100644 --- a/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java +++ b/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java @@ -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 primarySources; - private Set additionalSources = new LinkedHashSet<>(); + private Set 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. + *

+ * 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 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. *

* 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 getSources() { - return this.additionalSources; + return this.sources; } /** @@ -1142,13 +1160,13 @@ public class SpringApplication { *

* 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 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 getAllSources() { Set 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); } diff --git a/spring-boot/src/main/java/org/springframework/boot/builder/SpringApplicationBuilder.java b/spring-boot/src/main/java/org/springframework/boot/builder/SpringApplicationBuilder.java index e31086c81d..da65d8f071 100644 --- a/spring-boot/src/main/java/org/springframework/boot/builder/SpringApplicationBuilder.java +++ b/spring-boot/src/main/java/org/springframework/boot/builder/SpringApplicationBuilder.java @@ -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; } diff --git a/spring-boot/src/main/java/org/springframework/boot/web/servlet/support/SpringBootServletInitializer.java b/spring-boot/src/main/java/org/springframework/boot/web/servlet/support/SpringBootServletInitializer.java index 940aa197e7..a51b053e5e 100644 --- a/spring-boot/src/main/java/org/springframework/boot/web/servlet/support/SpringBootServletInitializer.java +++ b/spring-boot/src/main/java/org/springframework/boot/web/servlet/support/SpringBootServletInitializer.java @@ -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 diff --git a/spring-boot/src/test/java/org/springframework/boot/SpringApplicationTests.java b/spring-boot/src/test/java/org/springframework/boot/SpringApplicationTests.java index fc66965f9e..7655e4a6ff 100644 --- a/spring-boot/src/test/java/org/springframework/boot/SpringApplicationTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/SpringApplicationTests.java @@ -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(); } diff --git a/spring-boot/src/test/java/org/springframework/boot/builder/SpringApplicationBuilderTests.java b/spring-boot/src/test/java/org/springframework/boot/builder/SpringApplicationBuilderTests.java index 37f52fe72d..ae8fa65f9c 100644 --- a/spring-boot/src/test/java/org/springframework/boot/builder/SpringApplicationBuilderTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/builder/SpringApplicationBuilderTests.java @@ -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 { diff --git a/spring-boot/src/test/java/org/springframework/boot/web/servlet/support/SpringBootServletInitializerTests.java b/spring-boot/src/test/java/org/springframework/boot/web/servlet/support/SpringBootServletInitializerTests.java index 4685a1b86b..016a12d829 100644 --- a/spring-boot/src/test/java/org/springframework/boot/web/servlet/support/SpringBootServletInitializerTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/web/servlet/support/SpringBootServletInitializerTests.java @@ -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); }