|
36 | 36 | import org.junit.rules.ExpectedException;
|
37 | 37 |
|
38 | 38 | import org.springframework.beans.BeansException;
|
| 39 | +import org.springframework.beans.factory.BeanCreationException; |
39 | 40 | import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
40 | 41 | import org.springframework.beans.factory.support.BeanNameGenerator;
|
41 | 42 | import org.springframework.beans.factory.support.DefaultBeanNameGenerator;
|
42 | 43 | import org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext;
|
43 | 44 | import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
|
44 | 45 | import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
|
| 46 | +import org.springframework.boot.context.event.ApplicationFailedEvent; |
45 | 47 | import org.springframework.boot.context.event.ApplicationPreparedEvent;
|
46 | 48 | import org.springframework.boot.context.event.ApplicationReadyEvent;
|
47 | 49 | import org.springframework.boot.context.event.ApplicationStartingEvent;
|
48 | 50 | import org.springframework.boot.testutil.InternalOutputCapture;
|
49 | 51 | import org.springframework.context.ApplicationContext;
|
50 | 52 | import org.springframework.context.ApplicationContextAware;
|
| 53 | +import org.springframework.context.ApplicationContextException; |
51 | 54 | import org.springframework.context.ApplicationContextInitializer;
|
52 | 55 | import org.springframework.context.ApplicationEvent;
|
53 | 56 | import org.springframework.context.ApplicationListener;
|
@@ -722,11 +725,107 @@ public void onApplicationEvent(ApplicationEvent event) {
|
722 | 725 | private void verifyTestListenerEvents() {
|
723 | 726 | ApplicationListener<ApplicationEvent> listener = this.context
|
724 | 727 | .getBean("testApplicationListener", ApplicationListener.class);
|
725 |
| - verify(listener).onApplicationEvent(argThat(isA(ContextRefreshedEvent.class))); |
726 |
| - verify(listener).onApplicationEvent(argThat(isA(ApplicationReadyEvent.class))); |
| 728 | + verifyListenerEvents(listener, ContextRefreshedEvent.class, |
| 729 | + ApplicationReadyEvent.class); |
| 730 | + } |
| 731 | + |
| 732 | + @SuppressWarnings("unchecked") |
| 733 | + private void verifyListenerEvents(ApplicationListener<ApplicationEvent> listener, |
| 734 | + Class<? extends ApplicationEvent>... eventTypes) { |
| 735 | + for (Class<? extends ApplicationEvent> eventType : eventTypes) { |
| 736 | + verify(listener).onApplicationEvent(argThat(isA(eventType))); |
| 737 | + } |
727 | 738 | verifyNoMoreInteractions(listener);
|
728 | 739 | }
|
729 | 740 |
|
| 741 | + @SuppressWarnings("unchecked") |
| 742 | + @Test |
| 743 | + public void applicationListenerFromApplicationIsCalledWhenContextFailsRefreshBeforeListenerRegistration() { |
| 744 | + ApplicationListener<ApplicationEvent> listener = mock(ApplicationListener.class); |
| 745 | + SpringApplication application = new SpringApplication(ExampleConfig.class); |
| 746 | + application.addListeners(listener); |
| 747 | + try { |
| 748 | + application.run(); |
| 749 | + fail("Run should have failed with an ApplicationContextException"); |
| 750 | + } |
| 751 | + catch (ApplicationContextException ex) { |
| 752 | + verifyListenerEvents(listener, ApplicationStartingEvent.class, |
| 753 | + ApplicationEnvironmentPreparedEvent.class, |
| 754 | + ApplicationPreparedEvent.class, ApplicationFailedEvent.class); |
| 755 | + } |
| 756 | + } |
| 757 | + |
| 758 | + @SuppressWarnings("unchecked") |
| 759 | + @Test |
| 760 | + public void applicationListenerFromApplicationIsCalledWhenContextFailsRefreshAfterListenerRegistration() { |
| 761 | + ApplicationListener<ApplicationEvent> listener = mock(ApplicationListener.class); |
| 762 | + SpringApplication application = new SpringApplication( |
| 763 | + BrokenPostConstructConfig.class); |
| 764 | + application.setWebEnvironment(false); |
| 765 | + application.addListeners(listener); |
| 766 | + try { |
| 767 | + application.run(); |
| 768 | + fail("Run should have failed with a BeanCreationException"); |
| 769 | + } |
| 770 | + catch (BeanCreationException ex) { |
| 771 | + verifyListenerEvents(listener, ApplicationStartingEvent.class, |
| 772 | + ApplicationEnvironmentPreparedEvent.class, |
| 773 | + ApplicationPreparedEvent.class, ApplicationFailedEvent.class); |
| 774 | + } |
| 775 | + } |
| 776 | + |
| 777 | + @SuppressWarnings("unchecked") |
| 778 | + @Test |
| 779 | + public void applicationListenerFromContextIsCalledWhenContextFailsRefreshBeforeListenerRegistration() { |
| 780 | + final ApplicationListener<ApplicationEvent> listener = mock( |
| 781 | + ApplicationListener.class); |
| 782 | + SpringApplication application = new SpringApplication(ExampleConfig.class); |
| 783 | + application.addInitializers( |
| 784 | + new ApplicationContextInitializer<ConfigurableApplicationContext>() { |
| 785 | + |
| 786 | + @Override |
| 787 | + public void initialize( |
| 788 | + ConfigurableApplicationContext applicationContext) { |
| 789 | + applicationContext.addApplicationListener(listener); |
| 790 | + } |
| 791 | + |
| 792 | + }); |
| 793 | + try { |
| 794 | + application.run(); |
| 795 | + fail("Run should have failed with an ApplicationContextException"); |
| 796 | + } |
| 797 | + catch (ApplicationContextException ex) { |
| 798 | + verifyListenerEvents(listener, ApplicationFailedEvent.class); |
| 799 | + } |
| 800 | + } |
| 801 | + |
| 802 | + @SuppressWarnings("unchecked") |
| 803 | + @Test |
| 804 | + public void applicationListenerFromContextIsCalledWhenContextFailsRefreshAfterListenerRegistration() { |
| 805 | + final ApplicationListener<ApplicationEvent> listener = mock( |
| 806 | + ApplicationListener.class); |
| 807 | + SpringApplication application = new SpringApplication( |
| 808 | + BrokenPostConstructConfig.class); |
| 809 | + application.setWebEnvironment(false); |
| 810 | + application.addInitializers( |
| 811 | + new ApplicationContextInitializer<ConfigurableApplicationContext>() { |
| 812 | + |
| 813 | + @Override |
| 814 | + public void initialize( |
| 815 | + ConfigurableApplicationContext applicationContext) { |
| 816 | + applicationContext.addApplicationListener(listener); |
| 817 | + } |
| 818 | + |
| 819 | + }); |
| 820 | + try { |
| 821 | + application.run(); |
| 822 | + fail("Run should have failed with a BeanCreationException"); |
| 823 | + } |
| 824 | + catch (BeanCreationException ex) { |
| 825 | + verifyListenerEvents(listener, ApplicationFailedEvent.class); |
| 826 | + } |
| 827 | + } |
| 828 | + |
730 | 829 | @Test
|
731 | 830 | public void registerShutdownHookOff() throws Exception {
|
732 | 831 | SpringApplication application = new SpringApplication(ExampleConfig.class);
|
@@ -936,6 +1035,25 @@ static class ExampleConfig {
|
936 | 1035 |
|
937 | 1036 | }
|
938 | 1037 |
|
| 1038 | + @Configuration |
| 1039 | + static class BrokenPostConstructConfig { |
| 1040 | + |
| 1041 | + @Bean |
| 1042 | + public Thing thing() { |
| 1043 | + return new Thing(); |
| 1044 | + } |
| 1045 | + |
| 1046 | + static class Thing { |
| 1047 | + |
| 1048 | + @PostConstruct |
| 1049 | + public void boom() { |
| 1050 | + throw new IllegalStateException(); |
| 1051 | + } |
| 1052 | + |
| 1053 | + } |
| 1054 | + |
| 1055 | + } |
| 1056 | + |
939 | 1057 | @Configuration
|
940 | 1058 | static class ListenerConfig {
|
941 | 1059 |
|
|
0 commit comments