Skip to content

Commit 7db93ae

Browse files
committed
Merge branch '2.7.x'
Closes gh-32827
2 parents 072ce5c + 1c7bff7 commit 7db93ae

12 files changed

+189
-68
lines changed

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ApplicationContextFactory.java

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,10 @@
1818

1919
import java.util.function.Supplier;
2020

21-
import org.springframework.aot.AotDetector;
2221
import org.springframework.beans.BeanUtils;
2322
import org.springframework.context.ConfigurableApplicationContext;
24-
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
25-
import org.springframework.context.support.GenericApplicationContext;
26-
import org.springframework.core.io.support.SpringFactoriesLoader;
23+
import org.springframework.core.env.ConfigurableEnvironment;
24+
import org.springframework.core.env.Environment;
2725

2826
/**
2927
* Strategy interface for creating the {@link ConfigurableApplicationContext} used by a
@@ -42,23 +40,32 @@ public interface ApplicationContextFactory {
4240
* A default {@link ApplicationContextFactory} implementation that will create an
4341
* appropriate context for the {@link WebApplicationType}.
4442
*/
45-
ApplicationContextFactory DEFAULT = (webApplicationType) -> {
46-
try {
47-
for (ApplicationContextFactory candidate : SpringFactoriesLoader
48-
.loadFactories(ApplicationContextFactory.class, ApplicationContextFactory.class.getClassLoader())) {
49-
ConfigurableApplicationContext context = candidate.create(webApplicationType);
50-
if (context != null) {
51-
return context;
52-
}
53-
}
54-
return AotDetector.useGeneratedArtifacts() ? new GenericApplicationContext()
55-
: new AnnotationConfigApplicationContext();
56-
}
57-
catch (Exception ex) {
58-
throw new IllegalStateException("Unable create a default ApplicationContext instance, "
59-
+ "you may need a custom ApplicationContextFactory", ex);
60-
}
61-
};
43+
ApplicationContextFactory DEFAULT = new DefaultApplicationContextFactory();
44+
45+
/**
46+
* Return the {@link Environment} type expected to be set on the
47+
* {@link #create(WebApplicationType) created} application context. The result of this
48+
* method can be used to convert an existing environment instance to the correct type.
49+
* @param webApplicationType the web application type
50+
* @return the expected application context type or {@code null} to use the default
51+
* @since 2.6.14
52+
*/
53+
default Class<? extends ConfigurableEnvironment> getEnvironmentType(WebApplicationType webApplicationType) {
54+
return null;
55+
}
56+
57+
/**
58+
* Create a new {@link Environment} to be set on the
59+
* {@link #create(WebApplicationType) created} application context. The result of this
60+
* method must match the type returned by
61+
* {@link #getEnvironmentType(WebApplicationType)}.
62+
* @param webApplicationType the web application type
63+
* @return an environment instance or {@code null} to use the default
64+
* @since 2.6.14
65+
*/
66+
default ConfigurableEnvironment createEnvironment(WebApplicationType webApplicationType) {
67+
return null;
68+
}
6269

6370
/**
6471
* Creates the {@link ConfigurableApplicationContext application context} for a
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* Copyright 2012-2022 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+
* https://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;
18+
19+
import java.util.function.BiFunction;
20+
import java.util.function.Supplier;
21+
22+
import org.springframework.aot.AotDetector;
23+
import org.springframework.context.ConfigurableApplicationContext;
24+
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
25+
import org.springframework.context.support.GenericApplicationContext;
26+
import org.springframework.core.env.ConfigurableEnvironment;
27+
import org.springframework.core.io.support.SpringFactoriesLoader;
28+
29+
/**
30+
* Default {@link ApplicationContextFactory} implementation that will create an
31+
* appropriate context for the {@link WebApplicationType}.
32+
*
33+
* @author Phillip Webb
34+
*/
35+
class DefaultApplicationContextFactory implements ApplicationContextFactory {
36+
37+
@Override
38+
public Class<? extends ConfigurableEnvironment> getEnvironmentType(WebApplicationType webApplicationType) {
39+
return getFromSpringFactories(webApplicationType, ApplicationContextFactory::getEnvironmentType, null);
40+
}
41+
42+
@Override
43+
public ConfigurableEnvironment createEnvironment(WebApplicationType webApplicationType) {
44+
return getFromSpringFactories(webApplicationType, ApplicationContextFactory::createEnvironment, null);
45+
}
46+
47+
@Override
48+
public ConfigurableApplicationContext create(WebApplicationType webApplicationType) {
49+
try {
50+
return getFromSpringFactories(webApplicationType, ApplicationContextFactory::create,
51+
this::createDefaultApplicationContext);
52+
}
53+
catch (Exception ex) {
54+
throw new IllegalStateException("Unable create a default ApplicationContext instance, "
55+
+ "you may need a custom ApplicationContextFactory", ex);
56+
}
57+
}
58+
59+
private ConfigurableApplicationContext createDefaultApplicationContext() {
60+
if (!AotDetector.useGeneratedArtifacts()) {
61+
return new AnnotationConfigApplicationContext();
62+
}
63+
return new GenericApplicationContext();
64+
}
65+
66+
private <T> T getFromSpringFactories(WebApplicationType webApplicationType,
67+
BiFunction<ApplicationContextFactory, WebApplicationType, T> action, Supplier<T> defaultResult) {
68+
for (ApplicationContextFactory candidate : SpringFactoriesLoader.loadFactories(ApplicationContextFactory.class,
69+
getClass().getClassLoader())) {
70+
T result = action.apply(candidate, webApplicationType);
71+
if (result != null) {
72+
return result;
73+
}
74+
}
75+
return (defaultResult != null) ? defaultResult.get() : null;
76+
}
77+
78+
}

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/EnvironmentConverter.java

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors.
2+
* Copyright 2012-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.boot;
1818

