Extract SpringApplicationRunListeners
Extract `SpringApplicationRunListeners` class from `SpringApplication` to simplify the `run` method. Closes gh-3079
This commit is contained in:
		
							parent
							
								
									e5f111100a
								
							
						
					
					
						commit
						373338124d
					
				| 
						 | 
				
			
			@ -267,24 +267,46 @@ public class SpringApplication {
 | 
			
		|||
		StopWatch stopWatch = new StopWatch();
 | 
			
		||||
		stopWatch.start();
 | 
			
		||||
		ConfigurableApplicationContext context = null;
 | 
			
		||||
		configureHeadlessProperty();
 | 
			
		||||
		SpringApplicationRunListeners listeners = getRunListeners(args);
 | 
			
		||||
		listeners.started();
 | 
			
		||||
		try {
 | 
			
		||||
			context = doRun(listeners, args);
 | 
			
		||||
 | 
			
		||||
		System.setProperty(
 | 
			
		||||
				SYSTEM_PROPERTY_JAVA_AWT_HEADLESS,
 | 
			
		||||
				System.getProperty(SYSTEM_PROPERTY_JAVA_AWT_HEADLESS,
 | 
			
		||||
						Boolean.toString(this.headless)));
 | 
			
		||||
 | 
			
		||||
		Collection<SpringApplicationRunListener> runListeners = getRunListeners(args);
 | 
			
		||||
		for (SpringApplicationRunListener runListener : runListeners) {
 | 
			
		||||
			runListener.started();
 | 
			
		||||
			stopWatch.stop();
 | 
			
		||||
			if (this.logStartupInfo) {
 | 
			
		||||
				new StartupInfoLogger(this.mainApplicationClass).logStarted(
 | 
			
		||||
						getApplicationLog(), stopWatch);
 | 
			
		||||
			}
 | 
			
		||||
			return context;
 | 
			
		||||
		}
 | 
			
		||||
		catch (Throwable ex) {
 | 
			
		||||
			try {
 | 
			
		||||
				listeners.finished(context, ex);
 | 
			
		||||
				this.log.error("Application startup failed", ex);
 | 
			
		||||
			}
 | 
			
		||||
			finally {
 | 
			
		||||
				if (context != null) {
 | 
			
		||||
					context.close();
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			ReflectionUtils.rethrowRuntimeException(ex);
 | 
			
		||||
			return context;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
		try {
 | 
			
		||||
	/**
 | 
			
		||||
	 * @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);
 | 
			
		||||
			for (SpringApplicationRunListener runListener : runListeners) {
 | 
			
		||||
				runListener.environmentPrepared(environment);
 | 
			
		||||
			}
 | 
			
		||||
		listeners.environmentPrepared(environment);
 | 
			
		||||
		if (this.showBanner) {
 | 
			
		||||
			printBanner(environment);
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -302,9 +324,7 @@ public class SpringApplication {
 | 
			
		|||
		context.setEnvironment(environment);
 | 
			
		||||
		postProcessApplicationContext(context);
 | 
			
		||||
		applyInitializers(context);
 | 
			
		||||
			for (SpringApplicationRunListener runListener : runListeners) {
 | 
			
		||||
				runListener.contextPrepared(context);
 | 
			
		||||
			}
 | 
			
		||||
		listeners.contextPrepared(context);
 | 
			
		||||
		if (this.logStartupInfo) {
 | 
			
		||||
			logStartupInfo(context.getParent() == null);
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -313,46 +333,26 @@ public class SpringApplication {
 | 
			
		|||
		Set<Object> 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);
 | 
			
		||||
			}
 | 
			
		||||
		listeners.contextLoaded(context);
 | 
			
		||||
 | 
			
		||||
		// Refresh the context
 | 
			
		||||
		refresh(context);
 | 
			
		||||
		afterRefresh(context, args);
 | 
			
		||||
			for (SpringApplicationRunListener runListener : runListeners) {
 | 
			
		||||
				runListener.finished(context, null);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			stopWatch.stop();
 | 
			
		||||
			if (this.logStartupInfo) {
 | 
			
		||||
				new StartupInfoLogger(this.mainApplicationClass).logStarted(
 | 
			
		||||
						getApplicationLog(), stopWatch);
 | 
			
		||||
			}
 | 
			
		||||
			return context;
 | 
			
		||||
		}
 | 
			
		||||
		catch (Throwable ex) {
 | 
			
		||||
			try {
 | 
			
		||||
				for (SpringApplicationRunListener runListener : runListeners) {
 | 
			
		||||
					finishWithException(runListener, context, ex);
 | 
			
		||||
				}
 | 
			
		||||
				this.log.error("Application startup failed", ex);
 | 
			
		||||
			}
 | 
			
		||||
			finally {
 | 
			
		||||
				if (context != null) {
 | 
			
		||||
					context.close();
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			ReflectionUtils.rethrowRuntimeException(ex);
 | 
			
		||||
		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 Collection<SpringApplicationRunListener> getRunListeners(String[] args) {
 | 
			
		||||
		List<SpringApplicationRunListener> listeners = new ArrayList<SpringApplicationRunListener>();
 | 
			
		||||
		listeners.addAll(getSpringFactoriesInstances(SpringApplicationRunListener.class,
 | 
			
		||||
				new Class<?>[] { SpringApplication.class, String[].class }, this, args));
 | 
			
		||||
		return listeners;
 | 
			
		||||
	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 <T> Collection<? extends T> getSpringFactoriesInstances(Class<T> 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) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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<SpringApplicationRunListener> listeners;
 | 
			
		||||
 | 
			
		||||
	public SpringApplicationRunListeners(Log log,
 | 
			
		||||
			Collection<? extends SpringApplicationRunListener> listeners) {
 | 
			
		||||
		this.log = log;
 | 
			
		||||
		this.listeners = new ArrayList<SpringApplicationRunListener>(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 + ")");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue