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 005eda5d3c..e0e0728e50 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 @@ -59,6 +59,7 @@ import org.springframework.core.io.ResourceLoader; * SpringApplication instead. * * @author Dave Syer + * @author Andy Wilkinson */ public class SpringApplicationBuilder { @@ -80,6 +81,8 @@ public class SpringApplicationBuilder { private boolean registerShutdownHookApplied; + private boolean configuredAsChild = false; + public SpringApplicationBuilder(Object... sources) { this.application = createSpringApplication(sources); } @@ -120,19 +123,11 @@ public class SpringApplicationBuilder { * @return an application context created from the current state */ public ConfigurableApplicationContext run(String... args) { - if (this.parent != null) { - // If there is a parent don't register a shutdown hook - if (!this.registerShutdownHookApplied) { - this.application.setRegisterShutdownHook(false); - } - // initialize it and make sure it is added to the current context - initializers(new ParentContextApplicationContextInitializer( - this.parent.run(args))); - } if (this.running.get()) { // If already created we just return the existing context return this.context; } + configureAsChildIfNecessary(); if (this.running.compareAndSet(false, true)) { synchronized (this.running) { // If not already running copy the sources over and then run. @@ -142,11 +137,23 @@ public class SpringApplicationBuilder { return this.context; } + private void configureAsChildIfNecessary() { + if (this.parent != null && !this.configuredAsChild) { + this.configuredAsChild = true; + if (!this.registerShutdownHookApplied) { + this.application.setRegisterShutdownHook(false); + } + initializers( + new ParentContextApplicationContextInitializer(this.parent.run())); + } + } + /** * Returns a fully configured {@link SpringApplication} that is ready to run. * @return the fully configured {@link SpringApplication}. */ public SpringApplication build() { + configureAsChildIfNecessary(); this.application.setSources(this.sources); return this.application; } 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 e2c96191b7..e711d7ec51 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 @@ -98,7 +98,7 @@ public class SpringApplicationBuilderTests { } @Test - public void parentContextCreation() throws Exception { + public void parentContextCreationThatIsRunDirectly() throws Exception { SpringApplicationBuilder application = new SpringApplicationBuilder( ChildConfig.class).contextClass(SpyApplicationContext.class); application.parent(ExampleConfig.class); @@ -109,6 +109,18 @@ public class SpringApplicationBuilderTests { equalTo(false)); } + @Test + public void parentContextCreationThatIsBuiltThenRun() throws Exception { + SpringApplicationBuilder application = new SpringApplicationBuilder( + ChildConfig.class).contextClass(SpyApplicationContext.class); + application.parent(ExampleConfig.class); + this.context = application.build().run(); + verify(((SpyApplicationContext) this.context).getApplicationContext()) + .setParent(any(ApplicationContext.class)); + assertThat(((SpyApplicationContext) this.context).getRegisteredShutdownHook(), + equalTo(false)); + } + @Test public void parentContextCreationWithChildShutdown() throws Exception { SpringApplicationBuilder application = new SpringApplicationBuilder(