spring boot 调整日志打印情况
logging:
level:
com:
alibaba:
cloud: debug
# nacos: debug
org:
springframework:
context: debug
cloud: debug
# boot: debug
项目启动时打印了
properties search order:PROPERTIES->JVM->ENV->DEFAULT_SETTING
查看具体代码位置,发现位于 nacos-client 中
SearchableProperties
private List<AbstractPropertySource> sortPropertySourceDefaultOrder(
AbstractPropertySource... propertySources) {
final Map<SourceType, AbstractPropertySource> sourceMap = Arrays.stream(propertySources)
.collect(Collectors.toMap(AbstractPropertySource::getType, propertySource -> propertySource));
final List<AbstractPropertySource> collect = DEFAULT_ORDER.stream().map(sourceMap::get)
.collect(Collectors.toList());
LOGGER.info("properties search order:PROPERTIES->JVM->ENV->DEFAULT_SETTING");
return collect;
}
其中 DEFAULT_ORDER 引用当前类的全局变量
private static final List<SourceType> DEFAULT_ORDER = Arrays.asList(SourceType.PROPERTIES, SourceType.JVM,
SourceType.ENV, SourceType.DEFAULT_SETTING);
间接引用 SourceType
package com.alibaba.nacos.client.env;
enum SourceType {
/**
* get value from properties.
*/
PROPERTIES,
/**
* get value from jvm args.
*/
JVM,
/**
* get value from system environment.
*/
ENV,
/**
* get value from default setting.
*/
DEFAULT_SETTING
}
通过模板模式来对各种参数的获取
package com.alibaba.nacos.client.env;
import java.util.Properties;
abstract class AbstractPropertySource {
/**
* get property's type.
* @return name
*/
abstract SourceType getType();
/**
* get property, if the value can not be got by the special key, the null will be returned.
* @param key special key
* @return value or null
*/
abstract String getProperty(String key);
/**
* Tests if the specified object is a key in this propertySource.
* @param key key – possible key
* @return true if and only if the specified object is a key in this propertySource, false otherwise.
*/
abstract boolean containsKey(String key);
/**
* to properties.
* @return properties
*/
abstract Properties asProperties();
}
PROPERTIES
package com.alibaba.nacos.client.env;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import java.util.Properties;
class PropertiesPropertySource extends AbstractPropertySource {
private final Properties properties = new Properties();
private final PropertiesPropertySource parent;
PropertiesPropertySource() {
this.parent = null;
}
PropertiesPropertySource(PropertiesPropertySource parent) {
this.parent = parent;
}
@Override
SourceType getType() {
return SourceType.PROPERTIES;
}
@Override
String getProperty(String key) {
return getProperty(this, key);
}
private String getProperty(PropertiesPropertySource propertiesPropertySource, String key) {
final String value = propertiesPropertySource.properties.getProperty(key);
if (value != null) {
return value;
}
final PropertiesPropertySource parent = propertiesPropertySource.parent;
if (parent == null) {
return null;
}
return getProperty(parent, key);
}
@Override
boolean containsKey(String key) {
return containsKey(this, key);
}
boolean containsKey(PropertiesPropertySource propertiesPropertySource, String key) {
final boolean exist = propertiesPropertySource.properties.containsKey(key);
if (exist) {
return true;
}
final PropertiesPropertySource parent = propertiesPropertySource.parent;
if (parent == null) {
return false;
}
return containsKey(parent, key);
}
@Override
Properties asProperties() {
List<Properties> propertiesList = new ArrayList<>(8);
propertiesList = lookForProperties(this, propertiesList);
Properties ret = new Properties();
final ListIterator<Properties> iterator = propertiesList.listIterator(propertiesList.size());
while (iterator.hasPrevious()) {
final Properties properties = iterator.previous();
ret.putAll(properties);
}
return ret;
}
List<Properties> lookForProperties(PropertiesPropertySource propertiesPropertySource, List<Properties> propertiesList) {
propertiesList.add(propertiesPropertySource.properties);
final PropertiesPropertySource parent = propertiesPropertySource.parent;
if (parent == null) {
return propertiesList;
}
return lookForProperties(parent, propertiesList);
}
synchronized void setProperty(String key, String value) {
properties.setProperty(key, value);
}
synchronized void addProperties(Properties source) {
properties.putAll(source);
}
}
JVM
package com.alibaba.nacos.client.env;
import java.util.Properties;
class JvmArgsPropertySource extends AbstractPropertySource {
private final Properties properties;
JvmArgsPropertySource() {
this.properties = System.getProperties();
}
@Override
SourceType getType() {
return SourceType.JVM;
}
@Override
String getProperty(String key) {
return properties.getProperty(key);
}
@Override
boolean containsKey(String key) {
return properties.containsKey(key);
}
@Override
Properties asProperties() {
Properties properties = new Properties();
properties.putAll(this.properties);
return properties;
}
}
jvm参数通过 System.getProperties() 来获取。
ENV
package com.alibaba.nacos.client.env;
import java.util.Map;
import java.util.Properties;
class SystemEnvPropertySource extends AbstractPropertySource {
private final Map<String, String> env = System.getenv();
@Override
SourceType getType() {
return SourceType.ENV;
}
@Override
String getProperty(String key) {
String checkedKey = checkPropertyName(key);
if (checkedKey == null) {
final String upperCaseKey = key.toUpperCase();
if (!upperCaseKey.equals(key)) {
checkedKey = checkPropertyName(upperCaseKey);
}
}
if (checkedKey == null) {
return null;
}
return env.get(checkedKey);
}
/**
* copy from https://github.com/spring-projects/spring-framework.git
* Copyright 2002-2021 the original author or authors.
* Since:
* 3.1
* Author:
* Chris Beams, Juergen Hoeller
*/
private String checkPropertyName(String name) {
// Check name as-is
if (containsKey(name)) {
return name;
}
// Check name with just dots replaced
String noDotName = name.replace('.', '_');
if (!name.equals(noDotName) && containsKey(noDotName)) {
return noDotName;
}
// Check name with just hyphens replaced
String noHyphenName = name.replace('-', '_');
if (!name.equals(noHyphenName) && containsKey(noHyphenName)) {
return noHyphenName;
}
// Check name with dots and hyphens replaced
String noDotNoHyphenName = noDotName.replace('-', '_');
if (!noDotName.equals(noDotNoHyphenName) && containsKey(noDotNoHyphenName)) {
return noDotNoHyphenName;
}
// Give up
return null;
}
@Override
boolean containsKey(String name) {
return this.env.containsKey(name);
}
@Override
Properties asProperties() {
Properties properties = new Properties();
properties.putAll(this.env);
return properties;
}
}
环境变量通过 System.getenv() 来获取。
DEFAULT_SETTING
package com.alibaba.nacos.client.env;
import com.alibaba.nacos.common.utils.ResourceUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.InputStream;
import java.util.Properties;
class DefaultSettingPropertySource extends AbstractPropertySource {
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultSettingPropertySource.class);
private static final String DEFAULT_SETTING_PATH = "classpath:nacos_default_setting.properties";
private final Properties defaultSetting = new Properties();
DefaultSettingPropertySource() {
try (final InputStream inputStream = ResourceUtils.getResourceUrl(DEFAULT_SETTING_PATH).openStream()) {
defaultSetting.load(inputStream);
} catch (Exception e) {
LOGGER.error("load default setting failed", e);
}
}
@Override
SourceType getType() {
return SourceType.DEFAULT_SETTING;
}
@Override
String getProperty(String key) {
return defaultSetting.getProperty(key);
}
@Override
boolean containsKey(String key) {
return defaultSetting.containsKey(key);
}
@Override
Properties asProperties() {
Properties properties = new Properties();
properties.putAll(defaultSetting);
return properties;
}
}
默认设置读取 nacos_default_setting.properties 中的配置。