Add SpringApplicationBuilder
Builder for SpringApplication and ApplicationContext instances with
convenient fluent API and context hierarchy support. Simple example
of a context hierarchy:
new SpringApplicationBuilder(ParentConfig.class)
.child(ChildConfig.class).run(args);
Another common use case is setting default arguments, e.g.
active Spring profiles, to set up the environment for an application:
new SpringApplicationBuilder(Application.class).profiles("server")
.defaultArgs("--transport=local").run(args);
If your needs are simpler, consider using the static convenience
methods in SpringApplication instead.
[#49703716] [bs-116] Parent context for some beans maybe?
This commit is contained in:
@@ -40,7 +40,7 @@ import org.springframework.web.servlet.HandlerAdapter;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
|
||||
/**
|
||||
* Configuration for triggered from {@link EndpointWebMvcAutoConfiguration} when a new
|
||||
* Configuration triggered from {@link EndpointWebMvcAutoConfiguration} when a new
|
||||
* {@link EmbeddedServletContainer} running on a different port is required.
|
||||
*
|
||||
* @see EndpointWebMvcAutoConfiguration
|
||||
|
||||
@@ -24,12 +24,11 @@ import java.nio.charset.Charset;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.TestUtils;
|
||||
import org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.ManagementServerPropertiesAutoConfiguration;
|
||||
import org.springframework.boot.actuate.endpoint.AbstractEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.Endpoint;
|
||||
import org.springframework.boot.actuate.properties.ManagementServerProperties;
|
||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration;
|
||||
@@ -72,7 +71,7 @@ public class EndpointWebMvcAutoConfigurationTests {
|
||||
this.applicationContext.register(RootConfig.class,
|
||||
PropertyPlaceholderAutoConfiguration.class,
|
||||
EmbeddedServletContainerAutoConfiguration.class,
|
||||
WebMvcAutoConfiguration.class,
|
||||
DispatcherServletAutoConfiguration.class, WebMvcAutoConfiguration.class,
|
||||
ManagementServerPropertiesAutoConfiguration.class,
|
||||
EndpointWebMvcAutoConfiguration.class);
|
||||
this.applicationContext.refresh();
|
||||
@@ -89,7 +88,7 @@ public class EndpointWebMvcAutoConfigurationTests {
|
||||
this.applicationContext.register(RootConfig.class, DifferentPortConfig.class,
|
||||
PropertyPlaceholderAutoConfiguration.class,
|
||||
EmbeddedServletContainerAutoConfiguration.class,
|
||||
WebMvcAutoConfiguration.class,
|
||||
DispatcherServletAutoConfiguration.class, WebMvcAutoConfiguration.class,
|
||||
ManagementServerPropertiesAutoConfiguration.class,
|
||||
EndpointWebMvcAutoConfiguration.class);
|
||||
this.applicationContext.refresh();
|
||||
@@ -106,7 +105,7 @@ public class EndpointWebMvcAutoConfigurationTests {
|
||||
this.applicationContext.register(RootConfig.class, DisableConfig.class,
|
||||
PropertyPlaceholderAutoConfiguration.class,
|
||||
EmbeddedServletContainerAutoConfiguration.class,
|
||||
WebMvcAutoConfiguration.class,
|
||||
DispatcherServletAutoConfiguration.class, WebMvcAutoConfiguration.class,
|
||||
ManagementServerPropertiesAutoConfiguration.class,
|
||||
EndpointWebMvcAutoConfiguration.class);
|
||||
this.applicationContext.refresh();
|
||||
@@ -127,7 +126,8 @@ public class EndpointWebMvcAutoConfigurationTests {
|
||||
ManagementServerPropertiesAutoConfiguration.class,
|
||||
ServerPropertiesAutoConfiguration.class,
|
||||
EmbeddedServletContainerAutoConfiguration.class,
|
||||
WebMvcAutoConfiguration.class, EndpointWebMvcAutoConfiguration.class);
|
||||
DispatcherServletAutoConfiguration.class, WebMvcAutoConfiguration.class,
|
||||
EndpointWebMvcAutoConfiguration.class);
|
||||
this.applicationContext.refresh();
|
||||
assertContent("/controller", 7070, "controlleroutput");
|
||||
assertContent("/endpoint", 7070, null);
|
||||
@@ -145,7 +145,8 @@ public class EndpointWebMvcAutoConfigurationTests {
|
||||
ManagementServerPropertiesAutoConfiguration.class,
|
||||
ServerPropertiesAutoConfiguration.class,
|
||||
EmbeddedServletContainerAutoConfiguration.class,
|
||||
WebMvcAutoConfiguration.class, EndpointWebMvcAutoConfiguration.class);
|
||||
DispatcherServletAutoConfiguration.class, WebMvcAutoConfiguration.class,
|
||||
EndpointWebMvcAutoConfiguration.class);
|
||||
this.applicationContext.refresh();
|
||||
assertContent("/controller", 8080, "controlleroutput");
|
||||
assertContent("/test/endpoint", 8080, "endpointoutput");
|
||||
|
||||
@@ -21,9 +21,11 @@ import java.util.Arrays;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
|
||||
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ConditionContext;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
@@ -34,8 +36,8 @@ import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||
import org.springframework.web.servlet.DispatcherServlet;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for an the Spring
|
||||
* {@link DispatcherServlet} servlet containers.
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for the Spring
|
||||
* {@link DispatcherServlet} where an embedded servlet container is already present.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Dave Syer
|
||||
@@ -44,6 +46,7 @@ import org.springframework.web.servlet.DispatcherServlet;
|
||||
@Configuration
|
||||
@ConditionalOnWebApplication
|
||||
@ConditionalOnClass(DispatcherServlet.class)
|
||||
@ConditionalOnBean(EmbeddedServletContainerFactory.class)
|
||||
@AutoConfigureAfter(EmbeddedServletContainerAutoConfiguration.class)
|
||||
public class DispatcherServletAutoConfiguration {
|
||||
|
||||
|
||||
@@ -22,8 +22,6 @@ import org.junit.After;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.MultipartAutoConfiguration;
|
||||
import org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext;
|
||||
import org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainerFactory;
|
||||
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
|
||||
@@ -68,6 +66,7 @@ public class MultipartAutoConfigurationTests {
|
||||
this.context = new AnnotationConfigEmbeddedWebApplicationContext(
|
||||
ContainerWithNothing.class,
|
||||
EmbeddedServletContainerAutoConfiguration.class,
|
||||
DispatcherServletAutoConfiguration.class,
|
||||
MultipartAutoConfiguration.class);
|
||||
DispatcherServlet servlet = this.context.getBean(DispatcherServlet.class);
|
||||
assertNull(servlet.getMultipartResolver());
|
||||
@@ -86,6 +85,7 @@ public class MultipartAutoConfigurationTests {
|
||||
this.context = new AnnotationConfigEmbeddedWebApplicationContext(
|
||||
ContainerWithNoMultipartJetty.class,
|
||||
EmbeddedServletContainerAutoConfiguration.class,
|
||||
DispatcherServletAutoConfiguration.class,
|
||||
MultipartAutoConfiguration.class);
|
||||
DispatcherServlet servlet = this.context.getBean(DispatcherServlet.class);
|
||||
assertNull(servlet.getMultipartResolver());
|
||||
@@ -114,6 +114,7 @@ public class MultipartAutoConfigurationTests {
|
||||
this.context = new AnnotationConfigEmbeddedWebApplicationContext(
|
||||
ContainerWithNoMultipartTomcat.class,
|
||||
EmbeddedServletContainerAutoConfiguration.class,
|
||||
DispatcherServletAutoConfiguration.class,
|
||||
MultipartAutoConfiguration.class);
|
||||
DispatcherServlet servlet = this.context.getBean(DispatcherServlet.class);
|
||||
assertNull(servlet.getMultipartResolver());
|
||||
@@ -129,6 +130,7 @@ public class MultipartAutoConfigurationTests {
|
||||
this.context = new AnnotationConfigEmbeddedWebApplicationContext(
|
||||
ContainerWithEverythingJetty.class,
|
||||
EmbeddedServletContainerAutoConfiguration.class,
|
||||
DispatcherServletAutoConfiguration.class,
|
||||
MultipartAutoConfiguration.class);
|
||||
this.context.getBean(MultipartConfigElement.class);
|
||||
assertSame(this.context.getBean(DispatcherServlet.class).getMultipartResolver(),
|
||||
@@ -141,6 +143,7 @@ public class MultipartAutoConfigurationTests {
|
||||
this.context = new AnnotationConfigEmbeddedWebApplicationContext(
|
||||
ContainerWithEverythingTomcat.class,
|
||||
EmbeddedServletContainerAutoConfiguration.class,
|
||||
DispatcherServletAutoConfiguration.class,
|
||||
MultipartAutoConfiguration.class);
|
||||
this.context.getBean(MultipartConfigElement.class);
|
||||
assertSame(this.context.getBean(DispatcherServlet.class).getMultipartResolver(),
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration;
|
||||
import org.springframework.boot.sample.tomcat.service.HelloWorldService;
|
||||
@@ -54,7 +55,8 @@ public class NonAutoConfigurationSampleTomcatApplicationTests {
|
||||
|
||||
@Configuration
|
||||
@Import({ EmbeddedServletContainerAutoConfiguration.class,
|
||||
WebMvcAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class })
|
||||
DispatcherServletAutoConfiguration.class, WebMvcAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
@ComponentScan(basePackageClasses = { SampleController.class, HelloWorldService.class })
|
||||
public static class NonAutoConfigurationSampleTomcatApplication {
|
||||
|
||||
|
||||
@@ -155,9 +155,7 @@ public class SpringApplication {
|
||||
|
||||
private ConfigurableEnvironment environment;
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
private Class<? extends ApplicationContext> applicationContextClass;
|
||||
private Class<? extends ConfigurableApplicationContext> applicationContextClass;
|
||||
|
||||
private boolean webEnvironment;
|
||||
|
||||
@@ -245,7 +243,8 @@ public class SpringApplication {
|
||||
* @param args the application arguments (usually passed from a Java main method)
|
||||
* @return a running {@link ApplicationContext}
|
||||
*/
|
||||
public ApplicationContext run(String... args) {
|
||||
public ConfigurableApplicationContext run(String... args) {
|
||||
|
||||
StopWatch stopWatch = new StopWatch();
|
||||
stopWatch.start();
|
||||
|
||||
@@ -265,18 +264,15 @@ public class SpringApplication {
|
||||
}
|
||||
|
||||
// Create, load, refresh and run the ApplicationContext
|
||||
ApplicationContext context = createApplicationContext();
|
||||
if (context instanceof ConfigurableApplicationContext) {
|
||||
((ConfigurableApplicationContext) context).registerShutdownHook();
|
||||
((ConfigurableApplicationContext) context).setEnvironment(environment);
|
||||
}
|
||||
ConfigurableApplicationContext context = createApplicationContext();
|
||||
context.registerShutdownHook();
|
||||
context.setEnvironment(environment);
|
||||
postProcessApplicationContext(context);
|
||||
if (context instanceof ConfigurableApplicationContext) {
|
||||
applyInitializers((ConfigurableApplicationContext) context);
|
||||
}
|
||||
applyInitializers(context);
|
||||
if (this.logStartupInfo) {
|
||||
logStartupInfo();
|
||||
}
|
||||
|
||||
load(context, sources.toArray(new Object[sources.size()]));
|
||||
refresh(context);
|
||||
|
||||
@@ -288,6 +284,7 @@ public class SpringApplication {
|
||||
|
||||
runCommandLineRunners(context, args);
|
||||
return context;
|
||||
|
||||
}
|
||||
|
||||
private Set<Object> assembleSources() {
|
||||
@@ -310,10 +307,6 @@ public class SpringApplication {
|
||||
if (this.environment != null) {
|
||||
return this.environment;
|
||||
}
|
||||
if (this.applicationContext != null
|
||||
&& this.applicationContext.getEnvironment() instanceof ConfigurableEnvironment) {
|
||||
return (ConfigurableEnvironment) this.applicationContext.getEnvironment();
|
||||
}
|
||||
if (this.webEnvironment) {
|
||||
return new StandardServletEnvironment();
|
||||
}
|
||||
@@ -398,13 +391,9 @@ public class SpringApplication {
|
||||
* method will respect any explicitly set application context or application context
|
||||
* class before falling back to a suitable default.
|
||||
* @return the application context (not yet refreshed)
|
||||
* @see #setApplicationContext(ApplicationContext)
|
||||
* @see #setApplicationContextClass(Class)
|
||||
*/
|
||||
protected ApplicationContext createApplicationContext() {
|
||||
if (this.applicationContext != null) {
|
||||
return this.applicationContext;
|
||||
}
|
||||
protected ConfigurableApplicationContext createApplicationContext() {
|
||||
|
||||
Class<?> contextClass = this.applicationContextClass;
|
||||
if (contextClass == null) {
|
||||
@@ -420,7 +409,8 @@ public class SpringApplication {
|
||||
}
|
||||
}
|
||||
|
||||
return (ApplicationContext) BeanUtils.instantiate(contextClass);
|
||||
return (ConfigurableApplicationContext) BeanUtils.instantiate(contextClass);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -428,7 +418,7 @@ public class SpringApplication {
|
||||
* apply additional processing as required.
|
||||
* @param context the application context
|
||||
*/
|
||||
protected void postProcessApplicationContext(ApplicationContext context) {
|
||||
protected void postProcessApplicationContext(ConfigurableApplicationContext context) {
|
||||
if (this.webEnvironment) {
|
||||
if (context instanceof ConfigurableWebApplicationContext) {
|
||||
ConfigurableWebApplicationContext configurableContext = (ConfigurableWebApplicationContext) context;
|
||||
@@ -477,6 +467,10 @@ public class SpringApplication {
|
||||
if (context instanceof BeanDefinitionRegistry) {
|
||||
return (BeanDefinitionRegistry) context;
|
||||
}
|
||||
if (context instanceof AbstractApplicationContext) {
|
||||
return (BeanDefinitionRegistry) ((AbstractApplicationContext) context)
|
||||
.getBeanFactory();
|
||||
}
|
||||
throw new IllegalStateException("Could not locate BeanDefinitionRegistry");
|
||||
}
|
||||
|
||||
@@ -628,25 +622,12 @@ public class SpringApplication {
|
||||
* specified defaults to {@link #DEFAULT_WEB_CONTEXT_CLASS} for web based applications
|
||||
* or {@link AnnotationConfigApplicationContext} for non web based applications.
|
||||
* @param applicationContextClass the context class to set
|
||||
* @see #setApplicationContext(ApplicationContext)
|
||||
*/
|
||||
public void setApplicationContextClass(
|
||||
Class<? extends ApplicationContext> applicationContextClass) {
|
||||
Class<? extends ConfigurableApplicationContext> applicationContextClass) {
|
||||
this.applicationContextClass = applicationContextClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a Spring {@link ApplicationContext} that will be used for the application. If
|
||||
* not specified an {@link #DEFAULT_WEB_CONTEXT_CLASS} will be created for web based
|
||||
* applications or an {@link AnnotationConfigApplicationContext} for non web based
|
||||
* applications.
|
||||
* @param applicationContext the spring application context.
|
||||
* @see #setApplicationContextClass(Class)
|
||||
*/
|
||||
public void setApplicationContext(ApplicationContext applicationContext) {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link ApplicationContextInitializer} that will be applied to the Spring
|
||||
* {@link ApplicationContext}. Any existing initializers will be replaced.
|
||||
@@ -657,15 +638,6 @@ public class SpringApplication {
|
||||
this.initializers = new ArrayList<ApplicationContextInitializer<?>>(initializers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add {@link ApplicationContextInitializer}s to be applied to the Spring
|
||||
* {@link ApplicationContext} .
|
||||
* @param initializers the initializers to add
|
||||
*/
|
||||
public void addInitializers(ApplicationContextInitializer<?>... initializers) {
|
||||
this.initializers.addAll(Arrays.asList(initializers));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a mutable list of the {@link ApplicationContextInitializer}s that will be
|
||||
* applied to the Spring {@link ApplicationContext}.
|
||||
@@ -682,18 +654,18 @@ public class SpringApplication {
|
||||
* @param args the application arguments (usually passed from a Java main method)
|
||||
* @return the running {@link ApplicationContext}
|
||||
*/
|
||||
public static ApplicationContext run(Object source, String... args) {
|
||||
public static ConfigurableApplicationContext run(Object source, String... args) {
|
||||
return run(new Object[] { source }, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Static helper that can be used to run a {@link SpringApplication} from the
|
||||
* specified sources using default settings.
|
||||
* specified sources using default settings and user supplied arguments.
|
||||
* @param sources the sources to load
|
||||
* @param args the application arguments (usually passed from a Java main method)
|
||||
* @return the running {@link ApplicationContext}
|
||||
*/
|
||||
public static ApplicationContext run(Object[] sources, String[] args) {
|
||||
public static ConfigurableApplicationContext run(Object[] sources, String[] args) {
|
||||
return new SpringApplication(sources).run(args);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,405 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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
|
||||
*
|
||||
* http://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.builder;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.springframework.beans.factory.support.BeanNameGenerator;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.context.initializer.ParentContextApplicationContextInitializer;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextInitializer;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Builder for {@link SpringApplication} and {@link ApplicationContext} instances with
|
||||
* convenient fluent API and context hierarchy support. Simple example of a context
|
||||
* hierarchy:
|
||||
*
|
||||
* <pre>
|
||||
* new SpringApplicationBuilder(ParentConfig.class).child(ChildConfig.class).run(args);
|
||||
* </pre>
|
||||
*
|
||||
* Another common use case is setting default arguments, e.g. active Spring profiles, to
|
||||
* set up the environment for an application:
|
||||
*
|
||||
* <pre>
|
||||
* new SpringApplicationBuilder(Application.class).profiles("server")
|
||||
* .defaultArgs("--transport=local").run(args);
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* If your needs are simpler, consider using the static convenience methods in
|
||||
* SpringApplication instead.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class SpringApplicationBuilder {
|
||||
|
||||
private SpringApplication application;
|
||||
private ConfigurableApplicationContext context;
|
||||
private SpringApplicationBuilder parent;
|
||||
private AtomicBoolean running = new AtomicBoolean(false);
|
||||
private Set<Object> sources = new LinkedHashSet<Object>();
|
||||
private String[] defaultArgs;
|
||||
private ConfigurableEnvironment environment;
|
||||
|
||||
public SpringApplicationBuilder(Object... sources) {
|
||||
this.application = new SpringApplication(sources);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the current application context.
|
||||
*
|
||||
* @return the current application context (or null if not yet running)
|
||||
*/
|
||||
public ConfigurableApplicationContext context() {
|
||||
return this.context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for the current application.
|
||||
*
|
||||
* @return the current application (never null)
|
||||
*/
|
||||
public SpringApplication application() {
|
||||
return this.application;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an application context (and its parent if specified) with the command line
|
||||
* args provided. The parent is run first with the same arguments if has not yet been
|
||||
* started.
|
||||
*
|
||||
* @param args the command line arguments
|
||||
* @return an application context created from the current state
|
||||
*/
|
||||
public ConfigurableApplicationContext run(String... args) {
|
||||
|
||||
if (this.parent != null) {
|
||||
// If there is a parent initialize it and make sure it is added to the current
|
||||
// context
|
||||
addInitializers(new ParentContextApplicationContextInitializer(
|
||||
this.parent.run(args)));
|
||||
}
|
||||
|
||||
if (this.running.get()) {
|
||||
// If already created we just return the existing context
|
||||
return this.context;
|
||||
}
|
||||
|
||||
if (this.running.compareAndSet(false, true)) {
|
||||
synchronized (this.running) {
|
||||
// If not already running copy the sources over and then run.
|
||||
this.application.setSources(this.sources);
|
||||
this.context = this.application.run(args);
|
||||
}
|
||||
}
|
||||
|
||||
return this.context;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a child application with the provided sources. Default args and environment
|
||||
* are copied down into the child, but everything else is a clean sheet.
|
||||
*
|
||||
* @param sources the sources for the application (Spring configuration)
|
||||
* @return the child application nuilder
|
||||
*/
|
||||
public SpringApplicationBuilder child(Object... sources) {
|
||||
|
||||
SpringApplicationBuilder child = new SpringApplicationBuilder();
|
||||
child.sources(sources);
|
||||
|
||||
// Copy environment stuff from parent to child
|
||||
child.defaultArgs(this.defaultArgs).environment(this.environment);
|
||||
child.parent = this;
|
||||
|
||||
// It's not possible if embedded containers are enabled to support web contexts as
|
||||
// parents because the servlets cannot be initialized at the right point in
|
||||
// lifecycle.
|
||||
web(false);
|
||||
|
||||
// Probably not interested in multiple banners
|
||||
showBanner(false);
|
||||
|
||||
// Make sure sources get copied over
|
||||
this.application.setSources(this.sources);
|
||||
|
||||
return child;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a parent application with the provided sources. Default args and environment
|
||||
* are copied up into the parent, but everything else is a clean sheet.
|
||||
*
|
||||
* @param sources the sources for the application (Spring configuration)
|
||||
* @return the parent builder
|
||||
*/
|
||||
public SpringApplicationBuilder parent(Object... sources) {
|
||||
if (this.parent == null) {
|
||||
this.parent = new SpringApplicationBuilder(sources).web(false)
|
||||
.defaultArgs(this.defaultArgs).environment(this.environment);
|
||||
}
|
||||
else {
|
||||
this.parent.sources(sources);
|
||||
}
|
||||
return this.parent;
|
||||
}
|
||||
|
||||
private SpringApplicationBuilder runAndExtractParent(String... args) {
|
||||
if (this.context == null) {
|
||||
run(args);
|
||||
}
|
||||
if (this.parent != null) {
|
||||
return this.parent;
|
||||
}
|
||||
throw new IllegalStateException(
|
||||
"No parent defined yet (please use the other overloaded parent methods to set one)");
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an already running parent context to an existing application.
|
||||
*
|
||||
* @param parent the parent context
|
||||
* @return the current builder (not the parent)
|
||||
*/
|
||||
public SpringApplicationBuilder parent(ConfigurableApplicationContext parent) {
|
||||
this.parent = new SpringApplicationBuilder();
|
||||
this.parent.context = parent;
|
||||
this.parent.running.set(true);
|
||||
addInitializers(new ParentContextApplicationContextInitializer(parent));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a sibling application (one with the same parent). A side effect of calling
|
||||
* this method is that the current application (and its parent) are started.
|
||||
*
|
||||
* @param sources the sources for the application (Spring configuration)
|
||||
*
|
||||
* @return the new sibling builder
|
||||
*/
|
||||
public SpringApplicationBuilder sibling(Object... sources) {
|
||||
return runAndExtractParent().child(sources);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a sibling application (one with the same parent). A side effect of calling
|
||||
* this method is that the current application (and its parent) are started if they
|
||||
* are not already running.
|
||||
*
|
||||
* @param sources the sources for the application (Spring configuration)
|
||||
* @param args the command line arguments to use when starting the current app and its
|
||||
* parent
|
||||
*
|
||||
* @return the new sibling builder
|
||||
*/
|
||||
public SpringApplicationBuilder sibling(Object[] sources, String... args) {
|
||||
return runAndExtractParent(args).child(sources);
|
||||
}
|
||||
|
||||
/**
|
||||
* Explicitly set the context class to be used.
|
||||
*
|
||||
* @param cls the context class to use
|
||||
* @return the current builder
|
||||
*/
|
||||
public SpringApplicationBuilder contextClass(
|
||||
Class<? extends ConfigurableApplicationContext> cls) {
|
||||
this.application.setApplicationContextClass(cls);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add more sources to use in this application.
|
||||
*
|
||||
* @param sources the sources to add
|
||||
* @return the current builder
|
||||
*/
|
||||
public SpringApplicationBuilder sources(Object... sources) {
|
||||
this.sources.addAll(new LinkedHashSet<Object>(Arrays.asList(sources)));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add more sources (configuration classes and components) to this application
|
||||
*
|
||||
* @param sources the sources to add
|
||||
* @return the current builder
|
||||
*/
|
||||
public SpringApplicationBuilder sources(Class<?>... sources) {
|
||||
this.sources.addAll(new LinkedHashSet<Object>(Arrays.asList(sources)));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flag to explicitly request a web or non-web environment (auto detected based on
|
||||
* classpath if not set).
|
||||
*
|
||||
* @param webEnvironment the flag to set
|
||||
* @return the current builder
|
||||
*/
|
||||
public SpringApplicationBuilder web(boolean webEnvironment) {
|
||||
this.application.setWebEnvironment(webEnvironment);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flag to indicate the startup information should be logged.
|
||||
*
|
||||
* @param logStartupInfo the flag to set. Default true.
|
||||
* @return the current builder
|
||||
*/
|
||||
public SpringApplicationBuilder logStartupInfo(boolean logStartupInfo) {
|
||||
this.application.setLogStartupInfo(logStartupInfo);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flag to indicate the startup banner should be printed.
|
||||
*
|
||||
* @param showBanner the flag to set. Default true.
|
||||
* @return the current builder
|
||||
*/
|
||||
public SpringApplicationBuilder showBanner(boolean showBanner) {
|
||||
this.application.setShowBanner(showBanner);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fixes the main application class that is used to anchor the startup messages.
|
||||
*
|
||||
* @param mainApplicationClass the class to use.
|
||||
* @return the current builder
|
||||
*/
|
||||
public SpringApplicationBuilder main(Class<?> mainApplicationClass) {
|
||||
this.application.setMainApplicationClass(mainApplicationClass);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flag to indicate that command line arguments should be added to the environment.
|
||||
*
|
||||
* @param addCommandLineProperties the flag to set. Default true.
|
||||
* @return the current builder
|
||||
*/
|
||||
public SpringApplicationBuilder addCommandLineProperties(
|
||||
boolean addCommandLineProperties) {
|
||||
this.application.setAddCommandLineProperties(addCommandLineProperties);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default command line arguments (overridden by explicit arguments at runtime in
|
||||
* {@link #run(String...)}).
|
||||
*
|
||||
* @param defaultArgs the args to set.
|
||||
* @return the current builder
|
||||
*/
|
||||
public SpringApplicationBuilder defaultArgs(String... defaultArgs) {
|
||||
this.defaultArgs = defaultArgs;
|
||||
this.application.setDefaultArgs(defaultArgs);
|
||||
if (this.parent != null) {
|
||||
this.parent.defaultArgs(defaultArgs);
|
||||
this.parent.environment(this.environment);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the active Spring profiles for this app (and its parent and children).
|
||||
* Synonymous with {@link #defaultArgs(String...)
|
||||
* defaultArgs("--spring.profiles.active=[profiles]")}
|
||||
*
|
||||
* @param profiles the profiles to set.
|
||||
* @return the current builder
|
||||
*/
|
||||
public SpringApplicationBuilder profiles(String... profiles) {
|
||||
defaultArgs("--spring.profiles.active="
|
||||
+ StringUtils.arrayToCommaDelimitedString(profiles));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bean name generator for automatically generated bean names in the application
|
||||
* context.
|
||||
*
|
||||
* @param beanNameGenerator the generator to set.
|
||||
* @return the current builder
|
||||
*/
|
||||
public SpringApplicationBuilder beanNameGenerator(BeanNameGenerator beanNameGenerator) {
|
||||
this.application.setBeanNameGenerator(beanNameGenerator);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Environment for the application context.
|
||||
*
|
||||
* @param environment the environment to set.
|
||||
* @return the current builder
|
||||
*/
|
||||
public SpringApplicationBuilder environment(ConfigurableEnvironment environment) {
|
||||
this.application.setEnvironment(environment);
|
||||
this.environment = environment;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link ResourceLoader} for the application context. If a custom class loader is
|
||||
* needed, this is where it would be added.
|
||||
*
|
||||
* @param resourceLoader the resource loader to set.
|
||||
* @return the current builder
|
||||
*/
|
||||
public SpringApplicationBuilder resourceLoader(ResourceLoader resourceLoader) {
|
||||
this.application.setResourceLoader(resourceLoader);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add some initializers to the application (applied to the {@link ApplicationContext}
|
||||
* before any bean definitions are loaded).
|
||||
*
|
||||
* @param initializers some initializers to add
|
||||
* @return the current builder
|
||||
*/
|
||||
public SpringApplicationBuilder initializers(
|
||||
ApplicationContextInitializer<?>... initializers) {
|
||||
addInitializers(initializers);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param initializers the initializers to add
|
||||
*/
|
||||
private void addInitializers(ApplicationContextInitializer<?>... initializers) {
|
||||
Set<ApplicationContextInitializer<?>> target = new LinkedHashSet<ApplicationContextInitializer<?>>(
|
||||
this.application.getInitializers());
|
||||
target.addAll(Arrays.asList(initializers));
|
||||
this.application.setInitializers(target);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -83,6 +83,7 @@ import org.springframework.web.context.support.WebApplicationContextUtils;
|
||||
* {@link XmlEmbeddedWebApplicationContext} variants.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Dave Syer
|
||||
* @see AnnotationConfigEmbeddedWebApplicationContext
|
||||
* @see XmlEmbeddedWebApplicationContext
|
||||
* @see EmbeddedServletContainerFactory
|
||||
@@ -146,20 +147,11 @@ public class EmbeddedWebApplicationContext extends GenericWebApplicationContext
|
||||
}
|
||||
|
||||
private synchronized void createEmbeddedServletContainer() {
|
||||
if (this.embeddedServletContainer == null && getServletContext() == null) {
|
||||
if (this.embeddedServletContainer == null) {
|
||||
EmbeddedServletContainerFactory containerFactory = getEmbeddedServletContainerFactory();
|
||||
this.embeddedServletContainer = containerFactory
|
||||
.getEmbeddedServletContainer(getSelfInitializer());
|
||||
}
|
||||
else if (getServletContext() != null) {
|
||||
try {
|
||||
getSelfInitializer().onStartup(getServletContext());
|
||||
}
|
||||
catch (ServletException ex) {
|
||||
throw new ApplicationContextException(
|
||||
"Cannot initialize servlet context", ex);
|
||||
}
|
||||
}
|
||||
WebApplicationContextUtils.registerWebApplicationScopes(getBeanFactory(),
|
||||
getServletContext());
|
||||
WebApplicationContextUtils.registerEnvironmentBeans(getBeanFactory(),
|
||||
|
||||
@@ -49,12 +49,24 @@ import org.springframework.util.StringUtils;
|
||||
public class ContextIdApplicationContextInitializer implements
|
||||
ApplicationContextInitializer<ConfigurableApplicationContext>, Ordered {
|
||||
|
||||
private String name = "${spring.application.name:${vcap.application.name:${spring.config.name:application}}}";
|
||||
private String name;
|
||||
|
||||
private int index = -1;
|
||||
|
||||
private int order = Integer.MAX_VALUE - 10;
|
||||
|
||||
public ContextIdApplicationContextInitializer() {
|
||||
this(
|
||||
"${spring.application.name:${vcap.application.name:${spring.config.name:application}}}");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name
|
||||
*/
|
||||
public ContextIdApplicationContextInitializer(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setOrder(int order) {
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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
|
||||
*
|
||||
* http://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.context.initializer;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextInitializer;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
/**
|
||||
* {@link ApplicationContextInitializer} for setting the parent context.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class ParentContextApplicationContextInitializer implements
|
||||
ApplicationContextInitializer<ConfigurableApplicationContext>, Ordered {
|
||||
|
||||
private int order = Integer.MIN_VALUE;
|
||||
|
||||
private ApplicationContext parent;
|
||||
|
||||
public ParentContextApplicationContextInitializer(ApplicationContext parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public void setOrder(int order) {
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return this.order;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(ConfigurableApplicationContext applicationContext) {
|
||||
applicationContext.setParent(this.parent);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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
|
||||
*
|
||||
* http://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.context.initializer;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import org.springframework.context.ApplicationContextInitializer;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.web.context.ConfigurableWebApplicationContext;
|
||||
|
||||
/**
|
||||
* {@link ApplicationContextInitializer} for setting the servlet context.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class ServletContextApplicationContextInitializer implements
|
||||
ApplicationContextInitializer<ConfigurableWebApplicationContext>, Ordered {
|
||||
|
||||
private int order = Integer.MIN_VALUE;
|
||||
|
||||
private ServletContext servletContext;
|
||||
|
||||
/**
|
||||
* @param servletContext
|
||||
*/
|
||||
public ServletContextApplicationContextInitializer(ServletContext servletContext) {
|
||||
this.servletContext = servletContext;
|
||||
}
|
||||
|
||||
public void setOrder(int order) {
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return this.order;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(ConfigurableWebApplicationContext applicationContext) {
|
||||
applicationContext.setServletContext(this.servletContext);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,8 +22,10 @@ import javax.servlet.ServletException;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext;
|
||||
import org.springframework.boot.context.initializer.ParentContextApplicationContextInitializer;
|
||||
import org.springframework.boot.context.initializer.ServletContextApplicationContextInitializer;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.web.WebApplicationInitializer;
|
||||
@@ -77,11 +79,12 @@ public abstract class SpringBootServletInitializer implements WebApplicationInit
|
||||
servletContext.setAttribute(
|
||||
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, null);
|
||||
}
|
||||
SpringApplication application = new SpringApplication(getConfigClasses());
|
||||
AnnotationConfigEmbeddedWebApplicationContext context = new AnnotationConfigEmbeddedWebApplicationContext();
|
||||
context.setParent(parent);
|
||||
context.setServletContext(servletContext);
|
||||
application.setApplicationContext(context);
|
||||
SpringApplicationBuilder application = new SpringApplicationBuilder()
|
||||
.sources(getConfigClasses());
|
||||
application.initializers(
|
||||
new ParentContextApplicationContextInitializer(parent),
|
||||
new ServletContextApplicationContextInitializer(servletContext));
|
||||
application.contextClass(AnnotationConfigEmbeddedWebApplicationContext.class);
|
||||
return (WebApplicationContext) application.run();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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
|
||||
*
|
||||
* http://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.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.support.StaticApplicationContext;
|
||||
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class SpringApplicationBuilderTests {
|
||||
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void specificApplicationContextClass() throws Exception {
|
||||
SpringApplicationBuilder application = new SpringApplicationBuilder().sources(
|
||||
ExampleConfig.class).contextClass(StaticApplicationContext.class);
|
||||
this.context = application.run();
|
||||
assertThat(this.context, is(instanceOf(StaticApplicationContext.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parentContextCreation() throws Exception {
|
||||
SpringApplicationBuilder application = new SpringApplicationBuilder(
|
||||
ChildConfig.class).contextClass(SpyApplicationContext.class);
|
||||
application.parent(ExampleConfig.class);
|
||||
this.context = application.run();
|
||||
verify(((SpyApplicationContext) this.context).getApplicationContext()).setParent(
|
||||
any(ApplicationContext.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parentFirstCreation() throws Exception {
|
||||
SpringApplicationBuilder application = new SpringApplicationBuilder(
|
||||
ExampleConfig.class).child(ChildConfig.class);
|
||||
application.contextClass(SpyApplicationContext.class);
|
||||
this.context = application.run();
|
||||
verify(((SpyApplicationContext) this.context).getApplicationContext()).setParent(
|
||||
any(ApplicationContext.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parentContextIdentical() throws Exception {
|
||||
SpringApplicationBuilder application = new SpringApplicationBuilder(
|
||||
ExampleConfig.class);
|
||||
application.parent(ExampleConfig.class);
|
||||
application.contextClass(SpyApplicationContext.class);
|
||||
this.context = application.run();
|
||||
verify(((SpyApplicationContext) this.context).getApplicationContext()).setParent(
|
||||
any(ApplicationContext.class));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class ExampleConfig {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class ChildConfig {
|
||||
|
||||
}
|
||||
|
||||
public static class SpyApplicationContext extends AnnotationConfigApplicationContext {
|
||||
|
||||
ConfigurableApplicationContext applicationContext = spy(new AnnotationConfigApplicationContext());
|
||||
|
||||
@Override
|
||||
public void setParent(ApplicationContext parent) {
|
||||
this.applicationContext.setParent(parent);
|
||||
}
|
||||
|
||||
public ConfigurableApplicationContext getApplicationContext() {
|
||||
return this.applicationContext;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.boot;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
@@ -47,9 +48,7 @@ import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.core.env.StandardEnvironment;
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.mock.web.MockServletContext;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
import org.springframework.web.context.support.StaticWebApplicationContext;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
@@ -74,19 +73,19 @@ public class SpringApplicationTests {
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
private ApplicationContext context;
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
private Environment getEnvironment() {
|
||||
if (this.context instanceof ConfigurableApplicationContext) {
|
||||
return ((ConfigurableApplicationContext) this.context).getEnvironment();
|
||||
if (this.context != null) {
|
||||
return this.context.getEnvironment();
|
||||
}
|
||||
throw new IllegalStateException("No Environment available");
|
||||
throw new IllegalStateException("Could not obtain Environment");
|
||||
}
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
if (this.context instanceof ConfigurableApplicationContext) {
|
||||
((ConfigurableApplicationContext) this.context).close();
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,15 +120,6 @@ public class SpringApplicationTests {
|
||||
verify(application).printBanner();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void specificApplicationContext() throws Exception {
|
||||
SpringApplication application = new SpringApplication(ExampleConfig.class);
|
||||
ApplicationContext applicationContext = new StaticApplicationContext();
|
||||
application.setApplicationContext(applicationContext);
|
||||
this.context = application.run();
|
||||
assertThat(this.context, sameInstance(applicationContext));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void specificApplicationContextClass() throws Exception {
|
||||
SpringApplication application = new SpringApplication(ExampleConfig.class);
|
||||
@@ -144,12 +134,13 @@ public class SpringApplicationTests {
|
||||
application.setWebEnvironment(false);
|
||||
final AtomicReference<ApplicationContext> reference = new AtomicReference<ApplicationContext>();
|
||||
application
|
||||
.addInitializers(new ApplicationContextInitializer<ConfigurableApplicationContext>() {
|
||||
@Override
|
||||
public void initialize(ConfigurableApplicationContext context) {
|
||||
reference.set(context);
|
||||
}
|
||||
});
|
||||
.setInitializers(Arrays
|
||||
.asList(new ApplicationContextInitializer<ConfigurableApplicationContext>() {
|
||||
@Override
|
||||
public void initialize(ConfigurableApplicationContext context) {
|
||||
reference.set(context);
|
||||
}
|
||||
}));
|
||||
this.context = application.run("--foo=bar");
|
||||
assertThat(this.context, sameInstance(reference.get()));
|
||||
// Custom initializers do not switch off the defaults
|
||||
@@ -177,12 +168,9 @@ public class SpringApplicationTests {
|
||||
public void customEnvironment() throws Exception {
|
||||
TestSpringApplication application = new TestSpringApplication(ExampleConfig.class);
|
||||
application.setWebEnvironment(false);
|
||||
StaticApplicationContext applicationContext = spy(new StaticApplicationContext());
|
||||
ConfigurableEnvironment environment = new StandardEnvironment();
|
||||
application.setApplicationContext(applicationContext);
|
||||
application.setEnvironment(environment);
|
||||
application.run();
|
||||
verify(applicationContext).setEnvironment(environment);
|
||||
verify(application.getLoader()).setEnvironment(environment);
|
||||
}
|
||||
|
||||
@@ -190,12 +178,9 @@ public class SpringApplicationTests {
|
||||
public void customResourceLoader() throws Exception {
|
||||
TestSpringApplication application = new TestSpringApplication(ExampleConfig.class);
|
||||
application.setWebEnvironment(false);
|
||||
StaticApplicationContext applicationContext = spy(new StaticApplicationContext());
|
||||
ResourceLoader resourceLoader = new DefaultResourceLoader();
|
||||
application.setApplicationContext(applicationContext);
|
||||
application.setResourceLoader(resourceLoader);
|
||||
application.run();
|
||||
verify(applicationContext).setResourceLoader(resourceLoader);
|
||||
this.context = application.run();
|
||||
verify(application.getLoader()).setResourceLoader(resourceLoader);
|
||||
}
|
||||
|
||||
@@ -204,22 +189,15 @@ public class SpringApplicationTests {
|
||||
ResourceLoader resourceLoader = new DefaultResourceLoader();
|
||||
TestSpringApplication application = new TestSpringApplication(resourceLoader,
|
||||
ExampleWebConfig.class);
|
||||
StaticApplicationContext applicationContext = spy(new StaticApplicationContext());
|
||||
application.setApplicationContext(applicationContext);
|
||||
application.run();
|
||||
verify(applicationContext).setResourceLoader(resourceLoader);
|
||||
this.context = application.run();
|
||||
verify(application.getLoader()).setResourceLoader(resourceLoader);
|
||||
applicationContext.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customBeanNameGenerator() throws Exception {
|
||||
TestSpringApplication application = new TestSpringApplication(
|
||||
ExampleWebConfig.class);
|
||||
StaticWebApplicationContext applicationContext = spy(new StaticWebApplicationContext());
|
||||
applicationContext.setServletContext(new MockServletContext());
|
||||
BeanNameGenerator beanNameGenerator = new DefaultBeanNameGenerator();
|
||||
application.setApplicationContext(applicationContext);
|
||||
application.setBeanNameGenerator(beanNameGenerator);
|
||||
this.context = application.run();
|
||||
verify(application.getLoader()).setBeanNameGenerator(beanNameGenerator);
|
||||
@@ -342,10 +320,10 @@ public class SpringApplicationTests {
|
||||
@Test
|
||||
public void registerShutdownHook() throws Exception {
|
||||
SpringApplication application = new SpringApplication(ExampleConfig.class);
|
||||
ConfigurableApplicationContext applicationContext = spy(new AnnotationConfigApplicationContext());
|
||||
application.setApplicationContext(applicationContext);
|
||||
application.run();
|
||||
verify(applicationContext).registerShutdownHook();
|
||||
application.setApplicationContextClass(SpyApplicationContext.class);
|
||||
this.context = application.run();
|
||||
SpyApplicationContext applicationContext = (SpyApplicationContext) this.context;
|
||||
verify(applicationContext.getApplicationContext()).registerShutdownHook();
|
||||
}
|
||||
|
||||
private boolean hasPropertySource(ConfigurableEnvironment environment,
|
||||
@@ -363,6 +341,21 @@ public class SpringApplicationTests {
|
||||
|
||||
// FIXME test config files?
|
||||
|
||||
public static class SpyApplicationContext extends AnnotationConfigApplicationContext {
|
||||
|
||||
ConfigurableApplicationContext applicationContext = spy(new AnnotationConfigApplicationContext());
|
||||
|
||||
@Override
|
||||
public void registerShutdownHook() {
|
||||
this.applicationContext.registerShutdownHook();
|
||||
}
|
||||
|
||||
public ConfigurableApplicationContext getApplicationContext() {
|
||||
return this.applicationContext;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class TestSpringApplication extends SpringApplication {
|
||||
|
||||
private BeanDefinitionLoader loader;
|
||||
|
||||
Reference in New Issue
Block a user