Fix package tangle
Fix package tangle between the `org.springframework.boot` and the `event` sub-package. A new `SpringApplicationRunParticipant` abstraction has been introduced, with the `event` package solely responsible for handling event multi-casting.
This commit is contained in:
parent
c0a5c763b6
commit
042e512d3d
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
package org.springframework.boot;
|
package org.springframework.boot;
|
||||||
|
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
@ -31,28 +32,18 @@ import java.util.Set;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.BeanFactoryAware;
|
|
||||||
import org.springframework.beans.factory.groovy.GroovyBeanDefinitionReader;
|
import org.springframework.beans.factory.groovy.GroovyBeanDefinitionReader;
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||||
import org.springframework.beans.factory.support.BeanNameGenerator;
|
import org.springframework.beans.factory.support.BeanNameGenerator;
|
||||||
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
||||||
import org.springframework.boot.event.ApplicationEnvironmentPreparedEvent;
|
|
||||||
import org.springframework.boot.event.ApplicationFailedEvent;
|
|
||||||
import org.springframework.boot.event.ApplicationPreparedEvent;
|
|
||||||
import org.springframework.boot.event.ApplicationStartedEvent;
|
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.context.ApplicationContextInitializer;
|
import org.springframework.context.ApplicationContextInitializer;
|
||||||
import org.springframework.context.ApplicationEvent;
|
|
||||||
import org.springframework.context.ApplicationEventPublisher;
|
|
||||||
import org.springframework.context.ApplicationEventPublisherAware;
|
|
||||||
import org.springframework.context.ApplicationListener;
|
import org.springframework.context.ApplicationListener;
|
||||||
import org.springframework.context.ConfigurableApplicationContext;
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
import org.springframework.context.annotation.AnnotatedBeanDefinitionReader;
|
import org.springframework.context.annotation.AnnotatedBeanDefinitionReader;
|
||||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||||
import org.springframework.context.annotation.AnnotationConfigUtils;
|
import org.springframework.context.annotation.AnnotationConfigUtils;
|
||||||
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
|
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
|
||||||
import org.springframework.context.event.ApplicationEventMulticaster;
|
|
||||||
import org.springframework.context.event.SimpleApplicationEventMulticaster;
|
|
||||||
import org.springframework.context.support.AbstractApplicationContext;
|
import org.springframework.context.support.AbstractApplicationContext;
|
||||||
import org.springframework.context.support.GenericApplicationContext;
|
import org.springframework.context.support.GenericApplicationContext;
|
||||||
import org.springframework.core.GenericTypeResolver;
|
import org.springframework.core.GenericTypeResolver;
|
||||||
|
|
@ -72,6 +63,7 @@ import org.springframework.core.io.ResourceLoader;
|
||||||
import org.springframework.core.io.support.SpringFactoriesLoader;
|
import org.springframework.core.io.support.SpringFactoriesLoader;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
|
import org.springframework.util.ReflectionUtils;
|
||||||
import org.springframework.util.StopWatch;
|
import org.springframework.util.StopWatch;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.springframework.web.context.ConfigurableWebApplicationContext;
|
import org.springframework.web.context.ConfigurableWebApplicationContext;
|
||||||
|
|
@ -243,36 +235,6 @@ public class SpringApplication {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns objects loaded via the {@link SpringFactoriesLoader}.
|
|
||||||
*/
|
|
||||||
private <T> Collection<? extends T> getSpringFactoriesInstances(Class<T> type) {
|
|
||||||
ClassLoader classLoader = SpringApplication.class.getClassLoader();
|
|
||||||
|
|
||||||
// Use names and ensure unique to protect against duplicates
|
|
||||||
Set<String> names = new LinkedHashSet<String>(
|
|
||||||
SpringFactoriesLoader.loadFactoryNames(type, classLoader));
|
|
||||||
List<T> instances = new ArrayList<T>(names.size());
|
|
||||||
|
|
||||||
// Create instances from the names
|
|
||||||
for (String name : names) {
|
|
||||||
try {
|
|
||||||
Class<?> instanceClass = ClassUtils.forName(name, classLoader);
|
|
||||||
Assert.isAssignable(type, instanceClass);
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
T instance = (T) instanceClass.newInstance();
|
|
||||||
instances.add(instance);
|
|
||||||
}
|
|
||||||
catch (Throwable ex) {
|
|
||||||
throw new IllegalArgumentException("Cannot instantiate " + type + " : "
|
|
||||||
+ name, ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AnnotationAwareOrderComparator.sort(instances);
|
|
||||||
return instances;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Class<?> deduceMainApplicationClass() {
|
private Class<?> deduceMainApplicationClass() {
|
||||||
try {
|
try {
|
||||||
StackTraceElement[] stackTrace = new RuntimeException().getStackTrace();
|
StackTraceElement[] stackTrace = new RuntimeException().getStackTrace();
|
||||||
|
|
@ -302,23 +264,19 @@ public class SpringApplication {
|
||||||
|
|
||||||
System.setProperty("java.awt.headless", Boolean.toString(this.headless));
|
System.setProperty("java.awt.headless", Boolean.toString(this.headless));
|
||||||
|
|
||||||
ApplicationEventMulticaster multicaster = createApplicationEventMulticaster();
|
Collection<SpringApplicationRunParticipant> participants = createRunParticipants(args);
|
||||||
try {
|
for (SpringApplicationRunParticipant participant : participants) {
|
||||||
// Allow logging and stuff to initialize very early
|
participant.started();
|
||||||
multicaster.multicastEvent(new ApplicationStartedEvent(this, args));
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
// Create and configure the environment
|
// Create and configure the environment
|
||||||
ConfigurableEnvironment environment = getOrCreateEnvironment();
|
ConfigurableEnvironment environment = getOrCreateEnvironment();
|
||||||
addPropertySources(environment, args);
|
addPropertySources(environment, args);
|
||||||
setupProfiles(environment);
|
setupProfiles(environment);
|
||||||
|
for (SpringApplicationRunParticipant participant : participants) {
|
||||||
// Notify listeners of the environment creation
|
participant.environmentPrepared(environment);
|
||||||
multicaster.multicastEvent(new ApplicationEnvironmentPreparedEvent(this,
|
}
|
||||||
args, environment));
|
|
||||||
|
|
||||||
// Load the sources (might have changed when environment was applied)
|
|
||||||
Set<Object> sources = getSources();
|
|
||||||
Assert.notEmpty(sources, "Sources must not be empty");
|
|
||||||
|
|
||||||
if (this.showBanner) {
|
if (this.showBanner) {
|
||||||
printBanner();
|
printBanner();
|
||||||
|
|
@ -326,48 +284,93 @@ public class SpringApplication {
|
||||||
|
|
||||||
// Create, load, refresh and run the ApplicationContext
|
// Create, load, refresh and run the ApplicationContext
|
||||||
context = createApplicationContext();
|
context = createApplicationContext();
|
||||||
registerApplicationEventMulticaster(context, multicaster);
|
|
||||||
context.registerShutdownHook();
|
context.registerShutdownHook();
|
||||||
context.setEnvironment(environment);
|
context.setEnvironment(environment);
|
||||||
postProcessApplicationContext(context);
|
postProcessApplicationContext(context);
|
||||||
applyInitializers(context);
|
applyInitializers(context);
|
||||||
|
for (SpringApplicationRunParticipant participant : participants) {
|
||||||
|
participant.contextPrepared(context);
|
||||||
|
}
|
||||||
if (this.logStartupInfo) {
|
if (this.logStartupInfo) {
|
||||||
logStartupInfo(context.getParent() == null);
|
logStartupInfo(context.getParent() == null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load the sources
|
||||||
|
Set<Object> sources = getSources();
|
||||||
|
Assert.notEmpty(sources, "Sources must not be empty");
|
||||||
load(context, sources.toArray(new Object[sources.size()]));
|
load(context, sources.toArray(new Object[sources.size()]));
|
||||||
|
for (SpringApplicationRunParticipant participant : participants) {
|
||||||
|
participant.contextLoaded(context);
|
||||||
|
}
|
||||||
|
|
||||||
// Notify listeners of intention to refresh
|
// Refresh the context
|
||||||
multicaster.multicastEvent(new ApplicationPreparedEvent(this, args, context));
|
|
||||||
|
|
||||||
refresh(context);
|
refresh(context);
|
||||||
|
afterRefresh(context, args);
|
||||||
|
for (SpringApplicationRunParticipant participant : participants) {
|
||||||
|
participant.finished(context, null);
|
||||||
|
}
|
||||||
|
|
||||||
stopWatch.stop();
|
stopWatch.stop();
|
||||||
if (this.logStartupInfo) {
|
if (this.logStartupInfo) {
|
||||||
new StartupInfoLogger(this.mainApplicationClass).logStarted(
|
new StartupInfoLogger(this.mainApplicationClass).logStarted(
|
||||||
getApplicationLog(), stopWatch);
|
getApplicationLog(), stopWatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
afterRefresh(context, args);
|
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
catch (RuntimeException ex) {
|
catch (Exception ex) {
|
||||||
handleFailure(context, multicaster, ex, args);
|
for (SpringApplicationRunParticipant participant : participants) {
|
||||||
throw ex;
|
finishWithException(participant, context, ex);
|
||||||
|
}
|
||||||
|
if (context != null) {
|
||||||
|
context.close();
|
||||||
|
}
|
||||||
|
ReflectionUtils.rethrowRuntimeException(ex);
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
finally {
|
||||||
}
|
}
|
||||||
catch (Error ex) {
|
|
||||||
handleFailure(context, multicaster, ex, args);
|
|
||||||
throw ex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Collection<SpringApplicationRunParticipant> createRunParticipants(
|
||||||
|
String[] args) {
|
||||||
|
List<SpringApplicationRunParticipant> participants = new ArrayList<SpringApplicationRunParticipant>();
|
||||||
|
participants.addAll(getSpringFactoriesInstances(
|
||||||
|
SpringApplicationRunParticipant.class, new Class<?>[] {
|
||||||
|
SpringApplication.class, String[].class }, this, args));
|
||||||
|
return participants;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ApplicationEventMulticaster createApplicationEventMulticaster() {
|
private <T> Collection<? extends T> getSpringFactoriesInstances(Class<T> type) {
|
||||||
ApplicationEventMulticaster multicaster = new SpringApplicationEventMulticaster();
|
return getSpringFactoriesInstances(type, new Class<?>[] {});
|
||||||
for (ApplicationListener<?> listener : getListeners()) {
|
|
||||||
multicaster.addApplicationListener(listener);
|
|
||||||
}
|
}
|
||||||
return multicaster;
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private <T> Collection<? extends T> getSpringFactoriesInstances(Class<T> type,
|
||||||
|
Class<?>[] parameterTypes, Object... args) {
|
||||||
|
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
|
||||||
|
|
||||||
|
// Use names and ensure unique to protect against duplicates
|
||||||
|
Set<String> names = new LinkedHashSet<String>(
|
||||||
|
SpringFactoriesLoader.loadFactoryNames(type, classLoader));
|
||||||
|
List<T> instances = new ArrayList<T>(names.size());
|
||||||
|
|
||||||
|
// Create instances from the names
|
||||||
|
for (String name : names) {
|
||||||
|
try {
|
||||||
|
Class<?> instanceClass = ClassUtils.forName(name, classLoader);
|
||||||
|
Assert.isAssignable(type, instanceClass);
|
||||||
|
Constructor<?> constructor = instanceClass.getConstructor(parameterTypes);
|
||||||
|
T instance = (T) constructor.newInstance(args);
|
||||||
|
instances.add(instance);
|
||||||
|
}
|
||||||
|
catch (Throwable ex) {
|
||||||
|
throw new IllegalArgumentException("Cannot instantiate " + type + " : "
|
||||||
|
+ name, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AnnotationAwareOrderComparator.sort(instances);
|
||||||
|
return instances;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ConfigurableEnvironment getOrCreateEnvironment() {
|
private ConfigurableEnvironment getOrCreateEnvironment() {
|
||||||
|
|
@ -450,17 +453,6 @@ public class SpringApplication {
|
||||||
return (ConfigurableApplicationContext) BeanUtils.instantiate(contextClass);
|
return (ConfigurableApplicationContext) BeanUtils.instantiate(contextClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerApplicationEventMulticaster(
|
|
||||||
ConfigurableApplicationContext context,
|
|
||||||
ApplicationEventMulticaster multicaster) {
|
|
||||||
context.getBeanFactory().registerSingleton(
|
|
||||||
AbstractApplicationContext.APPLICATION_EVENT_MULTICASTER_BEAN_NAME,
|
|
||||||
multicaster);
|
|
||||||
if (multicaster instanceof BeanFactoryAware) {
|
|
||||||
((BeanFactoryAware) multicaster).setBeanFactory(context.getBeanFactory());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply any relevant post processing the {@link ApplicationContext}. Subclasses can
|
* Apply any relevant post processing the {@link ApplicationContext}. Subclasses can
|
||||||
* apply additional processing as required.
|
* apply additional processing as required.
|
||||||
|
|
@ -624,29 +616,23 @@ public class SpringApplication {
|
||||||
((AbstractApplicationContext) applicationContext).refresh();
|
((AbstractApplicationContext) applicationContext).refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void afterRefresh(ConfigurableApplicationContext context, String[] args) {
|
protected void afterRefresh(ConfigurableApplicationContext context, String[] args) {
|
||||||
runCommandLineRunners(context, args);
|
runCommandLineRunners(context, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void handleFailure(ConfigurableApplicationContext context,
|
private void finishWithException(SpringApplicationRunParticipant participant,
|
||||||
ApplicationEventMulticaster multicaster, Throwable exception, String... args) {
|
ConfigurableApplicationContext context, Exception exception) {
|
||||||
try {
|
try {
|
||||||
multicaster.multicastEvent(new ApplicationFailedEvent(this, args, context,
|
participant.finished(context, exception);
|
||||||
exception));
|
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
catch (Exception ex) {
|
||||||
// We don't want to fail here and mask the original exception
|
|
||||||
if (this.log.isDebugEnabled()) {
|
if (this.log.isDebugEnabled()) {
|
||||||
this.log.error("Error handling failed", ex);
|
this.log.error("Error handling failed", ex);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.log.warn("Error handling failed (" + ex.getMessage() == null ? "no error message"
|
String message = ex.getMessage();
|
||||||
: ex.getMessage() + ")");
|
message = (message == null ? "no error message" : message);
|
||||||
}
|
this.log.warn("Error handling failed (" + message + ")");
|
||||||
}
|
|
||||||
finally {
|
|
||||||
if (context != null) {
|
|
||||||
context.close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -974,38 +960,4 @@ public class SpringApplication {
|
||||||
return new LinkedHashSet<E>(list);
|
return new LinkedHashSet<E>(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@link ApplicationEventMulticaster} and {@link ApplicationEventPublisher} for
|
|
||||||
* {@link SpringApplication} events.
|
|
||||||
*/
|
|
||||||
private static class SpringApplicationEventMulticaster extends
|
|
||||||
SimpleApplicationEventMulticaster implements ApplicationEventPublisher {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void publishEvent(ApplicationEvent event) {
|
|
||||||
multicastEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Collection<ApplicationListener<?>> getApplicationListeners(
|
|
||||||
ApplicationEvent event) {
|
|
||||||
List<ApplicationListener<?>> listeners = new ArrayList<ApplicationListener<?>>();
|
|
||||||
listeners.addAll(super.getApplicationListeners(event));
|
|
||||||
if (event instanceof ApplicationFailedEvent) {
|
|
||||||
Collections.reverse(listeners);
|
|
||||||
}
|
|
||||||
return listeners;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addApplicationListener(ApplicationListener<?> listener) {
|
|
||||||
super.addApplicationListener(listener);
|
|
||||||
if (listener instanceof ApplicationEventPublisherAware) {
|
|
||||||
((ApplicationEventPublisherAware) listener)
|
|
||||||
.setApplicationEventPublisher(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2014 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.ApplicationContext;
|
||||||
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
|
import org.springframework.core.env.ConfigurableEnvironment;
|
||||||
|
import org.springframework.core.io.support.SpringFactoriesLoader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strategy class to allow dynamic participation when the {@link SpringApplication}
|
||||||
|
* {@code run} method is called. Participants are loaded via the
|
||||||
|
* {@link SpringFactoriesLoader} and should declare a public constructor that accepts a
|
||||||
|
* {@link SpringApplication} instance and a {@code String[]} of arguments. A new
|
||||||
|
* {@link SpringApplicationRunParticipant} instance will be created for each run.
|
||||||
|
*
|
||||||
|
* @author Phillip Webb
|
||||||
|
*/
|
||||||
|
public interface SpringApplicationRunParticipant {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called immediately when the run method has first started. Can be used for very
|
||||||
|
* early initialization.
|
||||||
|
*/
|
||||||
|
void started();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called once the environment has been prepared, but before the
|
||||||
|
* {@link ApplicationContext} has been created.
|
||||||
|
* @param environment the environment
|
||||||
|
*/
|
||||||
|
void environmentPrepared(ConfigurableEnvironment environment);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called once the {@link ApplicationContext} has been created and prepared, but
|
||||||
|
* before sources have been loaded.
|
||||||
|
* @param context the application context
|
||||||
|
*/
|
||||||
|
void contextPrepared(ConfigurableApplicationContext context);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called once the application context has been loaded but before it has been
|
||||||
|
* refreshed.
|
||||||
|
* @param context the application context
|
||||||
|
*/
|
||||||
|
void contextLoaded(ConfigurableApplicationContext context);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called immediately before the run method finishes.
|
||||||
|
* @param context the application context
|
||||||
|
* @param exception any run exception or null if run completed successfully.
|
||||||
|
*/
|
||||||
|
void finished(ConfigurableApplicationContext context, Throwable exception);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,95 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2014 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.event;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.BeanFactoryAware;
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.SpringApplicationRunParticipant;
|
||||||
|
import org.springframework.context.ApplicationListener;
|
||||||
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
|
import org.springframework.context.event.ApplicationEventMulticaster;
|
||||||
|
import org.springframework.context.event.SimpleApplicationEventMulticaster;
|
||||||
|
import org.springframework.context.support.AbstractApplicationContext;
|
||||||
|
import org.springframework.core.env.ConfigurableEnvironment;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link SpringApplicationRunParticipant} to publish {@link SpringApplicationEvent}s.
|
||||||
|
*
|
||||||
|
* @author Phillip Webb
|
||||||
|
*/
|
||||||
|
public class EventPublishingRunParticipant implements SpringApplicationRunParticipant {
|
||||||
|
|
||||||
|
private final ApplicationEventMulticaster multicaster;
|
||||||
|
|
||||||
|
private SpringApplication application;
|
||||||
|
|
||||||
|
private String[] args;
|
||||||
|
|
||||||
|
public EventPublishingRunParticipant(SpringApplication application, String[] args) {
|
||||||
|
this.application = application;
|
||||||
|
this.args = args;
|
||||||
|
this.multicaster = new SimpleApplicationEventMulticaster();
|
||||||
|
for (ApplicationListener<?> listener : application.getListeners()) {
|
||||||
|
this.multicaster.addApplicationListener(listener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void started() {
|
||||||
|
publishEvent(new ApplicationStartedEvent(this.application, this.args));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void environmentPrepared(ConfigurableEnvironment environment) {
|
||||||
|
publishEvent(new ApplicationEnvironmentPreparedEvent(this.application, this.args,
|
||||||
|
environment));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void contextPrepared(ConfigurableApplicationContext context) {
|
||||||
|
registerApplicationEventMulticaster(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerApplicationEventMulticaster(
|
||||||
|
ConfigurableApplicationContext context) {
|
||||||
|
context.getBeanFactory().registerSingleton(
|
||||||
|
AbstractApplicationContext.APPLICATION_EVENT_MULTICASTER_BEAN_NAME,
|
||||||
|
this.multicaster);
|
||||||
|
if (this.multicaster instanceof BeanFactoryAware) {
|
||||||
|
((BeanFactoryAware) this.multicaster)
|
||||||
|
.setBeanFactory(context.getBeanFactory());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void contextLoaded(ConfigurableApplicationContext context) {
|
||||||
|
publishEvent(new ApplicationPreparedEvent(this.application, this.args, context));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void finished(ConfigurableApplicationContext context, Throwable exception) {
|
||||||
|
if (exception != null) {
|
||||||
|
publishEvent(new ApplicationFailedEvent(this.application, this.args, context,
|
||||||
|
exception));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void publishEvent(SpringApplicationEvent event) {
|
||||||
|
this.multicaster.multicastEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
# Run Participants
|
||||||
|
org.springframework.boot.SpringApplicationRunParticipant=\
|
||||||
|
org.springframework.boot.event.EventPublishingRunParticipant
|
||||||
|
|
||||||
# Application Context Initializers
|
# Application Context Initializers
|
||||||
org.springframework.context.ApplicationContextInitializer=\
|
org.springframework.context.ApplicationContextInitializer=\
|
||||||
org.springframework.boot.context.initializer.ContextIdApplicationContextInitializer,\
|
org.springframework.boot.context.initializer.ContextIdApplicationContextInitializer,\
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue