Make context available when handling refresh failure
Previously, if SpringApplication.run failed due to the refresh of the application context throwing an exception, the application context would not be available during run failure handling. This meant that null was passed to any SpringApplicationRunListeners, however the javadoc for the finished method does not indicate that it is possible for null to be passed in. In addition to the possibility of a NullPointerException, a side-effect of this behaviour was that the auto-configuration report was not produced when refresh fails, making it useless as a tool for diagnosing refresh failures. This commit updates SpringApplication to take a reference to the application context as early as possible and, crucially, before it has been refreshed. This means that refresh no longer has to succeed for the context to be passed to any SpringApplicationRunListeners and that they will now receive an inactive context, rather than a null context in the event of a refresh failure. Closes gh-5325
This commit is contained in:
parent
427d3140b3
commit
474aed0541
|
@ -305,7 +305,14 @@ public class SpringApplication {
|
|||
try {
|
||||
ApplicationArguments applicationArguments = new DefaultApplicationArguments(
|
||||
args);
|
||||
context = createAndRefreshContext(listeners, applicationArguments);
|
||||
ConfigurableEnvironment environment = prepareEnvironment(listeners,
|
||||
applicationArguments);
|
||||
if (this.bannerMode != Banner.Mode.OFF) {
|
||||
printBanner(environment);
|
||||
}
|
||||
context = createApplicationContext();
|
||||
prepareContext(context, environment, listeners, applicationArguments);
|
||||
refreshContext(context);
|
||||
afterRefresh(context, applicationArguments);
|
||||
listeners.finished(context, null);
|
||||
stopWatch.stop();
|
||||
|
@ -321,10 +328,9 @@ public class SpringApplication {
|
|||
}
|
||||
}
|
||||
|
||||
private ConfigurableApplicationContext createAndRefreshContext(
|
||||
private ConfigurableEnvironment prepareEnvironment(
|
||||
SpringApplicationRunListeners listeners,
|
||||
ApplicationArguments applicationArguments) {
|
||||
ConfigurableApplicationContext context;
|
||||
// Create and configure the environment
|
||||
ConfigurableEnvironment environment = getOrCreateEnvironment();
|
||||
configureEnvironment(environment, applicationArguments.getSourceArgs());
|
||||
|
@ -332,13 +338,12 @@ public class SpringApplication {
|
|||
if (isWebEnvironment(environment) && !this.webEnvironment) {
|
||||
environment = convertToStandardEnvironment(environment);
|
||||
}
|
||||
return environment;
|
||||
}
|
||||
|
||||
if (this.bannerMode != Banner.Mode.OFF) {
|
||||
printBanner(environment);
|
||||
}
|
||||
|
||||
// Create, load, refresh and run the ApplicationContext
|
||||
context = createApplicationContext();
|
||||
private void prepareContext(ConfigurableApplicationContext context,
|
||||
ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
|
||||
ApplicationArguments applicationArguments) {
|
||||
context.setEnvironment(environment);
|
||||
postProcessApplicationContext(context);
|
||||
applyInitializers(context);
|
||||
|
@ -357,8 +362,9 @@ public class SpringApplication {
|
|||
Assert.notEmpty(sources, "Sources must not be empty");
|
||||
load(context, sources.toArray(new Object[sources.size()]));
|
||||
listeners.contextLoaded(context);
|
||||
}
|
||||
|
||||
// Refresh the context
|
||||
private void refreshContext(ConfigurableApplicationContext context) {
|
||||
refresh(context);
|
||||
if (this.registerShutdownHook) {
|
||||
try {
|
||||
|
@ -368,7 +374,6 @@ public class SpringApplication {
|
|||
// Not allowed in some environments.
|
||||
}
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
private void configureHeadlessProperty() {
|
||||
|
@ -886,7 +891,7 @@ public class SpringApplication {
|
|||
|
||||
private int getExitCodeFromMappedException(ConfigurableApplicationContext context,
|
||||
Throwable exception) {
|
||||
if (context == null) {
|
||||
if (context == null || !context.isActive()) {
|
||||
return 0;
|
||||
}
|
||||
ExitCodeGenerators generators = new ExitCodeGenerators();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2014 the original author or authors.
|
||||
* Copyright 2012-2016 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.
|
||||
|
@ -62,7 +62,8 @@ public interface SpringApplicationRunListener {
|
|||
|
||||
/**
|
||||
* Called immediately before the run method finishes.
|
||||
* @param context the application context
|
||||
* @param context the application context or null if a failure occurred before the
|
||||
* context was created
|
||||
* @param exception any run exception or null if run completed successfully.
|
||||
*/
|
||||
void finished(ConfigurableApplicationContext context, Throwable exception);
|
||||
|
|
Loading…
Reference in New Issue