从SpringApplication
实例化,到调用run
方法,触发ApplicationStartingEvent
事件,触发ApplicationEnvironmentPreparedEvent
事件,environment
对象中已经存储了一些配置数据,这里以servlet
为例。
ApplicationServletEnvironment
{"__type__": "ApplicationServletEnvironment","__super__": {"__type__": "StandardServletEnvironment","__super__": {"__type__": "StandardEnvironment","__super__": {"__type__": "AbstractEnvironment","IGNORE_GETENV_PROPERTY_NAME": "spring.getenv.ignore","ACTIVE_PROFILES_PROPERTY_NAME": "spring.profiles.active","DEFAULT_PROFILES_PROPERTY_NAME": "spring.profiles.default","RESERVED_DEFAULT_PROFILE_NAME": "default","logger": {"__type__": "Log"},"activeProfiles": [],"defaultProfiles": [ "default" ],"propertySources": {"__type__": "MutablePropertySources","propertySourceList": [{"__type__": "ConfigurationPropertySourcesPropertySource","__super__": {"__type__": "PropertySource","name": "configurationProperties","source": {"__type__": "SpringConfigurationPropertySources","sources": "@AbstractEnvironment.propertySources"}}},{"__type__": "SimpleCommandLinePropertySource","__super__": {"__type__": "CommandLinePropertySource","__super__": {"__type__": "EnumerablePropertySource","__super__": {"__type__": "PropertySource","name": "commandLineArgs","source": {"__type__": "CommandLineArgs","optionArgs": {},"nonOptionArgs": []}}},"COMMAND_LINE_PROPERTY_SOURCE_NAME": "commandLineArgs","DEFAULT_NON_OPTION_ARGS_PROPERTY_NAME": "nonOptionArgs","nonOptionArgsPropertyName": "nonOptionArgs"}},{"__type__": "StubPropertySource","__super__": {"__type__": "PropertySource","name": "servletConfigInitParams","source": {}}},{"__type__": "StubPropertySource","__super__": {"__type__": "PropertySource","name": "servletContextInitParams","source": {}}},{"__type__": "PropertiesPropertySource","__super__": {"__type__": "MapPropertySource","__super__": {"__type__": "EnumerablePropertySource","__super__": {"__type__": "PropertySource","name": "systemProperties","source": "对象,JVM系统变量"}}}},{"__type__": "OriginAwareSystemEnvironmentPropertySource","__super__": {"__type__": "SystemEnvironmentPropertySource","__super__": {"__type__": "MapPropertySource","__super__": {"__type__": "EnumerablePropertySource","__super__": {"__type__": "PropertySource","name": "systemEnvironment","source": "对象,操作系统变量"}}}},"prefix": null},{"__type__": "RandomValuePropertySource","RANDOM_PROPERTY_SOURCE_NAME": "random","PREFIX": "random.","__super__": {"__type__": "PropertySource","name": "random","source": {"__type__": "Random"}}}]},"propertyResolver": {"__type__": "PropertySourcesPropertyResolver","__super__": {"__type__": "AbstractPropertyResolver","logger": {"__type__": "Log","conversionService": {"__type__": "ApplicationConversionService","__super__": {"__type__": "FormattingConversionService","__super__": {"__type__": "GenericConversionService","NO_OP_CONVERTER": {"__type__": "NoOpConverter","name": "NO_OP"},"NO_MATCH": {"__type__": "NoOpConverter","name": "NO_MATCH"},"converters": {"__type__": "Converters","globalConverters": [],"converters": {}},"converterCache": {}},"embeddedValueResolver": null,"cachedPrinters": {},"cachedParsers": {}},"sharedInstance": null,"unmodifiable": false,},"nonStrictHelper": null,"strictHelper": null,"ignoreUnresolvableNestedPlaceholders": false,"placeholderPrefix": "${","placeholderSuffix": "}","valueSeparator": ":","requiredProperties": [],}},"propertySources": "@AbstractEnvironment.propertySources"}},"SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME": "systemEnvironment","SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME": "systemProperties",},"SERVLET_CONTEXT_PROPERTY_SOURCE_NAME": "servletContextInitParams","SERVLET_CONFIG_PROPERTY_SOURCE_NAME": "servletConfigInitParams","JNDI_PROPERTY_SOURCE_NAME": "jndiProperties","jndiPresent": false}
}
propertySources
中共有5个配置集合,带顺序
配置集合 | 说明 |
---|---|
configurationProperties | 指向propertySources 对象 |
commandLineArgs | 命令行参数 |
servletConfigInitParams | servletConfig 配置参数,当前占位 |
servletContextInitParams | servletContext 配置参数,当前占位 |
systemProperties | JVM 环境变量 |
systemEnvironment | 操作系统环境变量 |
random | 一个Random 实例 |
另外还有
云平台的配置集合,名称是vcap
jndi
配置集合,名称是jndiProperties
spring.application.json
的配置集合,名称是spring.application.json
ConfigDataEnvironment
这个对象的processAndApply
方法,涉及点过多,要读懂,得一个类以个类理解。
整理涉及到的类
{"__type__": "ConfigDataEnvironment","LOCATION_PROPERTY": "spring.config.location","ADDITIONAL_LOCATION_PROPERTY": "spring.config.additional-location","IMPORT_PROPERTY": "spring.config.import","ON_NOT_FOUND_PROPERTY": "spring.config.on-not-found","DEFAULT_SEARCH_LOCATIONS": [{"__type__": "ConfigDataLocation","OPTIONAL_PREFIX": "optional:","optional": true,"value": "classpath:/;optional:classpath:/config/","origin": null},{"__type__": "ConfigDataLocation","OPTIONAL_PREFIX": "optional:","optional": true,"value": "file:./;optional:file:./config/;optional:file:./config/*/","origin": null}],"EMPTY_LOCATIONS": [],"CONFIG_DATA_LOCATION_ARRAY": {"__type__": "Bindable"},"STRING_LIST": {"__type__": "Bindable"},"ALLOW_INACTIVE_BINDING": [],"DENY_INACTIVE_BINDING": [{"__type__": "BinderOption.FAIL_ON_BIND_TO_INACTIVE_SOURCE"}],"logFactory": "@ConfigDataEnvironmentPostProcessor.logFactory","logger": {"__type__": "DeferredLog","destinationSupplier": "() -> LogFactory.getLog(org.springframework.boot.context.config.ConfigDataEnvironment)","lines": {"__type__": "Lines","lines": []}},"notFoundAction": {"__type__": "BindResult"},"bootstrapContext": "@ConfigDataEnvironmentPostProcessor.bootstrapContext","environment": "ApplicationServletEnvironment","resolvers": {"__type__": "ConfigDataLocationResolvers","resolvers": [{"__type__": "ConfigTreeConfigDataLocationResolver","PREFIX": "configtree:","resourceLoader": {"__type__": "LocationResourceLoader","EMPTY_RESOURCES": [],"FILE_PATH_COMPARATOR": {},"FILE_NAME_COMPARATOR": {},"resourceLoader": {"__type__": "DefaultResourceLoader","classLoader": null,"protocolResolvers": [],"resourceCaches": {}}}},{"__type__": "StandardConfigDataLocationResolver","PREFIX": "resource:","CONFIG_NAME_PROPERTY": "spring.config.name","DEFAULT_CONFIG_NAMES": [ "application" ],"URL_PREFIX": {"__type__": "Pattern","pattern": "^([a-zA-Z][a-zA-Z0-9*]*?:)(.*$)","flags": 0},"EXTENSION_HINT_PATTERN": {"__type__": "Pattern","pattern": "^(.*)\\[(\\.\\w+)\\](?!\\[)$","flags": 0},"NO_PROFILE": null,"logger": {"__type__": "DeferredLog","destinationSupplier": "() -> LogFactory.getLog(org.springframework.boot.context.config.StandardConfigDataLocationResolver)","lines": {"__type__": "Lines","lines": []}},"propertySourceLoaders": [{"__type__": "PropertiesPropertySourceLoader","XML_FILE_EXTENSION": ".xml"},{"__type__": "YamlPropertySourceLoader",}],"configNames": [ "application" ],"resourceLoader": {"__type__": "LocationResourceLoader","EMPTY_RESOURCES": [],"FILE_PATH_COMPARATOR": {},"FILE_NAME_COMPARATOR": {},"resourceLoader": {"__type__": "DefaultResourceLoader","classLoader": null,"protocolResolvers": [],"resourceCaches": {}}},}]},"additionalProfiles": null,"environmentUpdateListener": {"__type__": "ConfigDataEnvironmentUpdateListener"},"loaders": {"__type__": "ConfigDataLoaders","logger": {"__type__": "DeferredLog","destinationSupplier": "() -> LogFactory.getLog(org.springframework.boot.context.config.ConfigTreeConfigDataLoader)","lines": {"__type__": "Lines","lines": []}},"loaders": [{"__type__": "ConfigTreeConfigDataLoader"},{"__type__": "StandardConfigDataLoader"}],"resourceTypes": [ "ConfigTreeConfigDataLoader", "StandardConfigDataLoader" ]},"contributors": null
}
Binder
{"__type__": "Binder","NON_BEAN_CLASSES": [ "Object.class", "Class.class" ],"sources": "@ConfigurationPropertySourcesPropertySource.source","placeholdersResolver": {"__type__": "PropertySourcesPlaceholdersResolver","sources": "@ConfigurationPropertySourcesPropertySource.source","helper": {"__type__": "PropertyPlaceholderHelper","logger": "org.springframework.util.PropertyPlaceholderHelper","wellKnownSimplePrefixes": {"}": "{","]": "[",")": "("},"placeholderPrefix": "${","placeholderSuffix": "}","simplePrefix": "${","valueSeparator": ":","ignoreUnresolvablePlaceholders": true}},"bindConverter": {"__type__": "BindConverter","sharedInstance": "BindConverter","delegates": [{"__type__": "TypeConverterConversionService","__super__": {"__type__": "GenericConversionService"}},{"__type__": "ApplicationConversionService","__super__": {"__type__": "FormattingConversionService","__super__": {"__type__": "GenericConversionService","NO_OP_CONVERTER": {"__type__": "NoOpConverter","name": "NO_OP"},"NO_MATCH": {"__type__": "NoOpConverter","name": "NO_MATCH"},"converters": {"__type__": "Converters","globalConverters": [],"converters": {}},"converterCache": {}},"embeddedValueResolver": null,"cachedPrinters": {},"cachedParsers": {}},"sharedInstance": "ApplicationConversionService","unmodifiable": true,}]},"defaultBindHandler": {"__type__": "BindHandler"},"dataObjectBinders": [{"__type__": "ValueObjectBinder","constructorProvider": {"__type__": "DefaultBindConstructorProvider"}},{"__type__": "JavaBeanBinder"}]
}
ConfigurationPropertyName
这个类里面有两个静态内部类
Elements
ElementsParser
ElementsParser
会把配置名称解析为Elements
比如spring.config.on-not-found
,会被解析成
start = [ 0, 7, 14 ]
end = [ 6, 13, 26 ]
size = 3
也就是解析成三个token,方便查找和替换。
这个解析器也支持中括号[
]
,里面可以是数字索引,也可以是属性名。