19+
import java.lang.reflect.Constructor;
1920
import java.util.Collections;
2021
import java.util.HashSet;
2122
import java.util.Set;
@@ -26,6 +27,7 @@
2627
import org.springframework.core.env.PropertySource;
2728
import org.springframework.core.env.StandardEnvironment;
2829
import org.springframework.util.ClassUtils;
30+
import org.springframework.util.ReflectionUtils;
2931
import org.springframework.web.context.support.StandardServletEnvironment;
3032

3133
/**
@@ -68,33 +70,35 @@ final class EnvironmentConverter {
6870
* @param type the type to convert the Environment to
6971
* @return the converted Environment
7072
*/
71-
StandardEnvironment convertEnvironmentIfNecessary(ConfigurableEnvironment environment,
72-
Class<? extends StandardEnvironment> type) {
73+
ConfigurableEnvironment convertEnvironmentIfNecessary(ConfigurableEnvironment environment,
74+
Class<? extends ConfigurableEnvironment> type) {
7375
if (type.equals(environment.getClass())) {
74-
return (StandardEnvironment) environment;
76+
return environment;
7577
}
7678
return convertEnvironment(environment, type);
7779
}
7880

79-
private StandardEnvironment convertEnvironment(ConfigurableEnvironment environment,
80-
Class<? extends StandardEnvironment> type) {
81-
StandardEnvironment result = createEnvironment(type);
81+
private ConfigurableEnvironment convertEnvironment(ConfigurableEnvironment environment,
82+
Class<? extends ConfigurableEnvironment> type) {
83+
ConfigurableEnvironment result = createEnvironment(type);
8284
result.setActiveProfiles(environment.getActiveProfiles());
8385
result.setConversionService(environment.getConversionService());
8486
copyPropertySources(environment, result);
8587
return result;
8688
}
8789

88-
private StandardEnvironment createEnvironment(Class<? extends StandardEnvironment> type) {
90+
private ConfigurableEnvironment createEnvironment(Class<? extends ConfigurableEnvironment> type) {
8991
try {
90-
return type.getDeclaredConstructor().newInstance();
92+
Constructor<? extends ConfigurableEnvironment> constructor = type.getDeclaredConstructor();
93+
ReflectionUtils.makeAccessible(constructor);
94+
return constructor.newInstance();
9195
}
9296
catch (Exception ex) {
93-
return new StandardEnvironment();
97+
return new ApplicationEnvironment();
9498
}
9599
}
96100

97-
private void copyPropertySources(ConfigurableEnvironment source, StandardEnvironment target) {
101+
private void copyPropertySources(ConfigurableEnvironment source, ConfigurableEnvironment target) {
98102
removePropertySources(target.getPropertySources(), isServletEnvironment(target.getClass(), this.classLoader));
99103
for (PropertySource<?> propertySource : source.getPropertySources()) {
100104
if (!SERVLET_ENVIRONMENT_SOURCE_NAMES.contains(propertySource.getName())) {

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@
7979
import org.springframework.core.env.MutablePropertySources;
8080
import org.springframework.core.env.PropertySource;
8181
import org.springframework.core.env.SimpleCommandLinePropertySource;
82-
import org.springframework.core.env.StandardEnvironment;
8382
import org.springframework.core.io.DefaultResourceLoader;
8483
import org.springframework.core.io.ResourceLoader;
8584
import org.springframework.core.io.support.SpringFactoriesLoader;
@@ -365,12 +364,16 @@ private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners
365364
return environment;
366365
}
367366

368-
private Class<? extends StandardEnvironment> deduceEnvironmentClass() {
369-
return switch (this.webApplicationType) {
370-
case SERVLET -> ApplicationServletEnvironment.class;
371-
case REACTIVE -> ApplicationReactiveWebEnvironment.class;
372-
default -> ApplicationEnvironment.class;
373-
};
367+
private Class<? extends ConfigurableEnvironment> deduceEnvironmentClass() {
368+
Class<? extends ConfigurableEnvironment> environmentType = this.applicationContextFactory
369+
.getEnvironmentType(this.webApplicationType);
370+
if (environmentType == null && this.applicationContextFactory != ApplicationContextFactory.DEFAULT) {
371+
environmentType = ApplicationContextFactory.DEFAULT.getEnvironmentType(this.webApplicationType);
372+
}
373+
if (environmentType == null) {
374+
return ApplicationEnvironment.class;
375+
}
376+
return environmentType;
374377
}
375378

376379
private void prepareContext(DefaultBootstrapContext bootstrapContext, ConfigurableApplicationContext context,
@@ -462,14 +465,11 @@ private ConfigurableEnvironment getOrCreateEnvironment() {
462465
if (this.environment != null) {
463466
return this.environment;
464467
}
465-
switch (this.webApplicationType) {
466-
case SERVLET:
467-
return new ApplicationServletEnvironment();
468-
case REACTIVE:
469-
return new ApplicationReactiveWebEnvironment();
470-
default:
471-
return new ApplicationEnvironment();
468+
ConfigurableEnvironment environment = this.applicationContextFactory.createEnvironment(this.webApplicationType);
469+
if (environment == null && this.applicationContextFactory != ApplicationContextFactory.DEFAULT) {
470+
environment = ApplicationContextFactory.DEFAULT.createEnvironment(this.webApplicationType);
472471
}
472+
return (environment != null) ? environment : new ApplicationEnvironment();
473473
}
474474

475475
/**

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ApplicationReactiveWebEnvironment.java renamed to spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ApplicationReactiveWebEnvironment.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2021 the original author or authors.
2+
* Copyright 2012-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -14,10 +14,10 @@
1414
* limitations under the License.
1515
*/
1616

17-
package org.springframework.boot;
17+
package org.springframework.boot.web.reactive.context;
1818

19+
import org.springframework.boot.SpringApplication;
1920
import org.springframework.boot.context.properties.source.ConfigurationPropertySources;
20-
import org.springframework.boot.web.reactive.context.StandardReactiveWebEnvironment;
2121
import org.springframework.core.env.ConfigurablePropertyResolver;
2222
import org.springframework.core.env.MutablePropertySources;
2323

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ReactiveWebServerApplicationContextFactory.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.springframework.boot.ApplicationContextFactory;
2121
import org.springframework.boot.WebApplicationType;
2222
import org.springframework.context.ConfigurableApplicationContext;
23+
import org.springframework.core.env.ConfigurableEnvironment;
2324

2425
/**
2526
* {@link ApplicationContextFactory} registered in {@code spring.factories} to support
@@ -31,6 +32,16 @@
3132
*/
3233
class ReactiveWebServerApplicationContextFactory implements ApplicationContextFactory {
3334

35+
@Override
36+
public Class<? extends ConfigurableEnvironment> getEnvironmentType(WebApplicationType webApplicationType) {
37+
return (webApplicationType != WebApplicationType.REACTIVE) ? null : ApplicationReactiveWebEnvironment.class;
38+
}
39+
40+
@Override
41+
public ConfigurableEnvironment createEnvironment(WebApplicationType webApplicationType) {
42+
return (webApplicationType != WebApplicationType.REACTIVE) ? null : new ApplicationReactiveWebEnvironment();
43+
}
44+
3445
@Override
3546
public ConfigurableApplicationContext create(WebApplicationType webApplicationType) {
3647
return (webApplicationType != WebApplicationType.REACTIVE) ? null : createContext();

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ApplicationServletEnvironment.java renamed to spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/ApplicationServletEnvironment.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2021 the original author or authors.
2+
* Copyright 2012-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -14,8 +14,9 @@
1414
* limitations under the License.
1515
*/
1616

17-
package org.springframework.boot;
17+
package org.springframework.boot.web.servlet.context;
1818

19+
import org.springframework.boot.SpringApplication;
1920
import org.springframework.boot.context.properties.source.ConfigurationPropertySources;
2021
import org.springframework.core.env.ConfigurablePropertyResolver;
2122
import org.springframework.core.env.MutablePropertySources;

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/ServletWebServerApplicationContextFactory.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.springframework.boot.ApplicationContextFactory;
2121
import org.springframework.boot.WebApplicationType;
2222
import org.springframework.context.ConfigurableApplicationContext;
23+
import org.springframework.core.env.ConfigurableEnvironment;
2324

2425
/**
2526
* {@link ApplicationContextFactory} registered in {@code spring.factories} to support
@@ -31,6 +32,16 @@
3132
*/
3233
class ServletWebServerApplicationContextFactory implements ApplicationContextFactory {
3334

35+
@Override
36+
public Class<? extends ConfigurableEnvironment> getEnvironmentType(WebApplicationType webApplicationType) {
37+
return (webApplicationType != WebApplicationType.SERVLET) ? null : ApplicationServletEnvironment.class;
38+
}
39+
40+
@Override
41+
public ConfigurableEnvironment createEnvironment(WebApplicationType webApplicationType) {
42+
return (webApplicationType != WebApplicationType.SERVLET) ? null : new ApplicationServletEnvironment();
43+
}
44+
3445
@Override
3546
public ConfigurableApplicationContext create(WebApplicationType webApplicationType) {
3647
return (webApplicationType != WebApplicationType.SERVLET) ? null : createContext();

0 commit comments

Comments
 (0)