@ -41,10 +41,12 @@ import reactor.core.publisher.Mono;
@@ -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
@@ -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 {
@@ -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 {
@@ -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 {