diff --git a/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java b/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java index 4d2825b9303..7797bbd0820 100644 --- a/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java +++ b/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java @@ -267,62 +267,11 @@ public class SpringApplication { StopWatch stopWatch = new StopWatch(); stopWatch.start(); ConfigurableApplicationContext context = null; - - System.setProperty( - SYSTEM_PROPERTY_JAVA_AWT_HEADLESS, - System.getProperty(SYSTEM_PROPERTY_JAVA_AWT_HEADLESS, - Boolean.toString(this.headless))); - - Collection runListeners = getRunListeners(args); - for (SpringApplicationRunListener runListener : runListeners) { - runListener.started(); - } - + configureHeadlessProperty(); + SpringApplicationRunListeners listeners = getRunListeners(args); + listeners.started(); try { - // Create and configure the environment - ConfigurableEnvironment environment = getOrCreateEnvironment(); - configureEnvironment(environment, args); - for (SpringApplicationRunListener runListener : runListeners) { - runListener.environmentPrepared(environment); - } - if (this.showBanner) { - printBanner(environment); - } - - // Create, load, refresh and run the ApplicationContext - context = createApplicationContext(); - if (this.registerShutdownHook) { - try { - context.registerShutdownHook(); - } - catch (AccessControlException ex) { - // Not allowed in some environments. - } - } - context.setEnvironment(environment); - postProcessApplicationContext(context); - applyInitializers(context); - for (SpringApplicationRunListener runListener : runListeners) { - runListener.contextPrepared(context); - } - if (this.logStartupInfo) { - logStartupInfo(context.getParent() == null); - } - - // Load the sources - Set sources = getSources(); - Assert.notEmpty(sources, "Sources must not be empty"); - load(context, sources.toArray(new Object[sources.size()])); - for (SpringApplicationRunListener runListener : runListeners) { - runListener.contextLoaded(context); - } - - // Refresh the context - refresh(context); - afterRefresh(context, args); - for (SpringApplicationRunListener runListener : runListeners) { - runListener.finished(context, null); - } + context = doRun(listeners, args); stopWatch.stop(); if (this.logStartupInfo) { @@ -333,9 +282,7 @@ public class SpringApplication { } catch (Throwable ex) { try { - for (SpringApplicationRunListener runListener : runListeners) { - finishWithException(runListener, context, ex); - } + listeners.finished(context, ex); this.log.error("Application startup failed", ex); } finally { @@ -348,11 +295,64 @@ public class SpringApplication { } } - private Collection getRunListeners(String[] args) { - List listeners = new ArrayList(); - listeners.addAll(getSpringFactoriesInstances(SpringApplicationRunListener.class, - new Class[] { SpringApplication.class, String[].class }, this, args)); - return listeners; + /** + * @param listeners + * @param args + * @return + */ + private ConfigurableApplicationContext doRun(SpringApplicationRunListeners listeners, + String... args) { + ConfigurableApplicationContext context; + // Create and configure the environment + ConfigurableEnvironment environment = getOrCreateEnvironment(); + configureEnvironment(environment, args); + listeners.environmentPrepared(environment); + if (this.showBanner) { + printBanner(environment); + } + + // Create, load, refresh and run the ApplicationContext + context = createApplicationContext(); + if (this.registerShutdownHook) { + try { + context.registerShutdownHook(); + } + catch (AccessControlException ex) { + // Not allowed in some environments. + } + } + context.setEnvironment(environment); + postProcessApplicationContext(context); + applyInitializers(context); + listeners.contextPrepared(context); + if (this.logStartupInfo) { + logStartupInfo(context.getParent() == null); + } + + // Load the sources + Set sources = getSources(); + Assert.notEmpty(sources, "Sources must not be empty"); + load(context, sources.toArray(new Object[sources.size()])); + listeners.contextLoaded(context); + + // Refresh the context + refresh(context); + afterRefresh(context, args); + listeners.finished(context, null); + return context; + } + + private void configureHeadlessProperty() { + System.setProperty( + SYSTEM_PROPERTY_JAVA_AWT_HEADLESS, + System.getProperty(SYSTEM_PROPERTY_JAVA_AWT_HEADLESS, + Boolean.toString(this.headless))); + } + + private SpringApplicationRunListeners getRunListeners(String[] args) { + Class[] types = new Class[] { SpringApplication.class, String[].class }; + return new SpringApplicationRunListeners(this.log, getSpringFactoriesInstances( + SpringApplicationRunListener.class, types, this, args)); } private Collection getSpringFactoriesInstances(Class type) { @@ -682,23 +682,6 @@ public class SpringApplication { runCommandLineRunners(context, args); } - private void finishWithException(SpringApplicationRunListener runListener, - ConfigurableApplicationContext context, Throwable exception) { - try { - runListener.finished(context, exception); - } - catch (Exception ex) { - if (this.log.isDebugEnabled()) { - this.log.error("Error handling failed", ex); - } - else { - String message = ex.getMessage(); - message = (message == null ? "no error message" : message); - this.log.warn("Error handling failed (" + message + ")"); - } - } - } - /** * Set a specific main application class that will be used as a log source and to * obtain version information. By default the main application class will be deduced. @@ -758,7 +741,7 @@ public class SpringApplication { /** * Sets if the application information should be logged when the application starts. - * Defaults to {@code true} + * Defaults to {@code true}. * @param logStartupInfo if startup info should be logged. */ public void setLogStartupInfo(boolean logStartupInfo) { diff --git a/spring-boot/src/main/java/org/springframework/boot/SpringApplicationRunListeners.java b/spring-boot/src/main/java/org/springframework/boot/SpringApplicationRunListeners.java new file mode 100644 index 00000000000..7a68ec45968 --- /dev/null +++ b/spring-boot/src/main/java/org/springframework/boot/SpringApplicationRunListeners.java @@ -0,0 +1,95 @@ +/* + * 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 java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.util.ReflectionUtils; + +/** + * A collection of {@link SpringApplicationRunListener}. + * + * @author Phillip Webb + */ +class SpringApplicationRunListeners { + + private final Log log; + + private final List listeners; + + public SpringApplicationRunListeners(Log log, + Collection listeners) { + this.log = log; + this.listeners = new ArrayList(listeners); + } + + public void started() { + for (SpringApplicationRunListener listener : this.listeners) { + listener.started(); + } + } + + public void environmentPrepared(ConfigurableEnvironment environment) { + for (SpringApplicationRunListener listener : this.listeners) { + listener.environmentPrepared(environment); + } + } + + public void contextPrepared(ConfigurableApplicationContext context) { + for (SpringApplicationRunListener listener : this.listeners) { + listener.contextPrepared(context); + } + } + + public void contextLoaded(ConfigurableApplicationContext context) { + for (SpringApplicationRunListener listener : this.listeners) { + listener.contextLoaded(context); + } + } + + public void finished(ConfigurableApplicationContext context, Throwable exception) { + for (SpringApplicationRunListener listener : this.listeners) { + callFinishedListener(listener, context, exception); + } + } + + private void callFinishedListener(SpringApplicationRunListener listener, + ConfigurableApplicationContext context, Throwable exception) { + try { + listener.finished(context, exception); + } + catch (Throwable ex) { + if (exception == null) { + ReflectionUtils.rethrowRuntimeException(ex); + } + if (this.log.isDebugEnabled()) { + this.log.error("Error handling failed", ex); + } + else { + String message = ex.getMessage(); + message = (message == null ? "no error message" : message); + this.log.warn("Error handling failed (" + message + ")"); + } + } + } + +}