From 0c8e52e87718af385478cb6746821b3aa2ece44e Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 14 Jul 2020 14:26:39 +0100 Subject: [PATCH] Avoid using reflection to create SpringApplication's context Closes gh-22322 --- .../test/context/SpringBootContextLoader.java | 20 +---- .../boot/ApplicationContextFactory.java | 53 +++++++++++++ .../boot/SpringApplication.java | 79 +++++++++++++------ .../builder/SpringApplicationBuilder.java | 17 +++- .../support/SpringBootServletInitializer.java | 2 +- .../boot/SpringApplicationNoWebTests.java | 5 +- .../boot/SpringApplicationTests.java | 25 +++++- .../SpringApplicationBuilderTests.java | 37 ++++++--- 8 files changed, 176 insertions(+), 62 deletions(-) create mode 100644 spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ApplicationContextFactory.java diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootContextLoader.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootContextLoader.java index 360af8dd83..a5a0feef5e 100644 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootContextLoader.java +++ b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootContextLoader.java @@ -110,7 +110,8 @@ public class SpringBootContextLoader extends AbstractContextLoader { else if (config instanceof ReactiveWebMergedContextConfiguration) { application.setWebApplicationType(WebApplicationType.REACTIVE); if (!isEmbeddedWebEnvironment(config)) { - new ReactiveWebConfigurer().configure(application); + application.setApplicationContextFactory( + (webApplicationType) -> new GenericReactiveWebApplicationContext()); } } else { @@ -250,13 +251,11 @@ public class SpringBootContextLoader extends AbstractContextLoader { */ private static class WebConfigurer { - private static final Class WEB_CONTEXT_CLASS = GenericWebApplicationContext.class; - void configure(MergedContextConfiguration configuration, SpringApplication application, List> initializers) { WebMergedContextConfiguration webConfiguration = (WebMergedContextConfiguration) configuration; addMockServletContext(initializers, webConfiguration); - application.setApplicationContextClass(WEB_CONTEXT_CLASS); + application.setApplicationContextFactory((webApplicationType) -> new GenericWebApplicationContext()); } private void addMockServletContext(List> initializers, @@ -268,19 +267,6 @@ public class SpringBootContextLoader extends AbstractContextLoader { } - /** - * Inner class to configure {@link ReactiveWebMergedContextConfiguration}. - */ - private static class ReactiveWebConfigurer { - - private static final Class WEB_CONTEXT_CLASS = GenericReactiveWebApplicationContext.class; - - void configure(SpringApplication application) { - application.setApplicationContextClass(WEB_CONTEXT_CLASS); - } - - } - /** * Adapts a {@link ContextCustomizer} to a {@link ApplicationContextInitializer} so * that it can be triggered via {@link SpringApplication}. 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 new file mode 100644 index 0000000000..574f741628 --- /dev/null +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ApplicationContextFactory.java @@ -0,0 +1,53 @@ +/* + * Copyright 2012-2020 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 + * + * https://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.beans.BeanUtils; +import org.springframework.context.ConfigurableApplicationContext; + +/** + * Strategy interface for creating the {@link ConfigurableApplicationContext} used by a + * {@link SpringApplication}. Created contexts should be returned in their default form, + * with the {@code SpringApplication} responsible for configuring and refreshing the + * context. + * + * @author Andy Wilkinson + * @since 2.4.0 + */ +@FunctionalInterface +public interface ApplicationContextFactory { + + /** + * Creates the {@link ConfigurableApplicationContext application context} for a + * {@link SpringApplication}, respecting the given {@code webApplicationType}. + * @param webApplicationType the web application type + * @return the newly created application context + */ + ConfigurableApplicationContext create(WebApplicationType webApplicationType); + + /** + * Creates an {@code ApplicationContextFactory} that will create contexts by + * instantiating the given {@code contextClass} via its primary constructor. + * @param contextClass the context class + * @return the factory that will instantiate the context class + * @see BeanUtils#instantiateClass(Class) + */ + static ApplicationContextFactory forContextClass(Class contextClass) { + return (webApplicationType) -> BeanUtils.instantiateClass(contextClass); + } + +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java index dbae3c030c..99df94c181 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java @@ -47,7 +47,9 @@ import org.springframework.boot.context.properties.bind.Bindable; import org.springframework.boot.context.properties.bind.Binder; import org.springframework.boot.context.properties.source.ConfigurationPropertySources; import org.springframework.boot.convert.ApplicationConversionService; +import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; import org.springframework.boot.web.reactive.context.StandardReactiveWebEnvironment; +import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ApplicationListener; @@ -163,21 +165,27 @@ public class SpringApplication { /** * The class name of application context that will be used by default for non-web * environments. + * @deprecated since 2.4.0 in favour of using a {@link ApplicationContextFactory} */ + @Deprecated public static final String DEFAULT_CONTEXT_CLASS = "org.springframework.context." + "annotation.AnnotationConfigApplicationContext"; /** * The class name of application context that will be used by default for web * environments. + * @deprecated since 2.4.0 in favour of using an {@link ApplicationContextFactory} */ + @Deprecated public static final String DEFAULT_SERVLET_WEB_CONTEXT_CLASS = "org.springframework.boot." + "web.servlet.context.AnnotationConfigServletWebServerApplicationContext"; /** * The class name of application context that will be used by default for reactive web * environments. + * @deprecated since 2.4.0 in favour of using an {@link ApplicationContextFactory} */ + @Deprecated public static final String DEFAULT_REACTIVE_WEB_CONTEXT_CLASS = "org.springframework." + "boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext"; @@ -217,8 +225,6 @@ public class SpringApplication { private ConfigurableEnvironment environment; - private Class applicationContextClass; - private WebApplicationType webApplicationType; private boolean headless = true; @@ -239,6 +245,8 @@ public class SpringApplication { private boolean lazyInitialization = false; + private ApplicationContextFactory applicationContextFactory = new DefaultApplicationContextFactory(); + /** * Create a new {@link SpringApplication} instance. The application context will load * beans from the specified primary sources (see {@link SpringApplication class-level} @@ -560,32 +568,14 @@ public class SpringApplication { /** * Strategy method used to create the {@link ApplicationContext}. By default this - * method will respect any explicitly set application context or application context - * class before falling back to a suitable default. + * method will respect any explicitly set application context class or factory before + * falling back to a suitable default. * @return the application context (not yet refreshed) * @see #setApplicationContextClass(Class) + * @see #setApplicationContextFactory(ApplicationContextFactory) */ protected ConfigurableApplicationContext createApplicationContext() { - Class contextClass = this.applicationContextClass; - if (contextClass == null) { - try { - switch (this.webApplicationType) { - case SERVLET: - contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS); - break; - case REACTIVE: - contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS); - break; - default: - contextClass = Class.forName(DEFAULT_CONTEXT_CLASS); - } - } - catch (ClassNotFoundException ex) { - throw new IllegalStateException( - "Unable create a default ApplicationContext, please specify an ApplicationContextClass", ex); - } - } - return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass); + return this.applicationContextFactory.create(this.webApplicationType); } /** @@ -1154,10 +1144,27 @@ public class SpringApplication { * applications or {@link AnnotationConfigApplicationContext} for non web based * applications. * @param applicationContextClass the context class to set + * @deprecated since 2.4.0 in favor of + * {@link #setApplicationContextFactory(ApplicationContextFactory)} */ + @Deprecated public void setApplicationContextClass(Class applicationContextClass) { - this.applicationContextClass = applicationContextClass; this.webApplicationType = WebApplicationType.deduceFromApplicationContext(applicationContextClass); + this.applicationContextFactory = ApplicationContextFactory.forContextClass(applicationContextClass); + } + + /** + * Sets the factory that will be called to create the application context. If not set, + * defaults to a factory that will create + * {@link AnnotationConfigServletWebServerApplicationContext} for servlet web + * applications, {@link AnnotationConfigReactiveWebServerApplicationContext} for + * reactive web applications, and {@link AnnotationConfigApplicationContext} for + * non-web applications. + * @param applicationContextFactory the factory for the context + * @since 2.4.0 + */ + public void setApplicationContextFactory(ApplicationContextFactory applicationContextFactory) { + this.applicationContextFactory = applicationContextFactory; } /** @@ -1302,4 +1309,26 @@ public class SpringApplication { return new LinkedHashSet<>(list); } + private static final class DefaultApplicationContextFactory implements ApplicationContextFactory { + + @Override + public ConfigurableApplicationContext create(WebApplicationType webApplicationType) { + try { + switch (webApplicationType) { + case SERVLET: + return new AnnotationConfigServletWebServerApplicationContext(); + case REACTIVE: + return new AnnotationConfigReactiveWebServerApplicationContext(); + default: + return new AnnotationConfigApplicationContext(); + } + } + catch (Exception ex) { + throw new IllegalStateException( + "Unable create a default ApplicationContext, please specify an ApplicationContextFactory", ex); + } + } + + } + } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/builder/SpringApplicationBuilder.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/builder/SpringApplicationBuilder.java index 5f7efcd0f5..26bbac7fd8 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/builder/SpringApplicationBuilder.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/builder/SpringApplicationBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2020 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. @@ -28,6 +28,7 @@ import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import org.springframework.beans.factory.support.BeanNameGenerator; +import org.springframework.boot.ApplicationContextFactory; import org.springframework.boot.Banner; import org.springframework.boot.SpringApplication; import org.springframework.boot.WebApplicationType; @@ -272,12 +273,26 @@ public class SpringApplicationBuilder { * Explicitly set the context class to be used. * @param cls the context class to use * @return the current builder + * @deprecated since 2.4.0 in favor of + * {@link #contextFactory(ApplicationContextFactory)} */ + @Deprecated public SpringApplicationBuilder contextClass(Class cls) { this.application.setApplicationContextClass(cls); return this; } + /** + * Explicitly set the factory used to create the application context. + * @param factory the factory to use + * @return the current builder + * @since 2.4.0 + */ + public SpringApplicationBuilder contextFactory(ApplicationContextFactory factory) { + this.application.setApplicationContextFactory(factory); + return this; + } + /** * Add more sources (configuration classes and components) to this application. * @param sources the sources to add diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/support/SpringBootServletInitializer.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/support/SpringBootServletInitializer.java index dca37a646a..38c4b7ccaa 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/support/SpringBootServletInitializer.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/support/SpringBootServletInitializer.java @@ -134,7 +134,7 @@ public abstract class SpringBootServletInitializer implements WebApplicationInit builder.initializers(new ParentContextApplicationContextInitializer(parent)); } builder.initializers(new ServletContextApplicationContextInitializer(servletContext)); - builder.contextClass(AnnotationConfigServletWebServerApplicationContext.class); + builder.contextFactory((webApplicationType) -> new AnnotationConfigServletWebServerApplicationContext()); builder = configure(builder); builder.listeners(new WebEnvironmentPropertySourceInitializer(servletContext)); SpringApplication application = builder.build(); diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/SpringApplicationNoWebTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/SpringApplicationNoWebTests.java index 437feea231..1cb847420f 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/SpringApplicationNoWebTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/SpringApplicationNoWebTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2020 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. @@ -42,7 +42,8 @@ class SpringApplicationNoWebTests { @Test void specificApplicationContextClass() { SpringApplication application = new SpringApplication(ExampleConfig.class); - application.setApplicationContextClass(StaticApplicationContext.class); + application.setApplicationContextFactory( + ApplicationContextFactory.forContextClass(StaticApplicationContext.class)); ConfigurableApplicationContext context = application.run(); assertThat(context).isInstanceOf(StaticApplicationContext.class); context.close(); diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/SpringApplicationTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/SpringApplicationTests.java index d67da1606c..30e7c58f49 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/SpringApplicationTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/SpringApplicationTests.java @@ -320,6 +320,7 @@ class SpringApplicationTests { } @Test + @SuppressWarnings("deprecation") void specificApplicationContextClass() { SpringApplication application = new SpringApplication(ExampleConfig.class); application.setApplicationContextClass(StaticApplicationContext.class); @@ -328,6 +329,16 @@ class SpringApplicationTests { } @Test + void specificApplicationContextFactory() { + SpringApplication application = new SpringApplication(ExampleConfig.class); + application.setApplicationContextFactory( + ApplicationContextFactory.forContextClass(StaticApplicationContext.class)); + this.context = application.run(); + assertThat(this.context).isInstanceOf(StaticApplicationContext.class); + } + + @Test + @SuppressWarnings("deprecation") void specificWebApplicationContextClassDetectWebApplicationType() { SpringApplication application = new SpringApplication(ExampleConfig.class); application.setApplicationContextClass(AnnotationConfigServletWebApplicationContext.class); @@ -335,6 +346,7 @@ class SpringApplicationTests { } @Test + @SuppressWarnings("deprecation") void specificReactiveApplicationContextClassDetectReactiveApplicationType() { SpringApplication application = new SpringApplication(ExampleConfig.class); application.setApplicationContextClass(AnnotationConfigReactiveWebApplicationContext.class); @@ -342,6 +354,7 @@ class SpringApplicationTests { } @Test + @SuppressWarnings("deprecation") void nonWebNorReactiveApplicationContextClassDetectNoneApplicationType() { SpringApplication application = new SpringApplication(ExampleConfig.class); application.setApplicationContextClass(StaticApplicationContext.class); @@ -876,7 +889,8 @@ class SpringApplicationTests { @Test void registerShutdownHook() { SpringApplication application = new SpringApplication(ExampleConfig.class); - application.setApplicationContextClass(SpyApplicationContext.class); + application + .setApplicationContextFactory(ApplicationContextFactory.forContextClass(SpyApplicationContext.class)); this.context = application.run(); SpyApplicationContext applicationContext = (SpyApplicationContext) this.context; verify(applicationContext.getApplicationContext()).registerShutdownHook(); @@ -885,7 +899,8 @@ class SpringApplicationTests { @Test void registerListener() { SpringApplication application = new SpringApplication(ExampleConfig.class, ListenerConfig.class); - application.setApplicationContextClass(SpyApplicationContext.class); + application + .setApplicationContextFactory(ApplicationContextFactory.forContextClass(SpyApplicationContext.class)); Set events = new LinkedHashSet<>(); application.addListeners((ApplicationListener) events::add); this.context = application.run(); @@ -898,7 +913,8 @@ class SpringApplicationTests { void registerListenerWithCustomMulticaster() { SpringApplication application = new SpringApplication(ExampleConfig.class, ListenerConfig.class, Multicaster.class); - application.setApplicationContextClass(SpyApplicationContext.class); + application + .setApplicationContextFactory(ApplicationContextFactory.forContextClass(SpyApplicationContext.class)); Set events = new LinkedHashSet<>(); application.addListeners((ApplicationListener) events::add); this.context = application.run(); @@ -978,7 +994,8 @@ class SpringApplicationTests { @Test void registerShutdownHookOff() { SpringApplication application = new SpringApplication(ExampleConfig.class); - application.setApplicationContextClass(SpyApplicationContext.class); + application + .setApplicationContextFactory(ApplicationContextFactory.forContextClass(SpyApplicationContext.class)); application.setRegisterShutdownHook(false); this.context = application.run(); SpyApplicationContext applicationContext = (SpyApplicationContext) this.context; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/builder/SpringApplicationBuilderTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/builder/SpringApplicationBuilderTests.java index 8f374ad153..5f5ac4c5d5 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/builder/SpringApplicationBuilderTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/builder/SpringApplicationBuilderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2020 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. @@ -24,6 +24,7 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationContextFactory; import org.springframework.boot.WebApplicationType; import org.springframework.context.ApplicationContext; import org.springframework.context.ConfigurableApplicationContext; @@ -68,7 +69,8 @@ class SpringApplicationBuilderTests { @Test void profileAndProperties() { SpringApplicationBuilder application = new SpringApplicationBuilder().sources(ExampleConfig.class) - .contextClass(StaticApplicationContext.class).profiles("foo").properties("foo=bar"); + .contextFactory(ApplicationContextFactory.forContextClass(StaticApplicationContext.class)) + .profiles("foo").properties("foo=bar"); this.context = application.run(); assertThat(this.context).isInstanceOf(StaticApplicationContext.class); assertThat(this.context.getEnvironment().getProperty("foo")).isEqualTo("bucket"); @@ -78,7 +80,8 @@ class SpringApplicationBuilderTests { @Test void propertiesAsMap() { SpringApplicationBuilder application = new SpringApplicationBuilder().sources(ExampleConfig.class) - .contextClass(StaticApplicationContext.class).properties(Collections.singletonMap("bar", "foo")); + .contextFactory(ApplicationContextFactory.forContextClass(StaticApplicationContext.class)) + .properties(Collections.singletonMap("bar", "foo")); this.context = application.run(); assertThat(this.context.getEnvironment().getProperty("bar")).isEqualTo("foo"); } @@ -86,7 +89,7 @@ class SpringApplicationBuilderTests { @Test void propertiesAsProperties() { SpringApplicationBuilder application = new SpringApplicationBuilder().sources(ExampleConfig.class) - .contextClass(StaticApplicationContext.class) + .contextFactory(ApplicationContextFactory.forContextClass(StaticApplicationContext.class)) .properties(StringUtils.splitArrayElementsIntoProperties(new String[] { "bar=foo" }, "=")); this.context = application.run(); assertThat(this.context.getEnvironment().getProperty("bar")).isEqualTo("foo"); @@ -95,7 +98,7 @@ class SpringApplicationBuilderTests { @Test void propertiesWithRepeatSeparator() { SpringApplicationBuilder application = new SpringApplicationBuilder().sources(ExampleConfig.class) - .contextClass(StaticApplicationContext.class) + .contextFactory(ApplicationContextFactory.forContextClass(StaticApplicationContext.class)) .properties("one=c:\\logging.file.name", "two=a:b", "three:c:\\logging.file.name", "four:a:b"); this.context = application.run(); ConfigurableEnvironment environment = this.context.getEnvironment(); @@ -106,6 +109,7 @@ class SpringApplicationBuilderTests { } @Test + @SuppressWarnings("deprecation") void specificApplicationContextClass() { SpringApplicationBuilder application = new SpringApplicationBuilder().sources(ExampleConfig.class) .contextClass(StaticApplicationContext.class); @@ -113,10 +117,18 @@ class SpringApplicationBuilderTests { assertThat(this.context).isInstanceOf(StaticApplicationContext.class); } + @Test + void specificApplicationContextFactory() { + SpringApplicationBuilder application = new SpringApplicationBuilder().sources(ExampleConfig.class) + .contextFactory(ApplicationContextFactory.forContextClass(StaticApplicationContext.class)); + this.context = application.run(); + assertThat(this.context).isInstanceOf(StaticApplicationContext.class); + } + @Test void parentContextCreationThatIsRunDirectly() { SpringApplicationBuilder application = new SpringApplicationBuilder(ChildConfig.class) - .contextClass(SpyApplicationContext.class); + .contextFactory(ApplicationContextFactory.forContextClass(SpyApplicationContext.class)); application.parent(ExampleConfig.class); this.context = application.run("foo.bar=baz"); verify(((SpyApplicationContext) this.context).getApplicationContext()).setParent(any(ApplicationContext.class)); @@ -129,7 +141,7 @@ class SpringApplicationBuilderTests { @Test void parentContextCreationThatIsBuiltThenRun() { SpringApplicationBuilder application = new SpringApplicationBuilder(ChildConfig.class) - .contextClass(SpyApplicationContext.class); + .contextFactory(ApplicationContextFactory.forContextClass(SpyApplicationContext.class)); application.parent(ExampleConfig.class); this.context = application.build("a=alpha").run("b=bravo"); verify(((SpyApplicationContext) this.context).getApplicationContext()).setParent(any(ApplicationContext.class)); @@ -141,7 +153,8 @@ class SpringApplicationBuilderTests { @Test void parentContextCreationWithChildShutdown() { SpringApplicationBuilder application = new SpringApplicationBuilder(ChildConfig.class) - .contextClass(SpyApplicationContext.class).registerShutdownHook(true); + .contextFactory(ApplicationContextFactory.forContextClass(SpyApplicationContext.class)) + .registerShutdownHook(true); application.parent(ExampleConfig.class); this.context = application.run(); verify(((SpyApplicationContext) this.context).getApplicationContext()).setParent(any(ApplicationContext.class)); @@ -151,7 +164,7 @@ class SpringApplicationBuilderTests { @Test void contextWithClassLoader() { SpringApplicationBuilder application = new SpringApplicationBuilder(ExampleConfig.class) - .contextClass(SpyApplicationContext.class); + .contextFactory(ApplicationContextFactory.forContextClass(SpyApplicationContext.class)); ClassLoader classLoader = new URLClassLoader(new URL[0], getClass().getClassLoader()); application.resourceLoader(new DefaultResourceLoader(classLoader)); this.context = application.run(); @@ -161,7 +174,7 @@ class SpringApplicationBuilderTests { @Test void parentContextWithClassLoader() { SpringApplicationBuilder application = new SpringApplicationBuilder(ChildConfig.class) - .contextClass(SpyApplicationContext.class); + .contextFactory(ApplicationContextFactory.forContextClass(SpyApplicationContext.class)); ClassLoader classLoader = new URLClassLoader(new URL[0], getClass().getClassLoader()); application.resourceLoader(new DefaultResourceLoader(classLoader)); application.parent(ExampleConfig.class); @@ -173,7 +186,7 @@ class SpringApplicationBuilderTests { void parentFirstCreation() { SpringApplicationBuilder application = new SpringApplicationBuilder(ExampleConfig.class) .child(ChildConfig.class); - application.contextClass(SpyApplicationContext.class); + application.contextFactory(ApplicationContextFactory.forContextClass(SpyApplicationContext.class)); this.context = application.run(); verify(((SpyApplicationContext) this.context).getApplicationContext()).setParent(any(ApplicationContext.class)); assertThat(((SpyApplicationContext) this.context).getRegisteredShutdownHook()).isFalse(); @@ -230,7 +243,7 @@ class SpringApplicationBuilderTests { void parentContextIdentical() { SpringApplicationBuilder application = new SpringApplicationBuilder(ExampleConfig.class); application.parent(ExampleConfig.class); - application.contextClass(SpyApplicationContext.class); + application.contextFactory(ApplicationContextFactory.forContextClass(SpyApplicationContext.class)); this.context = application.run(); verify(((SpyApplicationContext) this.context).getApplicationContext()).setParent(any(ApplicationContext.class)); }