Skip to content

Commit b8833c4

Browse files
committed
Allow spring.config.location to be configured via servlet context
Previously, in a war deployment, the web environment’s property sources were initialized using the servlet context after the application’s configuration had been read by ConfigFileApplicationListener. This meant that spring.config.location configured via the servlet context had no effect. This commit adds a new ApplicationListener, ServletContextApplicationListener, that initialises the configurable web environment’s property sources using the servlet context. It’s ordered with higher precedence than ConfigFileApplicationListener to ensure that any properties defined in the servlet context are available when loading the application’s configuration. Closes gh-6801
1 parent 56cf496 commit b8833c4

File tree

3 files changed

+68
-0
lines changed

3 files changed

+68
-0
lines changed
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright 2012-2016 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.context.web;
18+
19+
import javax.servlet.ServletContext;
20+
21+
import org.springframework.boot.SpringApplication;
22+
import org.springframework.boot.context.config.ConfigFileApplicationListener;
23+
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
24+
import org.springframework.context.ApplicationListener;
25+
import org.springframework.core.Ordered;
26+
import org.springframework.web.context.ConfigurableWebEnvironment;
27+
28+
/**
29+
* An {@link ApplicationListener} that initializes the {@link SpringApplication} using the
30+
* {@link ServletContext}.
31+
*
32+
* @author Andy Wilkinson
33+
*/
34+
final class ServletContextApplicationListener
35+
implements ApplicationListener<ApplicationEnvironmentPreparedEvent>, Ordered {
36+
37+
private final ServletContext servletContext;
38+
39+
ServletContextApplicationListener(ServletContext servletContext) {
40+
this.servletContext = servletContext;
41+
}
42+
43+
@Override
44+
public int getOrder() {
45+
return ConfigFileApplicationListener.DEFAULT_ORDER - 1;
46+
}
47+
48+
@Override
49+
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
50+
if (event.getEnvironment() instanceof ConfigurableWebEnvironment) {
51+
((ConfigurableWebEnvironment) event.getEnvironment())
52+
.initPropertySources(this.servletContext, null);
53+
}
54+
}
55+
56+
}

spring-boot/src/main/java/org/springframework/boot/context/web/SpringBootServletInitializer.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ protected WebApplicationContext createRootApplicationContext(
112112
}
113113
builder.initializers(
114114
new ServletContextApplicationContextInitializer(servletContext));
115+
builder.listeners(new ServletContextApplicationListener(servletContext));
115116
builder.contextClass(AnnotationConfigEmbeddedWebApplicationContext.class);
116117
builder = configure(builder);
117118
SpringApplication application = builder.build();

spring-boot/src/test/java/org/springframework/boot/context/web/SpringBootServletInitializerTests.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,14 @@
3030
import org.springframework.beans.DirectFieldAccessor;
3131
import org.springframework.boot.SpringApplication;
3232
import org.springframework.boot.builder.SpringApplicationBuilder;
33+
import org.springframework.context.ApplicationListener;
3334
import org.springframework.context.annotation.Configuration;
3435
import org.springframework.mock.web.MockServletContext;
3536
import org.springframework.web.context.WebApplicationContext;
3637

3738
import static org.hamcrest.Matchers.equalTo;
39+
import static org.hamcrest.Matchers.hasItem;
40+
import static org.hamcrest.Matchers.instanceOf;
3841
import static org.hamcrest.Matchers.is;
3942
import static org.junit.Assert.assertThat;
4043

@@ -102,6 +105,14 @@ public void withErrorPageFilterNotRegistered() throws Exception {
102105
equalToSet(WithErrorPageFilterNotRegistered.class));
103106
}
104107

108+
@Test
109+
public void servletContextApplicationListenerIsAdded() {
110+
new WithConfiguredSource().createRootApplicationContext(this.servletContext);
111+
assertThat(this.application.getListeners(),
112+
hasItem((Matcher<? super ApplicationListener<?>>) instanceOf(
113+
ServletContextApplicationListener.class)));
114+
}
115+
105116
private Matcher<? super Set<Object>> equalToSet(Object... items) {
106117
Set<Object> set = new LinkedHashSet<Object>();
107118
Collections.addAll(set, items);

0 commit comments

Comments
 (0)