diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java index e289906d4a6..671e240c35d 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java @@ -332,6 +332,7 @@ public class SpringApplication { new StartupInfoLogger(this.mainApplicationClass) .logStarted(getApplicationLog(), stopWatch); } + callRunners(context, applicationArguments); return context; } catch (Throwable ex) { @@ -757,7 +758,6 @@ public class SpringApplication { */ protected void afterRefresh(ConfigurableApplicationContext context, ApplicationArguments args) { - callRunners(context, args); } private void callRunners(ApplicationContext context, ApplicationArguments args) { diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/SpringApplicationTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/SpringApplicationTests.java index f49334c6550..6d4b5913cd2 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/SpringApplicationTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/SpringApplicationTests.java @@ -38,6 +38,9 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.mockito.ArgumentCaptor; +import org.mockito.ArgumentMatchers; +import org.mockito.InOrder; +import org.mockito.Mockito; import reactor.core.publisher.Mono; import org.springframework.beans.BeansException; @@ -582,6 +585,33 @@ public class SpringApplicationTests { assertThat(this.context).has(runTestRunnerBean("runnerC")); } + @Test + @SuppressWarnings("unchecked") + public void runnersAreCalledAfterApplicationReadyEventIsPublished() throws Exception { + SpringApplication application = new SpringApplication( + MockRunnerConfiguration.class); + application.setWebApplicationType(WebApplicationType.NONE); + ApplicationListener eventListener = mock( + ApplicationListener.class); + application.addListeners(eventListener); + this.context = application.run(); + ApplicationRunner applicationRunner = this.context + .getBean(ApplicationRunner.class); + CommandLineRunner commandLineRunner = this.context + .getBean(CommandLineRunner.class); + InOrder applicationRunnerOrder = Mockito.inOrder(eventListener, + applicationRunner); + applicationRunnerOrder.verify(eventListener) + .onApplicationEvent(ArgumentMatchers.any(ApplicationReadyEvent.class)); + applicationRunnerOrder.verify(applicationRunner) + .run(ArgumentMatchers.any(ApplicationArguments.class)); + InOrder commandLineRunnerOrder = Mockito.inOrder(eventListener, + commandLineRunner); + commandLineRunnerOrder.verify(eventListener) + .onApplicationEvent(ArgumentMatchers.any(ApplicationReadyEvent.class)); + commandLineRunnerOrder.verify(commandLineRunner).run(); + } + @Test public void loadSources() throws Exception { Class[] sources = { ExampleConfig.class, TestCommandLineRunner.class }; @@ -1217,6 +1247,21 @@ public class SpringApplicationTests { } + @Configuration + static class MockRunnerConfiguration { + + @Bean + public CommandLineRunner commandLineRunner() { + return mock(CommandLineRunner.class); + } + + @Bean + public ApplicationRunner applicationRunner() { + return mock(ApplicationRunner.class); + } + + } + static class ExitStatusException extends RuntimeException implements ExitCodeGenerator {