1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
| // org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor#postProcessEnvironment(org.springframework.core.env.ConfigurableEnvironment, org.springframework.boot.SpringApplication)
--> org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor#postProcessEnvironment(org.springframework.core.env.ConfigurableEnvironment, org.springframework.core.io.ResourceLoader, java.util.Collection<java.lang.String>)
--> new DefaultResourceLoader();
--|> org.springframework.core.io.DefaultResourceLoader#DefaultResourceLoader()
--> org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor#getConfigDataEnvironment
--> new ConfigDataEnvironment(
--|> org.springframework.boot.context.config.ConfigDataEnvironment#ConfigDataEnvironment
--|> 默认搜索路径`locations`为`"optional:classpath:/;optional:classpath:/config/"`和`"optional:file:./;optional:file:./config/;optional:file:./config/*/"`。通过使用
--> 构建`Binder`,`org.springframework.boot.context.properties.bind.Binder#get(org.springframework.core.env.Environment)`。
--> `ConfigurationPropertySources.get(environment);`略
--> new PropertySourcesPlaceholdersResolver(environment)
--> new PropertyPlaceholderHelper
--> `new Binder(sources, placeholdersResolver, null, null, defaultBindHandler);`,`defaultBindHandler`同样为 null。
--|> org.springframework.boot.context.properties.bind.Binder#Binder(java.lang.Iterable<org.springframework.boot.context.properties.source.ConfigurationPropertySource>, org.springframework.boot.context.properties.bind.PlaceholdersResolver, org.springframework.core.convert.ConversionService, java.util.function.Consumer<org.springframework.beans.PropertyEditorRegistry>, org.springframework.boot.context.properties.bind.BindHandler)
--> org.springframework.boot.context.properties.bind.Binder#Binder(java.lang.Iterable<org.springframework.boot.context.properties.source.ConfigurationPropertySource>, org.springframework.boot.context.properties.bind.PlaceholdersResolver, org.springframework.core.convert.ConversionService, java.util.function.Consumer<org.springframework.beans.PropertyEditorRegistry>, org.springframework.boot.context.properties.bind.BindHandler, org.springframework.boot.context.properties.bind.BindConstructorProvider)
--> org.springframework.boot.context.properties.bind.Binder#Binder(java.lang.Iterable<org.springframework.boot.context.properties.source.ConfigurationPropertySource>, org.springframework.boot.context.properties.bind.PlaceholdersResolver, org.springframework.core.convert.ConversionService, java.util.function.Consumer<org.springframework.beans.PropertyEditorRegistry>, org.springframework.boot.context.properties.bind.BindHandler, org.springframework.boot.context.properties.bind.BindConstructorProvider)
--> org.springframework.boot.context.properties.bind.BindConverter#get
--> 当前`conversionServices`和`propertyEditorInitializer`均为空,因此`BindConverter`获取默认转换器,包含`Converter`和`PropertyEditor`两大类。
--|> org.springframework.boot.context.properties.bind.BindConverter#getSharedInstance
--> new BindConverter(null, null);
--|> org.springframework.boot.context.properties.bind.BindConverter#BindConverter
--> new TypeConverterConversionService(propertyEditorInitializer)
--> new TypeConverterConverter(initializer)
--|> org.springframework.boot.context.properties.bind.BindConverter.TypeConverterConverter#TypeConverterConverter
--> createTypeConverter()
--|> org.springframework.boot.context.properties.bind.BindConverter.TypeConverterConverter#createTypeConverter
--> new SimpleTypeConverter()
--> new TypeConverterDelegate(this);
--|> org.springframework.beans.TypeConverterDelegate#TypeConverterDelegate(org.springframework.beans.PropertyEditorRegistrySupport)
--> registerDefaultEditors()
--> ApplicationConversionService.getSharedInstance()
--|> org.springframework.boot.convert.ApplicationConversionService#getSharedInstance
--> new ApplicationConversionService(null, true);
--|> org.springframework.boot.convert.ApplicationConversionService#ApplicationConversionService(org.springframework.util.StringValueResolver, boolean)
--> org.springframework.boot.convert.ApplicationConversionService#configure
--|> 批量注册`Converter`和`Formatter`。
--> 使用`BindConstructorProvider.DEFAULT`。
--> 两种 Binder `ValueObjectBinder`和`JavaBeanBinder`。
--> logger 为`DeferredLogs`。
--> createConfigDataLocationResolvers(
--|> org.springframework.boot.context.config.ConfigDataEnvironment#createConfigDataLocationResolvers
--> new ConfigDataLocationResolvers(
--|> org.springframework.boot.context.config.ConfigDataLocationResolvers
--> 获取`ConfigDataLocationResolver.class`实现类,`SpringFactoriesLoader.loadFactoryNames(ConfigDataLocationResolver.class`。
--> org.springframework.boot.context.config.ConfigDataLocationResolvers#ConfigDataLocationResolvers(org.springframework.boot.logging.DeferredLogFactory, org.springframework.boot.ConfigurableBootstrapContext, org.springframework.boot.context.properties.bind.Binder, org.springframework.core.io.ResourceLoader, java.util.List<java.lang.String>)
--> 填充`DeferredLogFactory.class`等信息。
--> 实例化`ConfigDataLocationResolver.class`实现类,默认2个,有序排列为`ConfigTreeConfigDataLocationResolver`和`StandardConfigDataLocationResolver`。
--> ConfigTreeConfigDataLocationResolver
--> StandardConfigDataLocationResolver
--> SpringFactoriesLoader.loadFactories(PropertySourceLoader.class
--|> 获取并实例化`PropertySourceLoader.class`实现类。
--|> 默认支持如下2种
--|> PropertiesPropertySourceLoader 支持查找`properties`和`xml`。
--|> YamlPropertySourceLoader 支持查找`yml`和`yaml` 。
--> 入参`this.environmentUpdateListener`为空,使用默认空实现`ConfigDataEnvironmentUpdateListener.NONE`,无逻辑。
--|> 该类监听器响应2种事件,分别为
--|> `onPropertySourceAdded`,属性源添加事件。
--|> `onSetProfiles`,profile 设置事件。
--> new ConfigDataLoaders(
--> SpringFactoriesLoader.loadFactoryNames(ConfigDataLoader.class, classLoader))
--|> 获取并实例化`ConfigDataLoader.class`实现类。
--|> 默认支持如下2种
--|> ConfigTreeConfigDataLoader
--|> StandardConfigDataLoader
--> `createContributors(binder);`
--|> org.springframework.boot.context.config.ConfigDataEnvironment#createContributors(org.springframework.boot.context.properties.bind.Binder)
--> for-each 遍历 propertySources,封装为`ConfigDataEnvironmentContributor`
--|> 此处忽略名称为`defaultProperties`的 propertySource,后续封装。应当是为了适配优先级。
--> ConfigDataEnvironmentContributor.ofExisting(propertySource)
--|> 类型为`org.springframework.boot.context.config.ConfigDataEnvironmentContributor.Kind#EXISTING`。
--> 添加若干个初始`ImportContributor`。
--|> 类型为`org.springframework.boot.context.config.ConfigDataEnvironmentContributor.Kind#INITIAL_IMPORT`。
--|> 对应配置参数如下:
--> spring.config.import
--> spring.config.additional-location
--> spring.config.location
--|> 默认搜索路径如下
--> "optional:classpath:/;optional:classpath:/config/"
--> "optional:file:./;optional:file:./config/;optional:file:./config/*/"
--> 如果存在,则将名称为`defaultProperties`的 propertySource 封装为`ConfigDataEnvironmentContributor`。
--> org.springframework.boot.context.config.ConfigDataEnvironment#processAndApply
--> `new ConfigDataImporter(`
--|> Imports ConfigData by resolving and loading locations. resources are tracked to ensure that they are not imported multiple times.
--|> 通过解析和加载位置来导入配置数据。跟踪资源以确保它们不会被多次导入。
--> 使用`DeferredLogs`,`ConfigDataLocationResolvers`,`ConfigDataLoaders`
--> 在`bootstrapContext`中注册`org.springframework.boot.context.properties.bind.Binder`为原型 bean。
--> `processInitial(`
--> 创建`ConfigDataActivationContext`。`createActivationContext(`
--> 加载与 profile 无关的配置文件。`processWithoutProfiles(`
--> 再次创建`ConfigDataActivationContext`。`withProfiles(`
--> 加载制定 profile 的配置文件。`processWithProfiles(`
--> 应用到 environment 中。`applyToEnvironment(`
|