Publish ExitCodeEvent when possible

Update SpringApplication to publish an ExitCodeEvent when a valid exit
code is known.

Fixes gh-4804
pull/4947/head
Phillip Webb 9 years ago
parent 7397dbaf57
commit a20cd2de02

@ -0,0 +1,50 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot;
import org.springframework.context.ApplicationEvent;
/**
* Event fired when an application exit code has been determined from an
* {@link ExitCodeGenerator}.
*
* @author Phillip Webb
* @since 1.3.2
*/
public class ExitCodeEvent extends ApplicationEvent {
private final int exitCode;
/**
* Create a new {@link ExitCodeEvent} instance.
* @param source the source of the event
* @param exitCode the exit code
*/
public ExitCodeEvent(Object source, int exitCode) {
super(source);
this.exitCode = exitCode;
}
/**
* Return the exit code that will be used to exit the JVM.
* @return the the exit code
*/
public int getExitCode() {
return this.exitCode;
}
}

@ -302,7 +302,11 @@ public class SpringApplication {
SpringApplicationRunListeners listeners = getRunListeners(args); SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.started(); listeners.started();
try { try {
context = doRun(listeners, args); ApplicationArguments applicationArguments = new DefaultApplicationArguments(
args);
context = createAndRefreshContext(listeners, applicationArguments);
afterRefresh(context, applicationArguments);
listeners.finished(context, null);
stopWatch.stop(); stopWatch.stop();
if (this.logStartupInfo) { if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass) new StartupInfoLogger(this.mainApplicationClass)
@ -316,12 +320,13 @@ public class SpringApplication {
} }
} }
private ConfigurableApplicationContext doRun(SpringApplicationRunListeners listeners, private ConfigurableApplicationContext createAndRefreshContext(
String... args) { SpringApplicationRunListeners listeners,
ApplicationArguments applicationArguments) {
ConfigurableApplicationContext context; ConfigurableApplicationContext context;
// Create and configure the environment // Create and configure the environment
ConfigurableEnvironment environment = getOrCreateEnvironment(); ConfigurableEnvironment environment = getOrCreateEnvironment();
configureEnvironment(environment, args); configureEnvironment(environment, applicationArguments.getSourceArgs());
listeners.environmentPrepared(environment); listeners.environmentPrepared(environment);
if (isWebEnvironment(environment) && !this.webEnvironment) { if (isWebEnvironment(environment) && !this.webEnvironment) {
environment = convertToStandardEnvironment(environment); environment = convertToStandardEnvironment(environment);
@ -343,7 +348,6 @@ public class SpringApplication {
} }
// Add boot specific singleton beans // Add boot specific singleton beans
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
context.getBeanFactory().registerSingleton("springApplicationArguments", context.getBeanFactory().registerSingleton("springApplicationArguments",
applicationArguments); applicationArguments);
@ -363,8 +367,6 @@ public class SpringApplication {
// Not allowed in some environments. // Not allowed in some environments.
} }
} }
afterRefresh(context, applicationArguments);
listeners.finished(context, null);
return context; return context;
} }
@ -858,6 +860,9 @@ public class SpringApplication {
Throwable exception) { Throwable exception) {
int exitCode = getExitCodeFromException(exception); int exitCode = getExitCodeFromException(exception);
if (exitCode != 0) { if (exitCode != 0) {
if (context != null) {
context.publishEvent(new ExitCodeEvent(context, exitCode));
}
SpringBootExceptionHandler handler = getSpringBootExceptionHandler(); SpringBootExceptionHandler handler = getSpringBootExceptionHandler();
if (handler != null) { if (handler != null) {
handler.registerExitCode(exitCode); handler.registerExitCode(exitCode);
@ -1186,6 +1191,7 @@ public class SpringApplication {
*/ */
public static int exit(ApplicationContext context, public static int exit(ApplicationContext context,
ExitCodeGenerator... exitCodeGenerators) { ExitCodeGenerator... exitCodeGenerators) {
Assert.notNull(context, "Context must not be null");
int exitCode = 0; int exitCode = 0;
try { try {
try { try {
@ -1195,6 +1201,9 @@ public class SpringApplication {
generators.addAll(exitCodeGenerators); generators.addAll(exitCodeGenerators);
generators.addAll(beans); generators.addAll(beans);
exitCode = generators.getExitCode(); exitCode = generators.getExitCode();
if (exitCode != 0) {
context.publishEvent(new ExitCodeEvent(context, exitCode));
}
} }
finally { finally {
close(context); close(context);

@ -549,6 +549,8 @@ public class SpringApplicationTests {
@Test @Test
public void exitWithExplicitCode() throws Exception { public void exitWithExplicitCode() throws Exception {
SpringApplication application = new SpringApplication(ExampleConfig.class); SpringApplication application = new SpringApplication(ExampleConfig.class);
ExitCodeListener listener = new ExitCodeListener();
application.addListeners(listener);
application.setWebEnvironment(false); application.setWebEnvironment(false);
this.context = application.run(); this.context = application.run();
assertNotNull(this.context); assertNotNull(this.context);
@ -560,6 +562,7 @@ public class SpringApplicationTests {
} }
})); }));
assertThat(listener.getExitCode(), equalTo(2));
} }
@Test @Test
@ -574,6 +577,8 @@ public class SpringApplicationTests {
} }
}; };
ExitCodeListener listener = new ExitCodeListener();
application.addListeners(listener);
application.setWebEnvironment(false); application.setWebEnvironment(false);
try { try {
application.run(); application.run();
@ -582,6 +587,7 @@ public class SpringApplicationTests {
catch (IllegalStateException ex) { catch (IllegalStateException ex) {
} }
verify(handler).registerExitCode(11); verify(handler).registerExitCode(11);
assertThat(listener.getExitCode(), equalTo(11));
} }
@Test @Test
@ -982,4 +988,18 @@ public class SpringApplicationTests {
} }
private static class ExitCodeListener implements ApplicationListener<ExitCodeEvent> {
private int exitCode;
@Override
public void onApplicationEvent(ExitCodeEvent event) {
this.exitCode = event.getExitCode();
}
public int getExitCode() {
return this.exitCode;
}
}
} }

Loading…
Cancel
Save