spring SpringConfigurationPropertySource 源码
springboot SpringConfigurationPropertySource 代码
文件路径:/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/source/SpringConfigurationPropertySource.java
/*
* Copyright 2012-2022 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.context.properties.source;
import java.util.Map;
import java.util.Random;
import org.springframework.boot.context.properties.source.ConfigurationPropertyName.Form;
import org.springframework.boot.origin.Origin;
import org.springframework.boot.origin.PropertySourceOrigin;
import org.springframework.core.env.EnumerablePropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.env.SystemEnvironmentPropertySource;
import org.springframework.util.Assert;
/**
* {@link ConfigurationPropertySource} backed by a non-enumerable Spring
* {@link PropertySource} or a restricted {@link EnumerablePropertySource} implementation
* (such as a security restricted {@code systemEnvironment} source). A
* {@link PropertySource} is adapted with the help of a {@link PropertyMapper} which
* provides the mapping rules for individual properties.
* <p>
* Each {@link ConfigurationPropertySource#getConfigurationProperty
* getConfigurationProperty} call attempts to
* {@link PropertyMapper#map(ConfigurationPropertyName) map} the
* {@link ConfigurationPropertyName} to one or more {@code String} based names. This
* allows fast property resolution for well-formed property sources.
* <p>
* When possible the {@link SpringIterableConfigurationPropertySource} will be used in
* preference to this implementation since it supports full "relaxed" style resolution.
*
* @author Phillip Webb
* @author Madhura Bhave
* @see #from(PropertySource)
* @see PropertyMapper
* @see SpringIterableConfigurationPropertySource
*/
class SpringConfigurationPropertySource implements ConfigurationPropertySource {
private static final PropertyMapper[] DEFAULT_MAPPERS = { DefaultPropertyMapper.INSTANCE };
private static final PropertyMapper[] SYSTEM_ENVIRONMENT_MAPPERS = { SystemEnvironmentPropertyMapper.INSTANCE,
DefaultPropertyMapper.INSTANCE };
private final PropertySource<?> propertySource;
private final PropertyMapper[] mappers;
/**
* Create a new {@link SpringConfigurationPropertySource} implementation.
* @param propertySource the source property source
* @param mappers the property mappers
*/
SpringConfigurationPropertySource(PropertySource<?> propertySource, PropertyMapper... mappers) {
Assert.notNull(propertySource, "PropertySource must not be null");
Assert.isTrue(mappers.length > 0, "Mappers must contain at least one item");
this.propertySource = propertySource;
this.mappers = mappers;
}
@Override
public ConfigurationProperty getConfigurationProperty(ConfigurationPropertyName name) {
if (name == null) {
return null;
}
for (PropertyMapper mapper : this.mappers) {
try {
for (String candidate : mapper.map(name)) {
Object value = getPropertySource().getProperty(candidate);
if (value != null) {
Origin origin = PropertySourceOrigin.get(this.propertySource, candidate);
return ConfigurationProperty.of(this, name, value, origin);
}
}
}
catch (Exception ex) {
}
}
return null;
}
@Override
public ConfigurationPropertyState containsDescendantOf(ConfigurationPropertyName name) {
PropertySource<?> source = getPropertySource();
Object underlyingSource = source.getSource();
if (underlyingSource instanceof Random) {
return containsDescendantOfForRandom("random", name);
}
if (underlyingSource instanceof PropertySource<?> underlyingPropertySource
&& underlyingPropertySource.getSource() instanceof Random) {
// Assume wrapped random sources use the source name as the prefix
return containsDescendantOfForRandom(source.getName(), name);
}
return ConfigurationPropertyState.UNKNOWN;
}
private static ConfigurationPropertyState containsDescendantOfForRandom(String prefix,
ConfigurationPropertyName name) {
if (name.getNumberOfElements() > 1 && name.getElement(0, Form.DASHED).equals(prefix)) {
return ConfigurationPropertyState.PRESENT;
}
return ConfigurationPropertyState.ABSENT;
}
@Override
public Object getUnderlyingSource() {
return this.propertySource;
}
protected PropertySource<?> getPropertySource() {
return this.propertySource;
}
protected final PropertyMapper[] getMappers() {
return this.mappers;
}
@Override
public String toString() {
return this.propertySource.toString();
}
/**
* Create a new {@link SpringConfigurationPropertySource} for the specified
* {@link PropertySource}.
* @param source the source Spring {@link PropertySource}
* @return a {@link SpringConfigurationPropertySource} or
* {@link SpringIterableConfigurationPropertySource} instance
*/
static SpringConfigurationPropertySource from(PropertySource<?> source) {
Assert.notNull(source, "Source must not be null");
PropertyMapper[] mappers = getPropertyMappers(source);
if (isFullEnumerable(source)) {
return new SpringIterableConfigurationPropertySource((EnumerablePropertySource<?>) source, mappers);
}
return new SpringConfigurationPropertySource(source, mappers);
}
private static PropertyMapper[] getPropertyMappers(PropertySource<?> source) {
if (source instanceof SystemEnvironmentPropertySource && hasSystemEnvironmentName(source)) {
return SYSTEM_ENVIRONMENT_MAPPERS;
}
return DEFAULT_MAPPERS;
}
private static boolean hasSystemEnvironmentName(PropertySource<?> source) {
String name = source.getName();
return StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME.equals(name)
|| name.endsWith("-" + StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME);
}
private static boolean isFullEnumerable(PropertySource<?> source) {
PropertySource<?> rootSource = getRootSource(source);
if (rootSource.getSource() instanceof Map) {
// Check we're not security restricted
try {
((Map<?, ?>) rootSource.getSource()).size();
}
catch (UnsupportedOperationException ex) {
return false;
}
}
return (source instanceof EnumerablePropertySource);
}
private static PropertySource<?> getRootSource(PropertySource<?> source) {
while (source.getSource() != null && source.getSource() instanceof PropertySource) {
source = (PropertySource<?>) source.getSource();
}
return source;
}
}
相关信息
相关文章
spring AliasedConfigurationPropertySource 源码
spring AliasedIterableConfigurationPropertySource 源码
spring CachingConfigurationPropertySource 源码
spring ConfigurationProperty 源码
spring ConfigurationPropertyCaching 源码
spring ConfigurationPropertyName 源码
spring ConfigurationPropertyNameAliases 源码
spring ConfigurationPropertySource 源码
0
赞
- 所属分类: 后端技术
- 本文标签: Spring Boot Java Spring
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
8、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