diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ApplicationContextFactory.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ApplicationContextFactory.java index d17ee20d31..9f9d08e71a 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ApplicationContextFactory.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ApplicationContextFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2022 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. @@ -19,10 +19,9 @@ package org.springframework.boot; import java.util.function.Supplier; import org.springframework.beans.BeanUtils; -import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.core.io.support.SpringFactoriesLoader; /** * Strategy interface for creating the {@link ConfigurableApplicationContext} used by a @@ -43,14 +42,14 @@ public interface ApplicationContextFactory { */ ApplicationContextFactory DEFAULT = (webApplicationType) -> { try { - switch (webApplicationType) { - case SERVLET: - return new AnnotationConfigServletWebServerApplicationContext(); - case REACTIVE: - return new AnnotationConfigReactiveWebServerApplicationContext(); - default: - return new AnnotationConfigApplicationContext(); + for (ApplicationContextFactory candidate : SpringFactoriesLoader + .loadFactories(ApplicationContextFactory.class, ApplicationContextFactory.class.getClassLoader())) { + ConfigurableApplicationContext context = candidate.create(webApplicationType); + if (context != null) { + return context; + } } + return new AnnotationConfigApplicationContext(); } catch (Exception ex) { throw new IllegalStateException("Unable create a default ApplicationContext instance, " diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/AnnotationConfigReactiveWebServerApplicationContext.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/AnnotationConfigReactiveWebServerApplicationContext.java index 8a2f68865f..9c9e3b6974 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/AnnotationConfigReactiveWebServerApplicationContext.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/AnnotationConfigReactiveWebServerApplicationContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2022 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. @@ -23,6 +23,9 @@ import java.util.Set; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.BeanNameGenerator; import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.boot.ApplicationContextFactory; +import org.springframework.boot.WebApplicationType; +import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.AnnotatedBeanDefinitionReader; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.AnnotationConfigRegistry; @@ -209,4 +212,18 @@ public class AnnotationConfigReactiveWebServerApplicationContext extends Reactiv } } + /** + * {@link ApplicationContextFactory} registered in {@code spring.factories} to support + * {@link AnnotationConfigReactiveWebServerApplicationContext}. + */ + static class Factory implements ApplicationContextFactory { + + @Override + public ConfigurableApplicationContext create(WebApplicationType webApplicationType) { + return (webApplicationType != WebApplicationType.REACTIVE) ? null + : new AnnotationConfigReactiveWebServerApplicationContext(); + } + + } + } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/AnnotationConfigServletWebServerApplicationContext.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/AnnotationConfigServletWebServerApplicationContext.java index 0b1775b9a6..2513b0cf3f 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/AnnotationConfigServletWebServerApplicationContext.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/AnnotationConfigServletWebServerApplicationContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2022 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. @@ -23,6 +23,9 @@ import java.util.Set; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.BeanNameGenerator; import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.boot.ApplicationContextFactory; +import org.springframework.boot.WebApplicationType; +import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.AnnotatedBeanDefinitionReader; import org.springframework.context.annotation.AnnotationConfigRegistry; import org.springframework.context.annotation.AnnotationConfigUtils; @@ -206,4 +209,18 @@ public class AnnotationConfigServletWebServerApplicationContext extends ServletW } } + /** + * {@link ApplicationContextFactory} registered in {@code spring.factories} to support + * {@link AnnotationConfigServletWebServerApplicationContext}. + */ + static class Factory implements ApplicationContextFactory { + + @Override + public ConfigurableApplicationContext create(WebApplicationType webApplicationType) { + return (webApplicationType != WebApplicationType.SERVLET) ? null + : new AnnotationConfigServletWebServerApplicationContext(); + } + + } + } diff --git a/spring-boot-project/spring-boot/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot/src/main/resources/META-INF/spring.factories index aab10a331b..41244a634e 100644 --- a/spring-boot-project/spring-boot/src/main/resources/META-INF/spring.factories +++ b/spring-boot-project/spring-boot/src/main/resources/META-INF/spring.factories @@ -19,6 +19,11 @@ org.springframework.boot.context.config.ConfigDataLoader=\ org.springframework.boot.context.config.ConfigTreeConfigDataLoader,\ org.springframework.boot.context.config.StandardConfigDataLoader +# Application Context Factories +org.springframework.boot.ApplicationContextFactory=\ +org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext.Factory,\ +org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext.Factory + # Run Listeners org.springframework.boot.SpringApplicationRunListener=\ org.springframework.boot.context.event.EventPublishingRunListener