Skip to content

Commit

Permalink
Add customer Application Environment subclasses
Browse files Browse the repository at this point in the history
Add custom `ApplicationEnvironment`, `ApplicationServletEnvironment`
and `ApplicationReactiveWebEnvironment` subclasses for use with
`SpringApplication`. The subclasses all disable the resolution of
active and default profiles using properties since this is handled
directly by the `ConfigDataEnvironmentPostProcessor`.

Closes gh-24892
See gh-24890
  • Loading branch information
philwebb committed Apr 9, 2021
1 parent d938dd9 commit 1d302f4
Show file tree
Hide file tree
Showing 15 changed files with 372 additions and 22 deletions.
@@ -0,0 +1,38 @@
/*
* Copyright 2012-2021 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.core.env.StandardEnvironment;

/**
* {@link StandardEnvironment} for typical use in a typical {@link SpringApplication}.
*
* @author Phillip Webb
*/
class ApplicationEnvironment extends StandardEnvironment {

@Override
protected String doGetActiveProfilesProperty() {
return null;
}

@Override
protected String doGetDefaultProfilesProperty() {
return null;
}

}
@@ -0,0 +1,39 @@
/*
* Copyright 2012-2021 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.boot.web.reactive.context.StandardReactiveWebEnvironment;

/**
* {@link StandardReactiveWebEnvironment} for typical use in a typical
* {@link SpringApplication}.
*
* @author Phillip Webb
*/
class ApplicationReactiveWebEnvironment extends StandardReactiveWebEnvironment {

@Override
protected String doGetActiveProfilesProperty() {
return null;
}

@Override
protected String doGetDefaultProfilesProperty() {
return null;
}

}
@@ -0,0 +1,39 @@
/*
* Copyright 2012-2021 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.web.context.support.StandardServletEnvironment;

/**
* {@link StandardServletEnvironment} for typical use in a typical
* {@link SpringApplication}.
*
* @author Phillip Webb
*/
class ApplicationServletEnvironment extends StandardServletEnvironment {

@Override
protected String doGetActiveProfilesProperty() {
return null;
}

@Override
protected String doGetDefaultProfilesProperty() {
return null;
}

}
Expand Up @@ -47,7 +47,6 @@
import org.springframework.boot.context.properties.source.ConfigurationPropertySources;
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.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextInitializer;
Expand Down Expand Up @@ -82,7 +81,6 @@
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StopWatch;
import org.springframework.util.StringUtils;
import org.springframework.web.context.support.StandardServletEnvironment;

