オリジナル:Javaのキャンプ(マイクロチャンネル公共数:ジャワ派)が、共有してください、ソースを保管してください再現。
序文
本稿バージョンで2.2.0.RELEASE
このようなSpringBootソースを見てのようないくつかの一般的な問題を把握するSpringBoot設定処理のソースコードを分析します。
- SpringBootどこコンフィギュレーション・ファイルのロードを開始するには?
- どの場所からコンフィギュレーション・ファイルをロードSpringBoot?
- どのようにSpringBootサポート
yaml
およびproperties
プロファイルのタイプ? - サポートしたい場合
json
の設定を、あなたは何をすべきでしょうか? - SpringBoot構成の最適化レベルはどのようにのようなものでしょうか?
- プレースホルダは、それが解決される方法ですか?
私たちの問題に答えを見つけるために、構成関連のソースコードをSpringBootか見に行きました。
SpringBootどこコンフィギュレーション・ファイルのロードを開始するには?
SpringBoot負荷設定ファイルのエントリがあるApplicationEnvironmentPreparedEvent
中、コンストラクタ意志SpringApplicationによって着信イベント、SpringBoot spring.factories
クラスファイルのApplicationListener例を取得します:
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
...
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
...
}
复制代码
spring.factories
ありConfigFileApplicationListener
リッスンするクラスApplicationEnvironmentPreparedEvent
と、構成ファイルをロードするには:
# Application Listeners
org.springframework.context.ApplicationListener= org.springframework.boot.context.config.ConfigFileApplicationListener
...
复制代码
あなたはクラスのイベントとイベント処理、その後、イベントを送信する場所を見つけるしたら、あなたは初期化さ良いSpringApplicationRunListenersにこのクラスを開始する前にSpringBootは、SpringBoot設定ファイルでロードする方法を見つけ出すことができ、それは、イベントのSpringApplicationRunListenerのインタフェースを実装します転送:
class SpringApplicationRunListeners {
private final Log log;
private final List<SpringApplicationRunListener> listeners;
SpringApplicationRunListeners(Log log, Collection<? extends SpringApplicationRunListener> listeners) {
this.log = log;
this.listeners = new ArrayList<>(listeners);
}
void environmentPrepared(ConfigurableEnvironment environment) {
for (SpringApplicationRunListener listener : this.listeners) {
listener.environmentPrepared(environment);
}
}
...
}
复制代码
SpringApplicationRunListenersコードを取得し、次のとおりです。
private SpringApplicationRunListeners getRunListeners(String[] args) {
Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
return new SpringApplicationRunListeners(logger,
getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args));
}
复制代码
同じロード行くspring.factories
EventPublishingRunListenerクラスを持つファイルを、このようなイベントの役割はSpringBootが送らApplicationEventに変換されます。
# Run Listeners
org.springframework.boot.SpringApplicationRunListener=\
org.springframework.boot.context.event.EventPublishingRunListener
复制代码
概要
- SpringBootイベントがApplicationEventを再配布するために変換されます
- SpringBootは聞いている
ApplicationEnvironmentPreparedEvent
プロファイルのイベントをロードするために - ConfigFileApplicationListenerは、メインの設定ファイルの処理であります
どの場所からコンフィギュレーション・ファイルをロードSpringBoot?
上記の分析はConfigFileApplicationListenerに持っているメインクラスは、設定ファイルを処理し、その後さらに、SpringBootがどのアドレスからのコンフィギュレーション・ファイルをロードしている参照ConfigFileApplicationListenerクラスを入力した後、2つのデフォルトの定数を持っています。
private static final String DEFAULT_SEARCH_LOCATIONS = "classpath:/,classpath:/config/,file:./,file:./config/";
private static final String DEFAULT_NAMES = "application";
复制代码
まず、例任意の構成が存在しない場合に、からDEFAULT_SEARCH_LOCATIONS
のロケーション記載されているファイルの名前の定数のロードDEFAULT_NAMES(.properties或yml)
ファイルを、デフォルトの場所は次のとおりです。
- クラスパスのルート(クラスパス:/)
- 設定ファイルのディレクトリ内のクラスパス(クラスパス:/設定/)
- プログラムの実行ディレクトリ(ファイル:./)
- プログラムの実行ディレクトリの下のconfigディレクトリ(ファイル:./のconfig /)
それは例追加の構成は、構成ファイルの検索パスを指定するのに十分な柔軟性SpringBoot、プロファイル名が存在しないと言い、ConfigFileApplicationListenerの内のクラスがありgetSearchLocations
、構成ディレクトリ検索を取得するために主に責任がある方法は、:
private Set<String> getSearchLocations() {
if (this.environment.containsProperty(CONFIG_LOCATION_PROPERTY)) {
return getSearchLocations(CONFIG_LOCATION_PROPERTY);
}
Set<String> locations = getSearchLocations(CONFIG_ADDITIONAL_LOCATION_PROPERTY);
locations.addAll(
asResolvedSet(ConfigFileApplicationListener.this.searchLocations, DEFAULT_SEARCH_LOCATIONS));
return locations;
}
复制代码
これは次のように手順:
- チェックし
spring.config.location
、その値が直接使用されている場合、プロパティ - 以下からの
spring.config.additional-location
検索パスにプロパティを取得 - 検索コレクションのデフォルトの検索パス
ここでは、2例の検索パスSpringBoot構成を決定することができます構成されている場合spring.config.location
、直接、そうでない場合は使用spring.config.additional-location
プロパティ値+デフォルトの検索パスを。
どのようにSpringBootサポートyaml
およびproperties
プロファイルのタイプ?
SpringBoot設定サポートproperties
とyaml
ファイル、SpringBoot分析していき、これら二つの文書にそれを解決するためにどのようにConfigFileApplicationListener
このカテゴリを、と呼ばれるサブカテゴリーがあるLoader
負荷プロファイルの主な仕事は、これらの商品の責任であるが、直接読み込むproperties
とyaml
とに変換するPropertySource
かによって、内部PropertySourceLoader
に責任があります:
Loader(ConfigurableEnvironment environment, ResourceLoader resourceLoader) {
...
this.propertySourceLoaders = SpringFactoriesLoader.loadFactories(PropertySourceLoader.class,
getClass().getClassLoader());
}
复制代码
構築しLoader
、それがPropertySourceLoader、ロードまたはからロードされるオブジェクトspring.factories
の読み取りを:
# PropertySource Loaders
org.springframework.boot.env.PropertySourceLoader=\
org.springframework.boot.env.PropertiesPropertySourceLoader,\
org.springframework.boot.env.YamlPropertySourceLoader
复制代码
前記2 PropertySourceLoader実装クラスの設定:
- PropertiesPropertySourceLoader
- YamlPropertySourceLoader
知っている名前を参照してください責任があるであるproperties
とyaml
友人。
サポートしたい場合json
の設定を、あなたは何をすべきでしょうか?
あなたが好きではない場合properties
とyaml
の両方の形式は、定義したいjson
設定テキスト形式としてPropertySourceLoaderの直接JSON形式を定義することができます。
public class JSONPropertySourceLoader implements PropertySourceLoader {
@Override
public String[] getFileExtensions() {
return new String[] {"json"};
}
@Override
public List<PropertySource<?>> load(String name, Resource resource) throws IOException {
if(resource == null || !resource.exists()){
return Collections.emptyList();
}
Map<String, Object> configs = JSON.parseObject(resource.getInputStream(), Map.class);
return Collections.singletonList(
new MapPropertySource(name, configs)
);
}
}
复制代码
その後でresources
ディレクトリの設立META-INF
、その後、追加しspring.factories
、次のようなコンテンツを:
org.springframework.boot.env.PropertySourceLoader=\
com.csbaic.arch.spring.env.loader.JSONPropertySourceLoader
复制代码
最後に、resources
ディレクトリの構築application.json
設定ファイルを:
{
"spring.application.name": "JSONConfig"
}
复制代码
通常の開始を取得SpringBoot spring.applicaiton.name
値の設定ですJSONConfig
。
2019-11-02 14:50:17.730 INFO 55275 --- [ main] c.c.a.spring.env.SpringEnvApplication : JSONConfig
复制代码
SpringBoot構成の最適化レベルはどのようにのようなものでしょうか?
SpringBootのあるPropertySource
一般的な実装クラスがあるプロパティを保存するために設計されたインタフェース:
- CommandLinePropertySource
- MapPropertySource
- SystemEnvironmentPropertySource
- ....
集中管理に加えてPropertySource
も抽象であるPropertySources
というクラスを達成するためのインタフェース、PropertySources:MutablePropertySourcesを、それをすべてPropertySourceが挙げに配置されるpropertySourceList
動作のいくつかの修飾方法を提供しながら、セット。
public void addFirst(PropertySource<?> propertySource) {}
public void addLast(PropertySource<?> propertySource) {}
public void addBefore(String relativePropertySourceName, PropertySource<?> propertySource) {}
public void addAfter(String relativePropertySourceName, PropertySource<?> propertySource) {}
public int precedenceOf(PropertySource<?> propertySource) { }
public PropertySource<?> remove(String name) {}
public void replace(String name, PropertySource<?> propertySource) {}
复制代码
すべてPropertySourceがpropertySourceListに格納されている、小さな屈折率の高い最適化レベル、あなたは別のジョブラインを最適化するのに十分なレベル限り、プロパティをオーバーライドする場合。
プレースホルダは、それが解決される方法ですか?
分析していき建設時にサブクラスが1を作成し、プレースホルダが完了することによって解決:ConfigFileApplicationListener
Loader
PropertySourcesPlaceholdersResolver
Loader(ConfigurableEnvironment environment, ResourceLoader resourceLoader) {
this.placeholdersResolver = new PropertySourcesPlaceholdersResolver(this.environment);
}
复制代码
PropertySourcesPlaceholdersResolver分析は、実際に構文解析が完了することを発見しPropertyPlaceholderHelper
、それは建設時にPropertySourcesPlaceholdersResolver PropertyPlaceholderHelperを作成し、完全な
public PropertySourcesPlaceholdersResolver(Iterable<PropertySource<?>> sources, PropertyPlaceholderHelper helper) {
this.sources = sources;
this.helper = (helper != null) ? helper : new PropertyPlaceholderHelper(SystemPropertyUtils.PLACEHOLDER_PREFIX,
SystemPropertyUtils.PLACEHOLDER_SUFFIX, SystemPropertyUtils.VALUE_SEPARATOR, true);
}
复制代码
接頭辞、接尾辞、デフォルトの区切り文字は、次の3つの定数によって表される各:PropertySourcesPlaceholdersResolver三個のPropertyPlaceholderHelperを作成パラメータを渡します。
public static final String PLACEHOLDER_PREFIX = "${";
public static final String PLACEHOLDER_SUFFIX = "}";
public static final String VALUE_SEPARATOR = ":";
复制代码
したがってなど解決するために、どのような形式を知ることができるときに解析プレースホルダPropertyPlaceholderHelper:$ {spring.application.name}プレースホルダは、プロパティ値に解析されるであろう。
概要
SpringBoot構成は非常に柔軟であり、SpringBootを介して、等ファイル、環境変数、JVMシステムプロパティ、流通センター、から構成されることができるPropertySource
とPropertySources
特性の優先順位実装、CRUD一元管理、開発者のための統一された構成の抽象化を提供します。