Avoid using reflection to create SpringApplication's context

Closes gh-22322
pull/22366/head
Andy Wilkinson 4 years ago
parent 0cd83007e9
commit 0c8e52e877

@ -110,7 +110,8 @@ public class SpringBootContextLoader extends AbstractContextLoader {
else if (config instanceof ReactiveWebMergedContextConfiguration) { else if (config instanceof ReactiveWebMergedContextConfiguration) {
application.setWebApplicationType(WebApplicationType.REACTIVE); application.setWebApplicationType(WebApplicationType.REACTIVE);
if (!isEmbeddedWebEnvironment(config)) { if (!isEmbeddedWebEnvironment(config)) {
new ReactiveWebConfigurer().configure(application); application.setApplicationContextFactory(
(webApplicationType) -> new GenericReactiveWebApplicationContext());
} }
} }
else { else {
@ -250,13 +251,11 @@ public class SpringBootContextLoader extends AbstractContextLoader {
*/ */
private static class WebConfigurer { private static class WebConfigurer {
private static final Class<GenericWebApplicationContext> WEB_CONTEXT_CLASS = GenericWebApplicationContext.class;
void configure(MergedContextConfiguration configuration, SpringApplication application, void configure(MergedContextConfiguration configuration, SpringApplication application,
List<ApplicationContextInitializer<?>> initializers) { List<ApplicationContextInitializer<?>> initializers) {
WebMergedContextConfiguration webConfiguration = (WebMergedContextConfiguration) configuration; WebMergedContextConfiguration webConfiguration = (WebMergedContextConfiguration) configuration;
addMockServletContext(initializers, webConfiguration); addMockServletContext(initializers, webConfiguration);
application.setApplicationContextClass(WEB_CONTEXT_CLASS); application.setApplicationContextFactory((webApplicationType) -> new GenericWebApplicationContext());
} }
private void addMockServletContext(List<ApplicationContextInitializer<?>> initializers, private void addMockServletContext(List<ApplicationContextInitializer<?>> initializers,
@ -268,19 +267,6 @@ public class SpringBootContextLoader extends AbstractContextLoader {
} }
/**
* Inner class to configure {@link ReactiveWebMergedContextConfiguration}.
*/
private static class ReactiveWebConfigurer {
private static final Class<GenericReactiveWebApplicationContext> WEB_CONTEXT_CLASS = GenericReactiveWebApplicationContext.class;
void configure(SpringApplication application) {
application.setApplicationContextClass(WEB_CONTEXT_CLASS);
}
}
/** /**
* Adapts a {@link ContextCustomizer} to a {@link ApplicationContextInitializer} so * Adapts a {@link ContextCustomizer} to a {@link ApplicationContextInitializer} so
* that it can be triggered via {@link SpringApplication}. * that it can be triggered via {@link SpringApplication}.

@ -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<? extends ConfigurableApplicationContext> contextClass) {
return (webApplicationType) -> BeanUtils.instantiateClass(contextClass);
}
}

@ -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.bind.Binder;
import org.springframework.boot.context.properties.source.ConfigurationPropertySources; import org.springframework.boot.context.properties.source.ConfigurationPropertySources;
import org.springframework.boot.convert.ApplicationConversionService; 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.reactive.context.StandardReactiveWebEnvironment;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ApplicationListener; 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 * The class name of application context that will be used by default for non-web
* environments. * environments.
* @deprecated since 2.4.0 in favour of using a {@link ApplicationContextFactory}
*/ */
@Deprecated
public static final String DEFAULT_CONTEXT_CLASS = "org.springframework.context." public static final String DEFAULT_CONTEXT_CLASS = "org.springframework.context."
+ "annotation.AnnotationConfigApplicationContext"; + "annotation.AnnotationConfigApplicationContext";
/** /**
* The class name of application context that will be used by default for web * The class name of application context that will be used by default for web
* environments. * 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." public static final String DEFAULT_SERVLET_WEB_CONTEXT_CLASS = "org.springframework.boot."
+ "web.servlet.context.AnnotationConfigServletWebServerApplicationContext"; + "web.servlet.context.AnnotationConfigServletWebServerApplicationContext";
/** /**
* The class name of application context that will be used by default for reactive web * The class name of application context that will be used by default for reactive web
* environments. * 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." public static final String DEFAULT_REACTIVE_WEB_CONTEXT_CLASS = "org.springframework."
+ "boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext"; + "boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext";
@ -217,8 +225,6 @@ public class SpringApplication {
private ConfigurableEnvironment environment; private ConfigurableEnvironment environment;
private Class<? extends ConfigurableApplicationContext> applicationContextClass;
private WebApplicationType webApplicationType; private WebApplicationType webApplicationType;
private boolean headless = true; private boolean headless = true;
@ -239,6 +245,8 @@ public class SpringApplication {
private boolean lazyInitialization = false; private boolean lazyInitialization = false;
private ApplicationContextFactory applicationContextFactory = new DefaultApplicationContextFactory();
/** /**
* Create a new {@link SpringApplication} instance. The application context will load * Create a new {@link SpringApplication} instance. The application context will load
* beans from the specified primary sources (see {@link SpringApplication class-level} * 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 * Strategy method used to create the {@link ApplicationContext}. By default this
* method will respect any explicitly set application context or application context * method will respect any explicitly set application context class or factory before
* class before falling back to a suitable default. * falling back to a suitable default.
* @return the application context (not yet refreshed) * @return the application context (not yet refreshed)
* @see #setApplicationContextClass(Class) * @see #setApplicationContextClass(Class)
* @see #setApplicationContextFactory(ApplicationContextFactory)
*/ */
protected ConfigurableApplicationContext createApplicationContext() { protected ConfigurableApplicationContext createApplicationContext() {
Class<?> contextClass = this.applicationContextClass; return this.applicationContextFactory.create(this.webApplicationType);
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);
} }
/** /**
@ -1154,10 +1144,27 @@ public class SpringApplication {
* applications or {@link AnnotationConfigApplicationContext} for non web based * applications or {@link AnnotationConfigApplicationContext} for non web based
* applications. * applications.
* @param applicationContextClass the context class to set * @param applicationContextClass the context class to set
* @deprecated since 2.4.0 in favor of
* {@link #setApplicationContextFactory(ApplicationContextFactory)}
*/ */
@Deprecated
public void setApplicationContextClass(Class<? extends ConfigurableApplicationContext> applicationContextClass) { public void setApplicationContextClass(Class<? extends ConfigurableApplicationContext> applicationContextClass) {
this.applicationContextClass = applicationContextClass;
this.webApplicationType = WebApplicationType.deduceFromApplicationContext(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); 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);
}
}
}
} }

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 java.util.concurrent.atomic.AtomicBoolean;
import org.springframework.beans.factory.support.BeanNameGenerator; import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.boot.ApplicationContextFactory;
import org.springframework.boot.Banner; import org.springframework.boot.Banner;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.WebApplicationType; import org.springframework.boot.WebApplicationType;
@ -272,12 +273,26 @@ public class SpringApplicationBuilder {
* Explicitly set the context class to be used. * Explicitly set the context class to be used.
* @param cls the context class to use * @param cls the context class to use
* @return the current builder * @return the current builder
* @deprecated since 2.4.0 in favor of
* {@link #contextFactory(ApplicationContextFactory)}
*/ */
@Deprecated
public SpringApplicationBuilder contextClass(Class<? extends ConfigurableApplicationContext> cls) { public SpringApplicationBuilder contextClass(Class<? extends ConfigurableApplicationContext> cls) {
this.application.setApplicationContextClass(cls); this.application.setApplicationContextClass(cls);
return this; 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. * Add more sources (configuration classes and components) to this application.
* @param sources the sources to add * @param sources the sources to add

@ -134,7 +134,7 @@ public abstract class SpringBootServletInitializer implements WebApplicationInit
builder.initializers(new ParentContextApplicationContextInitializer(parent)); builder.initializers(new ParentContextApplicationContextInitializer(parent));
} }
builder.initializers(new ServletContextApplicationContextInitializer(servletContext)); builder.initializers(new ServletContextApplicationContextInitializer(servletContext));
builder.contextClass(AnnotationConfigServletWebServerApplicationContext.class); builder.contextFactory((webApplicationType) -> new AnnotationConfigServletWebServerApplicationContext());
builder = configure(builder); builder = configure(builder);
builder.listeners(new WebEnvironmentPropertySourceInitializer(servletContext)); builder.listeners(new WebEnvironmentPropertySourceInitializer(servletContext));
SpringApplication application = builder.build(); SpringApplication application = builder.build();

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -42,7 +42,8 @@ class SpringApplicationNoWebTests {
@Test @Test
void specificApplicationContextClass() { void specificApplicationContextClass() {
SpringApplication application = new SpringApplication(ExampleConfig.class); SpringApplication application = new SpringApplication(ExampleConfig.class);
application.setApplicationContextClass(StaticApplicationContext.class); application.setApplicationContextFactory(
ApplicationContextFactory.forContextClass(StaticApplicationContext.class));
ConfigurableApplicationContext context = application.run(); ConfigurableApplicationContext context = application.run();
assertThat(context).isInstanceOf(StaticApplicationContext.class); assertThat(context).isInstanceOf(StaticApplicationContext.class);
context.close(); context.close();

@ -320,6 +320,7 @@ class SpringApplicationTests {
} }
@Test @Test
@SuppressWarnings("deprecation")
void specificApplicationContextClass() { void specificApplicationContextClass() {
SpringApplication application = new SpringApplication(ExampleConfig.class); SpringApplication application = new SpringApplication(ExampleConfig.class);
application.setApplicationContextClass(StaticApplicationContext.class); application.setApplicationContextClass(StaticApplicationContext.class);
@ -328,6 +329,16 @@ class SpringApplicationTests {
} }
@Test @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() { void specificWebApplicationContextClassDetectWebApplicationType() {
SpringApplication application = new SpringApplication(ExampleConfig.class); SpringApplication application = new SpringApplication(ExampleConfig.class);
application.setApplicationContextClass(AnnotationConfigServletWebApplicationContext.class); application.setApplicationContextClass(AnnotationConfigServletWebApplicationContext.class);
@ -335,6 +346,7 @@ class SpringApplicationTests {
} }
@Test @Test
@SuppressWarnings("deprecation")
void specificReactiveApplicationContextClassDetectReactiveApplicationType() { void specificReactiveApplicationContextClassDetectReactiveApplicationType() {
SpringApplication application = new SpringApplication(ExampleConfig.class); SpringApplication application = new SpringApplication(ExampleConfig.class);
application.setApplicationContextClass(AnnotationConfigReactiveWebApplicationContext.class); application.setApplicationContextClass(AnnotationConfigReactiveWebApplicationContext.class);
@ -342,6 +354,7 @@ class SpringApplicationTests {
} }
@Test @Test
@SuppressWarnings("deprecation")
void nonWebNorReactiveApplicationContextClassDetectNoneApplicationType() { void nonWebNorReactiveApplicationContextClassDetectNoneApplicationType() {
SpringApplication application = new SpringApplication(ExampleConfig.class); SpringApplication application = new SpringApplication(ExampleConfig.class);
application.setApplicationContextClass(StaticApplicationContext.class); application.setApplicationContextClass(StaticApplicationContext.class);
@ -876,7 +889,8 @@ class SpringApplicationTests {
@Test @Test
void registerShutdownHook() { void registerShutdownHook() {
SpringApplication application = new SpringApplication(ExampleConfig.class); SpringApplication application = new SpringApplication(ExampleConfig.class);
application.setApplicationContextClass(SpyApplicationContext.class); application
.setApplicationContextFactory(ApplicationContextFactory.forContextClass(SpyApplicationContext.class));
this.context = application.run(); this.context = application.run();
SpyApplicationContext applicationContext = (SpyApplicationContext) this.context; SpyApplicationContext applicationContext = (SpyApplicationContext) this.context;
verify(applicationContext.getApplicationContext()).registerShutdownHook(); verify(applicationContext.getApplicationContext()).registerShutdownHook();
@ -885,7 +899,8 @@ class SpringApplicationTests {
@Test @Test
void registerListener() { void registerListener() {
SpringApplication application = new SpringApplication(ExampleConfig.class, ListenerConfig.class); SpringApplication application = new SpringApplication(ExampleConfig.class, ListenerConfig.class);
application.setApplicationContextClass(SpyApplicationContext.class); application
.setApplicationContextFactory(ApplicationContextFactory.forContextClass(SpyApplicationContext.class));
Set<ApplicationEvent> events = new LinkedHashSet<>(); Set<ApplicationEvent> events = new LinkedHashSet<>();
application.addListeners((ApplicationListener<ApplicationEvent>) events::add); application.addListeners((ApplicationListener<ApplicationEvent>) events::add);
this.context = application.run(); this.context = application.run();
@ -898,7 +913,8 @@ class SpringApplicationTests {
void registerListenerWithCustomMulticaster() { void registerListenerWithCustomMulticaster() {
SpringApplication application = new SpringApplication(ExampleConfig.class, ListenerConfig.class, SpringApplication application = new SpringApplication(ExampleConfig.class, ListenerConfig.class,
Multicaster.class); Multicaster.class);
application.setApplicationContextClass(SpyApplicationContext.class); application
.setApplicationContextFactory(ApplicationContextFactory.forContextClass(SpyApplicationContext.class));
Set<ApplicationEvent> events = new LinkedHashSet<>(); Set<ApplicationEvent> events = new LinkedHashSet<>();
application.addListeners((ApplicationListener<ApplicationEvent>) events::add); application.addListeners((ApplicationListener<ApplicationEvent>) events::add);
this.context = application.run(); this.context = application.run();
@ -978,7 +994,8 @@ class SpringApplicationTests {
@Test @Test
void registerShutdownHookOff() { void registerShutdownHookOff() {
SpringApplication application = new SpringApplication(ExampleConfig.class); SpringApplication application = new SpringApplication(ExampleConfig.class);
application.setApplicationContextClass(SpyApplicationContext.class); application
.setApplicationContextFactory(ApplicationContextFactory.forContextClass(SpyApplicationContext.class));
application.setRegisterShutdownHook(false); application.setRegisterShutdownHook(false);
this.context = application.run(); this.context = application.run();
SpyApplicationContext applicationContext = (SpyApplicationContext) this.context; SpyApplicationContext applicationContext = (SpyApplicationContext) this.context;

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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.junit.jupiter.api.Test;
import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationContextFactory;
import org.springframework.boot.WebApplicationType; import org.springframework.boot.WebApplicationType;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.ConfigurableApplicationContext;
@ -68,7 +69,8 @@ class SpringApplicationBuilderTests {
@Test @Test
void profileAndProperties() { void profileAndProperties() {
SpringApplicationBuilder application = new SpringApplicationBuilder().sources(ExampleConfig.class) 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(); this.context = application.run();
assertThat(this.context).isInstanceOf(StaticApplicationContext.class); assertThat(this.context).isInstanceOf(StaticApplicationContext.class);
assertThat(this.context.getEnvironment().getProperty("foo")).isEqualTo("bucket"); assertThat(this.context.getEnvironment().getProperty("foo")).isEqualTo("bucket");
@ -78,7 +80,8 @@ class SpringApplicationBuilderTests {
@Test @Test
void propertiesAsMap() { void propertiesAsMap() {
SpringApplicationBuilder application = new SpringApplicationBuilder().sources(ExampleConfig.class) 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(); this.context = application.run();
assertThat(this.context.getEnvironment().getProperty("bar")).isEqualTo("foo"); assertThat(this.context.getEnvironment().getProperty("bar")).isEqualTo("foo");
} }
@ -86,7 +89,7 @@ class SpringApplicationBuilderTests {
@Test @Test
void propertiesAsProperties() { void propertiesAsProperties() {
SpringApplicationBuilder application = new SpringApplicationBuilder().sources(ExampleConfig.class) SpringApplicationBuilder application = new SpringApplicationBuilder().sources(ExampleConfig.class)
.contextClass(StaticApplicationContext.class) .contextFactory(ApplicationContextFactory.forContextClass(StaticApplicationContext.class))
.properties(StringUtils.splitArrayElementsIntoProperties(new String[] { "bar=foo" }, "=")); .properties(StringUtils.splitArrayElementsIntoProperties(new String[] { "bar=foo" }, "="));
this.context = application.run(); this.context = application.run();
assertThat(this.context.getEnvironment().getProperty("bar")).isEqualTo("foo"); assertThat(this.context.getEnvironment().getProperty("bar")).isEqualTo("foo");
@ -95,7 +98,7 @@ class SpringApplicationBuilderTests {
@Test @Test
void propertiesWithRepeatSeparator() { void propertiesWithRepeatSeparator() {
SpringApplicationBuilder application = new SpringApplicationBuilder().sources(ExampleConfig.class) 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"); .properties("one=c:\\logging.file.name", "two=a:b", "three:c:\\logging.file.name", "four:a:b");
this.context = application.run(); this.context = application.run();
ConfigurableEnvironment environment = this.context.getEnvironment(); ConfigurableEnvironment environment = this.context.getEnvironment();
@ -106,6 +109,7 @@ class SpringApplicationBuilderTests {
} }
@Test @Test
@SuppressWarnings("deprecation")
void specificApplicationContextClass() { void specificApplicationContextClass() {
SpringApplicationBuilder application = new SpringApplicationBuilder().sources(ExampleConfig.class) SpringApplicationBuilder application = new SpringApplicationBuilder().sources(ExampleConfig.class)
.contextClass(StaticApplicationContext.class); .contextClass(StaticApplicationContext.class);
@ -113,10 +117,18 @@ class SpringApplicationBuilderTests {
assertThat(this.context).isInstanceOf(StaticApplicationContext.class); 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 @Test
void parentContextCreationThatIsRunDirectly() { void parentContextCreationThatIsRunDirectly() {
SpringApplicationBuilder application = new SpringApplicationBuilder(ChildConfig.class) SpringApplicationBuilder application = new SpringApplicationBuilder(ChildConfig.class)
.contextClass(SpyApplicationContext.class); .contextFactory(ApplicationContextFactory.forContextClass(SpyApplicationContext.class));
application.parent(ExampleConfig.class); application.parent(ExampleConfig.class);
this.context = application.run("foo.bar=baz"); this.context = application.run("foo.bar=baz");
verify(((SpyApplicationContext) this.context).getApplicationContext()).setParent(any(ApplicationContext.class)); verify(((SpyApplicationContext) this.context).getApplicationContext()).setParent(any(ApplicationContext.class));
@ -129,7 +141,7 @@ class SpringApplicationBuilderTests {
@Test @Test
void parentContextCreationThatIsBuiltThenRun() { void parentContextCreationThatIsBuiltThenRun() {
SpringApplicationBuilder application = new SpringApplicationBuilder(ChildConfig.class) SpringApplicationBuilder application = new SpringApplicationBuilder(ChildConfig.class)
.contextClass(SpyApplicationContext.class); .contextFactory(ApplicationContextFactory.forContextClass(SpyApplicationContext.class));
application.parent(ExampleConfig.class); application.parent(ExampleConfig.class);
this.context = application.build("a=alpha").run("b=bravo"); this.context = application.build("a=alpha").run("b=bravo");
verify(((SpyApplicationContext) this.context).getApplicationContext()).setParent(any(ApplicationContext.class)); verify(((SpyApplicationContext) this.context).getApplicationContext()).setParent(any(ApplicationContext.class));
@ -141,7 +153,8 @@ class SpringApplicationBuilderTests {
@Test @Test
void parentContextCreationWithChildShutdown() { void parentContextCreationWithChildShutdown() {
SpringApplicationBuilder application = new SpringApplicationBuilder(ChildConfig.class) SpringApplicationBuilder application = new SpringApplicationBuilder(ChildConfig.class)
.contextClass(SpyApplicationContext.class).registerShutdownHook(true); .contextFactory(ApplicationContextFactory.forContextClass(SpyApplicationContext.class))
.registerShutdownHook(true);
application.parent(ExampleConfig.class); application.parent(ExampleConfig.class);
this.context = application.run(); this.context = application.run();
verify(((SpyApplicationContext) this.context).getApplicationContext()).setParent(any(ApplicationContext.class)); verify(((SpyApplicationContext) this.context).getApplicationContext()).setParent(any(ApplicationContext.class));
@ -151,7 +164,7 @@ class SpringApplicationBuilderTests {
@Test @Test
void contextWithClassLoader() { void contextWithClassLoader() {
SpringApplicationBuilder application = new SpringApplicationBuilder(ExampleConfig.class) SpringApplicationBuilder application = new SpringApplicationBuilder(ExampleConfig.class)
.contextClass(SpyApplicationContext.class); .contextFactory(ApplicationContextFactory.forContextClass(SpyApplicationContext.class));
ClassLoader classLoader = new URLClassLoader(new URL[0], getClass().getClassLoader()); ClassLoader classLoader = new URLClassLoader(new URL[0], getClass().getClassLoader());
application.resourceLoader(new DefaultResourceLoader(classLoader)); application.resourceLoader(new DefaultResourceLoader(classLoader));
this.context = application.run(); this.context = application.run();
@ -161,7 +174,7 @@ class SpringApplicationBuilderTests {
@Test @Test
void parentContextWithClassLoader() { void parentContextWithClassLoader() {
SpringApplicationBuilder application = new SpringApplicationBuilder(ChildConfig.class) SpringApplicationBuilder application = new SpringApplicationBuilder(ChildConfig.class)
.contextClass(SpyApplicationContext.class); .contextFactory(ApplicationContextFactory.forContextClass(SpyApplicationContext.class));
ClassLoader classLoader = new URLClassLoader(new URL[0], getClass().getClassLoader()); ClassLoader classLoader = new URLClassLoader(new URL[0], getClass().getClassLoader());
application.resourceLoader(new DefaultResourceLoader(classLoader)); application.resourceLoader(new DefaultResourceLoader(classLoader));
application.parent(ExampleConfig.class); application.parent(ExampleConfig.class);
@ -173,7 +186,7 @@ class SpringApplicationBuilderTests {
void parentFirstCreation() { void parentFirstCreation() {
SpringApplicationBuilder application = new SpringApplicationBuilder(ExampleConfig.class) SpringApplicationBuilder application = new SpringApplicationBuilder(ExampleConfig.class)
.child(ChildConfig.class); .child(ChildConfig.class);
application.contextClass(SpyApplicationContext.class); application.contextFactory(ApplicationContextFactory.forContextClass(SpyApplicationContext.class));
this.context = application.run(); this.context = application.run();
verify(((SpyApplicationContext) this.context).getApplicationContext()).setParent(any(ApplicationContext.class)); verify(((SpyApplicationContext) this.context).getApplicationContext()).setParent(any(ApplicationContext.class));
assertThat(((SpyApplicationContext) this.context).getRegisteredShutdownHook()).isFalse(); assertThat(((SpyApplicationContext) this.context).getRegisteredShutdownHook()).isFalse();
@ -230,7 +243,7 @@ class SpringApplicationBuilderTests {
void parentContextIdentical() { void parentContextIdentical() {
SpringApplicationBuilder application = new SpringApplicationBuilder(ExampleConfig.class); SpringApplicationBuilder application = new SpringApplicationBuilder(ExampleConfig.class);
application.parent(ExampleConfig.class); application.parent(ExampleConfig.class);
application.contextClass(SpyApplicationContext.class); application.contextFactory(ApplicationContextFactory.forContextClass(SpyApplicationContext.class));
this.context = application.run(); this.context = application.run();
verify(((SpyApplicationContext) this.context).getApplicationContext()).setParent(any(ApplicationContext.class)); verify(((SpyApplicationContext) this.context).getApplicationContext()).setParent(any(ApplicationContext.class));
} }

Loading…
Cancel
Save