/**
* Class that can be used to bootstrap and launch a Spring application from a Java main
Expand Down Expand Up @@ -391,11 +389,11 @@ private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners
private Class<? extends StandardEnvironment> deduceEnvironmentClass() {
switch (this.webApplicationType) {
case SERVLET:
return StandardServletEnvironment.class;
return ApplicationServletEnvironment.class;
case REACTIVE:
return StandardReactiveWebEnvironment.class;
return ApplicationReactiveWebEnvironment.class;
default:
return StandardEnvironment.class;
return ApplicationEnvironment.class;
}
}

Expand Down Expand Up @@ -493,11 +491,11 @@ private ConfigurableEnvironment getOrCreateEnvironment() {
}
switch (this.webApplicationType) {
case SERVLET:
return new StandardServletEnvironment();
return new ApplicationServletEnvironment();
case REACTIVE:
return new StandardReactiveWebEnvironment();
return new ApplicationReactiveWebEnvironment();
default:
return new StandardEnvironment();
return new ApplicationEnvironment();
}
}

Expand Down
Expand Up @@ -61,6 +61,7 @@
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.context.event.SmartApplicationListener;
import org.springframework.core.Ordered;
import org.springframework.core.env.AbstractEnvironment;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MutablePropertySources;
Expand Down Expand Up @@ -361,13 +362,18 @@ private void initializeProfiles() {
this.profiles.addAll(includedViaProperty);
addActiveProfiles(activatedViaProperty);
if (this.profiles.size() == 1) { // only has null profile
for (String defaultProfileName : this.environment.getDefaultProfiles()) {
for (String defaultProfileName : getDefaultProfiles(binder)) {
Profile defaultProfile = new Profile(defaultProfileName, true);
this.profiles.add(defaultProfile);
}
}
}

private String[] getDefaultProfiles(Binder binder) {
return binder.bind(AbstractEnvironment.DEFAULT_PROFILES_PROPERTY_NAME, STRING_ARRAY)
.orElseGet(this.environment::getDefaultProfiles);
}

private List<Profile> getOtherActiveProfiles(Set<Profile> activatedViaProperty,
Set<Profile> includedViaProperty) {
return Arrays.stream(this.environment.getActiveProfiles()).map(Profile::new).filter(
Expand Down Expand Up @@ -777,9 +783,9 @@ private void applyActiveProfiles(PropertySource<?> defaultProperties) {
if (defaultProperties != null) {
Binder binder = new Binder(ConfigurationPropertySources.from(defaultProperties),
new PropertySourcesPlaceholdersResolver(this.environment));
activeProfiles.addAll(getDefaultProfiles(binder, "spring.profiles.include"));
activeProfiles.addAll(bindStringList(binder, "spring.profiles.include"));
if (!this.activatedProfiles) {
activeProfiles.addAll(getDefaultProfiles(binder, "spring.profiles.active"));
activeProfiles.addAll(bindStringList(binder, "spring.profiles.active"));
}
}
this.processedProfiles.stream().filter(this::isDefaultProfile).map(Profile::getName)
Expand All @@ -791,7 +797,7 @@ private boolean isDefaultProfile(Profile profile) {
return profile != null && !profile.isDefaultProfile();
}

private List<String> getDefaultProfiles(Binder binder, String property) {
private List<String> bindStringList(Binder binder, String property) {
return binder.bind(property, STRING_LIST).orElse(Collections.emptyList());
}

Expand Down
Expand Up @@ -109,6 +109,9 @@ private boolean hasExplicit(Supplier<String[]> supplier, String propertyValue, S
if (!StringUtils.hasLength(propertyValue)) {
return !unset.equals(profiles);
}
if (unset.equals(profiles)) {
return false;
}
Set<String> propertyProfiles = StringUtils
.commaDelimitedListToSet(StringUtils.trimAllWhitespace(propertyValue));
return !propertyProfiles.equals(profiles);
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2021 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.
Expand All @@ -17,6 +17,7 @@
package org.springframework.boot.web.reactive.context;

import org.springframework.core.env.Environment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.StandardEnvironment;

/**
Expand All @@ -29,4 +30,12 @@
*/
public class StandardReactiveWebEnvironment extends StandardEnvironment implements ConfigurableReactiveWebEnvironment {

public StandardReactiveWebEnvironment() {
super();
}

protected StandardReactiveWebEnvironment(MutablePropertySources propertySources) {
super(propertySources);
}

}
@@ -0,0 +1,55 @@
/*
* Copyright 2012-2021 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.junit.jupiter.api.Test;

import org.springframework.core.env.AbstractEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.mock.env.MockPropertySource;

import static org.assertj.core.api.Assertions.assertThat;

/**
* Base class for {@link SpringApplication} {@link Environment} tests.
*
* @author Phillip Webb
*/
public abstract class AbstractApplicationEnvironmentTests {

@Test
void getActiveProfilesDoesNotResolveProperty() {
StandardEnvironment environment = createEnvironment();
new MockPropertySource().withProperty("", "");
environment.getPropertySources().addFirst(
new MockPropertySource().withProperty(AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME, "test"));
assertThat(environment.getActiveProfiles()).isEmpty();
}

@Test
void getDefaultProfilesDoesNotResolveProperty() {
StandardEnvironment environment = createEnvironment();
new MockPropertySource().withProperty("", "");
environment.getPropertySources().addFirst(
new MockPropertySource().withProperty(AbstractEnvironment.DEFAULT_PROFILES_PROPERTY_NAME, "test"));
assertThat(environment.getDefaultProfiles()).containsExactly("default");
}

protected abstract StandardEnvironment createEnvironment();

}
@@ -0,0 +1,33 @@
/*
* Copyright 2012-2021 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.core.env.StandardEnvironment;

/**
* Tests for {@link ApplicationEnvironment}.
*
* @author Phillip Webb
*/
class ApplicationEnvironmentTests extends AbstractApplicationEnvironmentTests {

@Override
protected StandardEnvironment createEnvironment() {
return new ApplicationEnvironment();
}

}
@@ -0,0 +1,33 @@
/*
* Copyright 2012-2021 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.core.env.StandardEnvironment;

/**
* Tests for {@link ApplicationReactiveWebEnvironment}.
*
* @author Phillip Webb
*/
class ApplicationReactiveWebEnvironmentTests extends AbstractApplicationEnvironmentTests {

@Override
protected StandardEnvironment createEnvironment() {
return new ApplicationReactiveWebEnvironment();
}

}

0 comments on commit 1d302f4

Please sign in to comment.