Delay property source initialization till LoggingSystem is initialized
Previously, the initialization of StandardServletEnvironment's property sources in SpringBootServletInitializer led to debug logging calls being made before the LoggingSystem had been initialized. As a result, the system's default configuration was used and, in the case of Logback at least, the debug logging was output to System.out in a war deployment. This commit updates SpringBootServletInitializer to delay the initialization of StandardServletEnvironment's property sources until after the LoggingSystem has been initialized, but still in time for active profiles to be configured via servlet context parameters (see gh-9972). Closes gh-13736
This commit is contained in:
parent
73a08dd668
commit
57ebdab2ab
|
|
@ -29,15 +29,19 @@ import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.builder.ParentContextApplicationContextInitializer;
|
import org.springframework.boot.builder.ParentContextApplicationContextInitializer;
|
||||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||||
import org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext;
|
import org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext;
|
||||||
|
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
|
||||||
import org.springframework.boot.web.servlet.ServletContextInitializer;
|
import org.springframework.boot.web.servlet.ServletContextInitializer;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.ApplicationListener;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.core.Ordered;
|
||||||
import org.springframework.core.annotation.AnnotationUtils;
|
import org.springframework.core.annotation.AnnotationUtils;
|
||||||
|
import org.springframework.core.env.ConfigurableEnvironment;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.web.WebApplicationInitializer;
|
import org.springframework.web.WebApplicationInitializer;
|
||||||
|
import org.springframework.web.context.ConfigurableWebEnvironment;
|
||||||
import org.springframework.web.context.ContextLoaderListener;
|
import org.springframework.web.context.ContextLoaderListener;
|
||||||
import org.springframework.web.context.WebApplicationContext;
|
import org.springframework.web.context.WebApplicationContext;
|
||||||
import org.springframework.web.context.support.StandardServletEnvironment;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An opinionated {@link WebApplicationInitializer} to run a {@link SpringApplication}
|
* An opinionated {@link WebApplicationInitializer} to run a {@link SpringApplication}
|
||||||
|
|
@ -104,9 +108,6 @@ public abstract class SpringBootServletInitializer implements WebApplicationInit
|
||||||
protected WebApplicationContext createRootApplicationContext(
|
protected WebApplicationContext createRootApplicationContext(
|
||||||
ServletContext servletContext) {
|
ServletContext servletContext) {
|
||||||
SpringApplicationBuilder builder = createSpringApplicationBuilder();
|
SpringApplicationBuilder builder = createSpringApplicationBuilder();
|
||||||
StandardServletEnvironment environment = new StandardServletEnvironment();
|
|
||||||
environment.initPropertySources(servletContext, null);
|
|
||||||
builder.environment(environment);
|
|
||||||
builder.main(getClass());
|
builder.main(getClass());
|
||||||
ApplicationContext parent = getExistingRootWebApplicationContext(servletContext);
|
ApplicationContext parent = getExistingRootWebApplicationContext(servletContext);
|
||||||
if (parent != null) {
|
if (parent != null) {
|
||||||
|
|
@ -119,6 +120,7 @@ public abstract class SpringBootServletInitializer implements WebApplicationInit
|
||||||
new ServletContextApplicationContextInitializer(servletContext));
|
new ServletContextApplicationContextInitializer(servletContext));
|
||||||
builder.contextClass(AnnotationConfigEmbeddedWebApplicationContext.class);
|
builder.contextClass(AnnotationConfigEmbeddedWebApplicationContext.class);
|
||||||
builder = configure(builder);
|
builder = configure(builder);
|
||||||
|
builder.listeners(new WebEnvironmentPropertySourceInitializer(servletContext));
|
||||||
SpringApplication application = builder.build();
|
SpringApplication application = builder.build();
|
||||||
if (application.getSources().isEmpty() && AnnotationUtils
|
if (application.getSources().isEmpty() && AnnotationUtils
|
||||||
.findAnnotation(getClass(), Configuration.class) != null) {
|
.findAnnotation(getClass(), Configuration.class) != null) {
|
||||||
|
|
@ -177,4 +179,30 @@ public abstract class SpringBootServletInitializer implements WebApplicationInit
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final class WebEnvironmentPropertySourceInitializer
|
||||||
|
implements ApplicationListener<ApplicationEnvironmentPreparedEvent>, Ordered {
|
||||||
|
|
||||||
|
private final ServletContext servletContext;
|
||||||
|
|
||||||
|
private WebEnvironmentPropertySourceInitializer(ServletContext servletContext) {
|
||||||
|
this.servletContext = servletContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
|
||||||
|
ConfigurableEnvironment environment = event.getEnvironment();
|
||||||
|
if (environment instanceof ConfigurableWebEnvironment) {
|
||||||
|
((ConfigurableWebEnvironment) environment)
|
||||||
|
.initPropertySources(this.servletContext, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrder() {
|
||||||
|
return Ordered.HIGHEST_PRECEDENCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2017 the original author or authors.
|
* Copyright 2012-2018 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.
|
||||||
|
|
@ -22,6 +22,7 @@ import java.util.Collections;
|
||||||
import javax.servlet.ServletContext;
|
import javax.servlet.ServletContext;
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.rules.ExpectedException;
|
import org.junit.rules.ExpectedException;
|
||||||
|
|
@ -33,6 +34,7 @@ import org.springframework.boot.context.embedded.EmbeddedServletContainer;
|
||||||
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
|
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
|
||||||
import org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory;
|
import org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory;
|
||||||
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
|
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
|
||||||
|
import org.springframework.boot.testutil.InternalOutputCapture;
|
||||||
import org.springframework.boot.web.servlet.ServletContextInitializer;
|
import org.springframework.boot.web.servlet.ServletContextInitializer;
|
||||||
import org.springframework.context.ApplicationListener;
|
import org.springframework.context.ApplicationListener;
|
||||||
import org.springframework.context.ConfigurableApplicationContext;
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
|
|
@ -59,10 +61,19 @@ public class SpringBootServletInitializerTests {
|
||||||
@Rule
|
@Rule
|
||||||
public ExpectedException thrown = ExpectedException.none();
|
public ExpectedException thrown = ExpectedException.none();
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public InternalOutputCapture output = new InternalOutputCapture();
|
||||||
|
|
||||||
private ServletContext servletContext = new MockServletContext();
|
private ServletContext servletContext = new MockServletContext();
|
||||||
|
|
||||||
private SpringApplication application;
|
private SpringApplication application;
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void verifyLoggingOutput() {
|
||||||
|
assertThat(this.output.toString())
|
||||||
|
.doesNotContain(StandardServletEnvironment.class.getSimpleName());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void failsWithoutConfigure() throws Exception {
|
public void failsWithoutConfigure() throws Exception {
|
||||||
this.thrown.expect(IllegalStateException.class);
|
this.thrown.expect(IllegalStateException.class);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue