Allow step action to be optional
Update `SpringApplicationRunListeners` so that the step action is optional and does not need to call `end()`. This commit also introduces a test for the failure case showing that there is a missed call to end with the initial solution. See gh-22845
This commit is contained in:
committed by
Phillip Webb
parent
ac357283a6
commit
0e5be0ab62
@@ -103,7 +103,8 @@ class SpringApplicationRunListeners {
|
||||
}
|
||||
|
||||
private void doWithListeners(String stepName, Consumer<SpringApplicationRunListener> listenerAction) {
|
||||
doWithListeners(stepName, listenerAction, StartupStep::end);
|
||||
doWithListeners(stepName, listenerAction, (step) -> {
|
||||
});
|
||||
}
|
||||
|
||||
private void doWithListeners(String stepName, Consumer<SpringApplicationRunListener> listenerAction,
|
||||
@@ -111,6 +112,7 @@ class SpringApplicationRunListeners {
|
||||
StartupStep step = this.applicationStartup.start(stepName);
|
||||
this.listeners.forEach(listenerAction);
|
||||
stepAction.accept(step);
|
||||
step.end();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -141,6 +141,7 @@ import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
* @author Madhura Bhave
|
||||
* @author Brian Clozel
|
||||
* @author Artsiom Yudovin
|
||||
* @author Marten Deinum
|
||||
*/
|
||||
@ExtendWith(OutputCaptureExtension.class)
|
||||
class SpringApplicationTests {
|
||||
@@ -1179,6 +1180,29 @@ class SpringApplicationTests {
|
||||
assertThat(startCount).isEqualTo(endCount);
|
||||
}
|
||||
|
||||
@Test
|
||||
void customApplicationStartupPublishStartupStepsWithFailure() {
|
||||
ApplicationStartup applicationStartup = mock(ApplicationStartup.class);
|
||||
StartupStep startupStep = mock(StartupStep.class);
|
||||
given(applicationStartup.start(anyString())).willReturn(startupStep);
|
||||
given(startupStep.tag(anyString(), anyString())).willReturn(startupStep);
|
||||
given(startupStep.tag(anyString(), ArgumentMatchers.<Supplier<String>>any())).willReturn(startupStep);
|
||||
SpringApplication application = new SpringApplication(BrokenPostConstructConfig.class);
|
||||
application.setWebApplicationType(WebApplicationType.NONE);
|
||||
application.setApplicationStartup(applicationStartup);
|
||||
assertThatExceptionOfType(BeanCreationException.class).isThrownBy(application::run);
|
||||
|
||||
verify(applicationStartup).start("spring.boot.application.starting");
|
||||
verify(applicationStartup).start("spring.boot.application.environment-prepared");
|
||||
verify(applicationStartup).start("spring.boot.application.failed");
|
||||
|
||||
long startCount = mockingDetails(applicationStartup).getInvocations().stream()
|
||||
.filter((invocation) -> invocation.getMethod().toString().contains("start(")).count();
|
||||
long endCount = mockingDetails(startupStep).getInvocations().stream()
|
||||
.filter((invocation) -> invocation.getMethod().toString().contains("end(")).count();
|
||||
assertThat(startCount).isEqualTo(endCount);
|
||||
}
|
||||
|
||||
private <S extends AvailabilityState> ArgumentMatcher<ApplicationEvent> isAvailabilityChangeEventWithState(
|
||||
S state) {
|
||||
return (argument) -> (argument instanceof AvailabilityChangeEvent<?>)
|
||||
|
||||
Reference in New Issue
Block a user