SpringBootは、設定ファイルをロードする方法ですか?

オリジナル:Javaのキャンプ(マイクロチャンネル公共数:ジャワ派)が、共有してください、ソースを保管してください再現。

序文

本稿バージョンで2.2.0.RELEASEこのようなSpringBootソースを見てのようないくつかの一般的な問題を把握するSpringBoot設定処理のソースコードを分析します。

  1. SpringBootどこコンフィギュレーション・ファイルのロードを開始するには?
  2. どの場所からコンフィギュレーション・ファイルをロードSpringBoot?
  3. どのようにSpringBootサポートyamlおよびpropertiesプロファイルのタイプ?
  4. サポートしたい場合jsonの設定を、あなたは何をすべきでしょうか?
  5. SpringBoot構成の最適化レベルはどのようにのようなものでしょうか?
  6. プレースホルダは、それが解決される方法ですか?

私たちの問題に答えを見つけるために、構成関連のソースコードを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.factoriesEventPublishingRunListenerクラスを持つファイルを、このようなイベントの役割は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;
}
复制代码

これは次のように手順:

  1. チェックしspring.config.location、その値が直接使用されている場合、プロパティ
  2. 以下からのspring.config.additional-location検索パスにプロパティを取得
  3. 検索コレクションのデフォルトの検索パス

ここでは、2例の検索パスSpringBoot構成を決定することができます構成されている場合spring.config.location、直接、そうでない場合は使用spring.config.additional-locationプロパティ値+デフォルトの検索パスを。

どのようにSpringBootサポートyamlおよびpropertiesプロファイルのタイプ?

SpringBoot設定サポートpropertiesyamlファイル、SpringBoot分析していき、これら二つの文書にそれを解決するためにどのようにConfigFileApplicationListenerこのカテゴリを、と呼ばれるサブカテゴリーがあるLoader負荷プロファイルの主な仕事は、これらの商品の責任であるが、直接読み込むpropertiesyamlとに変換する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

知っている名前を参照してください責任があるであるpropertiesyaml友人。

サポートしたい場合jsonの設定を、あなたは何をすべきでしょうか?

あなたが好きではない場合propertiesyamlの両方の形式は、定義したい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を作成し、プレースホルダが完了することによって解決:ConfigFileApplicationListenerLoaderPropertySourcesPlaceholdersResolver

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システムプロパティ、流通センター、から構成されることができるPropertySourcePropertySources特性の優先順位実装、CRUD一元管理、開発者のための統一された構成の抽象化を提供します。

おすすめ

転載: juejin.im/post/5dbcec0e6fb9a020433f643b
おすすめ