From ee3d4b34a0b232cb5f72f900462594ad9c70998a Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Mon, 12 Oct 2015 12:29:31 +0100 Subject: [PATCH] Consider parent when application is built and then run Previously, the parent context was only considered when the builder was used to run the application. If the application was built using the builder and then run using SpringApplication.run, the parent context was not considered. This commit updates the builder to consider the parent both when it's used to run the application and when it's used to build the application that will later be run via SpringApplication.run Closes gh-4014 --- .../builder/SpringApplicationBuilder.java | 29 ++++++++++++------- .../SpringApplicationBuilderTests.java | 14 ++++++++- 2 files changed, 31 insertions(+), 12 deletions(-) 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 59b7ecfa235..481214670c7 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * Copyright 2012-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -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; } @@ -405,7 +412,7 @@ public class SpringApplicationBuilder { /** * Default properties for the environment. Multiple calls to this method are * cumulative. - * @param defaults + * @param defaults the default properties * @return the current builder * @see SpringApplicationBuilder#properties(String...) */ 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 7d91196bc49..47b1d4c3a02 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(