Merge branch '1.5.x'

pull/9590/head
Andy Wilkinson 8 years ago
commit d844a0cf66

@ -26,6 +26,7 @@ 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.Ordered;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.util.ErrorHandler;
@ -93,12 +94,20 @@ public class EventPublishingRunListener implements SpringApplicationRunListener,
@Override
public void finished(ConfigurableApplicationContext context, Throwable exception) {
SpringApplicationEvent event = getFinishedEvent(context, exception);
if (context != null) {
if (context != null && context.isActive()) {
// Listeners have been registered to the application context so we should
// use it at this point if we can
context.publishEvent(event);
}
else {
// An inactive context may not have a multicaster so we use our multicaster to
// call all of the context's listeners instead
if (context instanceof AbstractApplicationContext) {
for (ApplicationListener<?> listener : ((AbstractApplicationContext) context)
.getApplicationListeners()) {
this.initialMulticaster.addApplicationListener(listener);
}
}
if (event instanceof ApplicationFailedEvent) {
this.initialMulticaster.setErrorHandler(new LoggingErrorHandler());
}

@ -41,10 +41,12 @@ import reactor.core.publisher.Mono;
import org.springframework.beans.BeansException;
import org.springframework.beans.CachedIntrospectionResults;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.beans.factory.support.DefaultBeanNameGenerator;
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
import org.springframework.boot.context.event.ApplicationFailedEvent;
import org.springframework.boot.context.event.ApplicationPreparedEvent;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.boot.context.event.ApplicationStartingEvent;
@ -56,6 +58,7 @@ import org.springframework.boot.web.reactive.context.ReactiveWebServerApplicatio
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationContextException;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
@ -790,11 +793,92 @@ public class SpringApplicationTests {
private void verifyTestListenerEvents() {
ApplicationListener<ApplicationEvent> listener = this.context
.getBean("testApplicationListener", ApplicationListener.class);
verify(listener).onApplicationEvent(isA(ContextRefreshedEvent.class));
verify(listener).onApplicationEvent(isA(ApplicationReadyEvent.class));
verifyListenerEvents(listener, ContextRefreshedEvent.class,
ApplicationReadyEvent.class);
}
@SuppressWarnings("unchecked")
private void verifyListenerEvents(ApplicationListener<ApplicationEvent> listener,
Class<? extends ApplicationEvent>... eventTypes) {
for (Class<? extends ApplicationEvent> eventType : eventTypes) {
verify(listener).onApplicationEvent(isA(eventType));
}
verifyNoMoreInteractions(listener);
}
@SuppressWarnings("unchecked")
@Test
public void applicationListenerFromApplicationIsCalledWhenContextFailsRefreshBeforeListenerRegistration() {
ApplicationListener<ApplicationEvent> listener = mock(ApplicationListener.class);
SpringApplication application = new SpringApplication(ExampleConfig.class);
application.addListeners(listener);
try {
application.run();
fail("Run should have failed with an ApplicationContextException");
}
catch (ApplicationContextException ex) {
verifyListenerEvents(listener, ApplicationStartingEvent.class,
ApplicationEnvironmentPreparedEvent.class,
ApplicationPreparedEvent.class, ApplicationFailedEvent.class);
}
}
@SuppressWarnings("unchecked")
@Test
public void applicationListenerFromApplicationIsCalledWhenContextFailsRefreshAfterListenerRegistration() {
ApplicationListener<ApplicationEvent> listener = mock(ApplicationListener.class);
SpringApplication application = new SpringApplication(
BrokenPostConstructConfig.class);
application.setWebApplicationType(WebApplicationType.NONE);
application.addListeners(listener);
try {
application.run();
fail("Run should have failed with a BeanCreationException");
}
catch (BeanCreationException ex) {
verifyListenerEvents(listener, ApplicationStartingEvent.class,
ApplicationEnvironmentPreparedEvent.class,
ApplicationPreparedEvent.class, ApplicationFailedEvent.class);
}
}
@SuppressWarnings("unchecked")
@Test
public void applicationListenerFromContextIsCalledWhenContextFailsRefreshBeforeListenerRegistration() {
final ApplicationListener<ApplicationEvent> listener = mock(
ApplicationListener.class);
SpringApplication application = new SpringApplication(ExampleConfig.class);
application.addInitializers((applicationContext) -> {
applicationContext.addApplicationListener(listener);
});
try {
application.run();
fail("Run should have failed with an ApplicationContextException");
}
catch (ApplicationContextException ex) {
verifyListenerEvents(listener, ApplicationFailedEvent.class);
}
}
@SuppressWarnings("unchecked")
@Test
public void applicationListenerFromContextIsCalledWhenContextFailsRefreshAfterListenerRegistration() {
ApplicationListener<ApplicationEvent> listener = mock(ApplicationListener.class);
SpringApplication application = new SpringApplication(
BrokenPostConstructConfig.class);
application.setWebApplicationType(WebApplicationType.NONE);
application.addInitializers((applicationContext) -> {
applicationContext.addApplicationListener(listener);
});
try {
application.run();
fail("Run should have failed with a BeanCreationException");
}
catch (BeanCreationException ex) {
verifyListenerEvents(listener, ApplicationFailedEvent.class);
}
}
@Test
public void registerShutdownHookOff() throws Exception {
SpringApplication application = new SpringApplication(ExampleConfig.class);
@ -1017,6 +1101,25 @@ public class SpringApplicationTests {
}
@Configuration
static class BrokenPostConstructConfig {
@Bean
public Thing thing() {
return new Thing();
}
static class Thing {
@PostConstruct
public void boom() {
throw new IllegalStateException();
}
}
}
@Configuration
static class ListenerConfig {

Loading…
Cancel
Save