001/* 002 * Copyright 2002-2018 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.core.env; 018 019import java.util.Map; 020 021/** 022 * Configuration interface to be implemented by most if not all {@link Environment} types. 023 * Provides facilities for setting active and default profiles and manipulating underlying 024 * property sources. Allows clients to set and validate required properties, customize the 025 * conversion service and more through the {@link ConfigurablePropertyResolver} 026 * superinterface. 027 * 028 * <h2>Manipulating property sources</h2> 029 * <p>Property sources may be removed, reordered, or replaced; and additional 030 * property sources may be added using the {@link MutablePropertySources} 031 * instance returned from {@link #getPropertySources()}. The following examples 032 * are against the {@link StandardEnvironment} implementation of 033 * {@code ConfigurableEnvironment}, but are generally applicable to any implementation, 034 * though particular default property sources may differ. 035 * 036 * <h4>Example: adding a new property source with highest search priority</h4> 037 * <pre class="code"> 038 * ConfigurableEnvironment environment = new StandardEnvironment(); 039 * MutablePropertySources propertySources = environment.getPropertySources(); 040 * Map<String, String> myMap = new HashMap<>(); 041 * myMap.put("xyz", "myValue"); 042 * propertySources.addFirst(new MapPropertySource("MY_MAP", myMap)); 043 * </pre> 044 * 045 * <h4>Example: removing the default system properties property source</h4> 046 * <pre class="code"> 047 * MutablePropertySources propertySources = environment.getPropertySources(); 048 * propertySources.remove(StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME) 049 * </pre> 050 * 051 * <h4>Example: mocking the system environment for testing purposes</h4> 052 * <pre class="code"> 053 * MutablePropertySources propertySources = environment.getPropertySources(); 054 * MockPropertySource mockEnvVars = new MockPropertySource().withProperty("xyz", "myValue"); 055 * propertySources.replace(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, mockEnvVars); 056 * </pre> 057 * 058 * When an {@link Environment} is being used by an {@code ApplicationContext}, it is 059 * important that any such {@code PropertySource} manipulations be performed 060 * <em>before</em> the context's {@link 061 * org.springframework.context.support.AbstractApplicationContext#refresh() refresh()} 062 * method is called. This ensures that all property sources are available during the 063 * container bootstrap process, including use by {@linkplain 064 * org.springframework.context.support.PropertySourcesPlaceholderConfigurer property 065 * placeholder configurers}. 066 * 067 * @author Chris Beams 068 * @since 3.1 069 * @see StandardEnvironment 070 * @see org.springframework.context.ConfigurableApplicationContext#getEnvironment 071 */ 072public interface ConfigurableEnvironment extends Environment, ConfigurablePropertyResolver { 073 074 /** 075 * Specify the set of profiles active for this {@code Environment}. Profiles are 076 * evaluated during container bootstrap to determine whether bean definitions 077 * should be registered with the container. 078 * <p>Any existing active profiles will be replaced with the given arguments; call 079 * with zero arguments to clear the current set of active profiles. Use 080 * {@link #addActiveProfile} to add a profile while preserving the existing set. 081 * @throws IllegalArgumentException if any profile is null, empty or whitespace-only 082 * @see #addActiveProfile 083 * @see #setDefaultProfiles 084 * @see org.springframework.context.annotation.Profile 085 * @see AbstractEnvironment#ACTIVE_PROFILES_PROPERTY_NAME 086 */ 087 void setActiveProfiles(String... profiles); 088 089 /** 090 * Add a profile to the current set of active profiles. 091 * @throws IllegalArgumentException if the profile is null, empty or whitespace-only 092 * @see #setActiveProfiles 093 */ 094 void addActiveProfile(String profile); 095 096 /** 097 * Specify the set of profiles to be made active by default if no other profiles 098 * are explicitly made active through {@link #setActiveProfiles}. 099 * @throws IllegalArgumentException if any profile is null, empty or whitespace-only 100 * @see AbstractEnvironment#DEFAULT_PROFILES_PROPERTY_NAME 101 */ 102 void setDefaultProfiles(String... profiles); 103 104 /** 105 * Return the {@link PropertySources} for this {@code Environment} in mutable form, 106 * allowing for manipulation of the set of {@link PropertySource} objects that should 107 * be searched when resolving properties against this {@code Environment} object. 108 * The various {@link MutablePropertySources} methods such as 109 * {@link MutablePropertySources#addFirst addFirst}, 110 * {@link MutablePropertySources#addLast addLast}, 111 * {@link MutablePropertySources#addBefore addBefore} and 112 * {@link MutablePropertySources#addAfter addAfter} allow for fine-grained control 113 * over property source ordering. This is useful, for example, in ensuring that 114 * certain user-defined property sources have search precedence over default property 115 * sources such as the set of system properties or the set of system environment 116 * variables. 117 * @see AbstractEnvironment#customizePropertySources 118 */ 119 MutablePropertySources getPropertySources(); 120 121 /** 122 * Return the value of {@link System#getProperties()} if allowed by the current 123 * {@link SecurityManager}, otherwise return a map implementation that will attempt 124 * to access individual keys using calls to {@link System#getProperty(String)}. 125 * <p>Note that most {@code Environment} implementations will include this system 126 * properties map as a default {@link PropertySource} to be searched. Therefore, it is 127 * recommended that this method not be used directly unless bypassing other property 128 * sources is expressly intended. 129 * <p>Calls to {@link Map#get(Object)} on the Map returned will never throw 130 * {@link IllegalAccessException}; in cases where the SecurityManager forbids access 131 * to a property, {@code null} will be returned and an INFO-level log message will be 132 * issued noting the exception. 133 */ 134 Map<String, Object> getSystemProperties(); 135 136 /** 137 * Return the value of {@link System#getenv()} if allowed by the current 138 * {@link SecurityManager}, otherwise return a map implementation that will attempt 139 * to access individual keys using calls to {@link System#getenv(String)}. 140 * <p>Note that most {@link Environment} implementations will include this system 141 * environment map as a default {@link PropertySource} to be searched. Therefore, it 142 * is recommended that this method not be used directly unless bypassing other 143 * property sources is expressly intended. 144 * <p>Calls to {@link Map#get(Object)} on the Map returned will never throw 145 * {@link IllegalAccessException}; in cases where the SecurityManager forbids access 146 * to a property, {@code null} will be returned and an INFO-level log message will be 147 * issued noting the exception. 148 */ 149 Map<String, Object> getSystemEnvironment(); 150 151 /** 152 * Append the given parent environment's active profiles, default profiles and 153 * property sources to this (child) environment's respective collections of each. 154 * <p>For any identically-named {@code PropertySource} instance existing in both 155 * parent and child, the child instance is to be preserved and the parent instance 156 * discarded. This has the effect of allowing overriding of property sources by the 157 * child as well as avoiding redundant searches through common property source types, 158 * e.g. system environment and system properties. 159 * <p>Active and default profile names are also filtered for duplicates, to avoid 160 * confusion and redundant storage. 161 * <p>The parent environment remains unmodified in any case. Note that any changes to 162 * the parent environment occurring after the call to {@code merge} will not be 163 * reflected in the child. Therefore, care should be taken to configure parent 164 * property sources and profile information prior to calling {@code merge}. 165 * @param parent the environment to merge with 166 * @since 3.1.2 167 * @see org.springframework.context.support.AbstractApplicationContext#setParent 168 */ 169 void merge(ConfigurableEnvironment parent); 170 171}