diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/builder/SpringApplicationBuilder.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/builder/SpringApplicationBuilder.java index a4893ff516..4a73981658 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/builder/SpringApplicationBuilder.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/builder/SpringApplicationBuilder.java @@ -94,21 +94,40 @@ public class SpringApplicationBuilder { private boolean configuredAsChild = false; public SpringApplicationBuilder(Class... sources) { - this.application = createSpringApplication(sources); + this(null, sources); + } + + public SpringApplicationBuilder(ResourceLoader resourceLoader, Class... sources) { + this.application = createSpringApplication(resourceLoader, sources); } /** - * Creates a new {@link org.springframework.boot.SpringApplication} instances from the - * given sources. Subclasses may override in order to provide a custom subclass of - * {@link org.springframework.boot.SpringApplication} + * Creates a new {@link SpringApplication} instance from the given sources. Subclasses + * may override in order to provide a custom subclass of {@link SpringApplication} * @param sources the sources - * @return the {@link org.springframework.boot.SpringApplication} instance + * @return the {@link SpringApplication} instance * @since 1.1.0 + * @deprecated since 2.6.0 for removal in 2.8.0 in favor of + * {@link #createSpringApplication(ResourceLoader, Class...)} */ + @Deprecated protected SpringApplication createSpringApplication(Class... sources) { return new SpringApplication(sources); } + /** + * Creates a new {@link SpringApplication} instances from the given sources using the + * given {@link ResourceLoader}. Subclasses may override in order to provide a custom + * subclass of {@link SpringApplication} + * @param resourceLoader the resource loader (can be null) + * @param sources the sources + * @return the {@link SpringApplication} instance + * @since 2.6.0 + */ + protected SpringApplication createSpringApplication(ResourceLoader resourceLoader, Class... sources) { + return new SpringApplication(resourceLoader, sources); + } + /** * Accessor for the current application context. * @return the current application context (or null if not yet running) diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/builder/SpringApplicationBuilderTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/builder/SpringApplicationBuilderTests.java index c571779449..25f0f369b3 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/builder/SpringApplicationBuilderTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/builder/SpringApplicationBuilderTests.java @@ -20,11 +20,13 @@ import java.net.URL; import java.net.URLClassLoader; import java.util.Collections; +import org.assertj.core.api.InstanceOfAssertFactories; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationContextFactory; +import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplicationShutdownHookInstance; import org.springframework.boot.WebApplicationType; import org.springframework.context.ApplicationContext; @@ -41,6 +43,7 @@ import org.springframework.util.StringUtils; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; @@ -309,6 +312,22 @@ class SpringApplicationBuilderTests { assertThat(builder.application().getEnvironmentPrefix()).isEqualTo("test"); } + @Test + void customApplicationWithResourceLoader() { + ResourceLoader resourceLoader = mock(ResourceLoader.class); + SpringApplicationBuilder applicationBuilder = new SpringApplicationBuilder(resourceLoader, + ExampleConfig.class) { + @Override + protected SpringApplication createSpringApplication(ResourceLoader resourceLoader, Class... sources) { + return new CustomSpringApplication(resourceLoader, sources); + } + }; + SpringApplication application = applicationBuilder.build(); + assertThat(application).isInstanceOf(CustomSpringApplication.class) + .asInstanceOf(InstanceOfAssertFactories.type(CustomSpringApplication.class)) + .satisfies((customApp) -> assertThat(customApp.resourceLoader).isEqualTo(resourceLoader)); + } + @Configuration(proxyBeanMethods = false) static class ExampleConfig { @@ -319,6 +338,17 @@ class SpringApplicationBuilderTests { } + static class CustomSpringApplication extends SpringApplication { + + private final ResourceLoader resourceLoader; + + CustomSpringApplication(ResourceLoader resourceLoader, Class... primarySources) { + super(resourceLoader, primarySources); + this.resourceLoader = resourceLoader; + } + + } + static class SpyApplicationContext extends AnnotationConfigApplicationContext { private final ConfigurableApplicationContext applicationContext = spy(new AnnotationConfigApplicationContext());