環境Springboot理解するには、次の質問からこの記事:
環境とは何ですか?
簡単な紹介
環境はspring3.1からインターフェースはSpringアプリケーションが現在実行環境を表し、提供を開始しましたです。環境は、主に二つのもので構成されています。
1、プロファイル
中国の直訳は「概要」、「はじめに」、「輪郭」である等の平均、マルチ環境の部門で、より関連性のプロファイルの私達の印象プロフィール、私たちは多くの場合、分割する必要があります:開発、テスト、生産前、生産環境。それぞれの環境には、すべての異なるBeanを持って、異なる構成、異なるコンフィギュレーションファイルをロードすることがあります。その後、我々は、プロファイルに応じて、負荷に異なるプロファイル、対応するBean、またはコンフィギュレーションファイルを定義することができます。これが意味を説明したjavadocの春に「論理グループ」です。
上記の異なる環境に分け例としては、基本的に我々は唯一のプロファイルがアクティブであることを確認しますが、これは環境が唯一のプロファイルとして存在することができるという意味ではありません、それは我々が同時に複数のプロファイルを設定することができることを意味し、コレクション、負荷であります複数の豆プロファイルとプロファイル。
図2に示すように、特性
Javaのプロパティで、我々はより精通しているプロパティの概念は、オブジェクトの形でキーと値を表します。また、キーと値の形で設計環境内のプロパティに対応するオブジェクトキーを格納するために使用されます。
要約すると、環境は、さらに、メモリ属性のプロパティキーと値のペアを含む、適切なスイッチング環境プロファイルを含みます。
コアUMLクラス図
関連するインタフェースと実装クラスを見て環境によって、私たちに関連する次のクラス図
環境春の継承インターフェイスは比較的簡単ですが、私たちは環境インタフェース、トップダウンの外観から開始します
1)環境インタフェースはPropertyResolverから継承し、PropertyResolverは、getPropertyメソッドなどの特性に関連する操作の数、(文字列キー)を含みます。だから、プロパティ設計環境関連の責任の春には、インターフェースの中でPropertyResolverにデカップリングされています。
2)環境インタフェースはsetActiveProfiles(文字列...プロファイル)として、環境のいくつかのセット動作を含み、ConfigurableEnvironmentインタフェースは下方に延びています。あなたは環境プログラムで試してみたくないときに推定春になるゲッターとセッター界面剥離は、実行されている予測不可能なバグを生成するために誤用されるのを避けるために、開発者セッター操作にさらされます。
3)ダウンConfigurableEnvironment AbstractEnvironment抽象クラス、コアコンテンツに関連するプロファイルとプロパティに含まれている抽象クラスを実装しています。
4)AbstractEnvironment底まで、それは反応のためのアプリケーションに関連し、それぞれ、StandardReactiveWebEnvironmentとStandardServletEnvironmentあり、サーブレットウェブを実装します。
環境は、ときに作成されましたか?
mainメソッドの最初から開始し、その後、mainメソッドでのようなコアプロセスを実行しSpringApplicationのrunメソッドが環境に作成されます呼び出しますSpringboot
私たちは、その名の通り、prepareEnvironmentを参照して、Environmentオブジェクトを作成します。
prepareEnvironmentでそのようにgetOrCreateEnvironmentメソッドを呼び出します
この方法は、タイプまたは環境反応性または非Webアプリケーションに対応するgetOrCreateEnvironmentサーブレットコンテナのタイプを選択します。
内部数据存储结构是怎么样的?
前面,我们提到AbstractEnvironment包含了Environment的核心实现。
profile结构
我们先看看profile相关的存储结构,如:
profile的存储结构很简单,就是两个Set集合,每个profile是一个String类型的字符串。
我们注意到除了active的profile有一个集合,还有一个default的profile集合,这就意味着如果没有设置active的profile将会试用default的profile。而default的profile集合通过getReservedDefaultProfiles方法初始化。我们看看该方法
这个方法就是返回一个包含"default"字符串的String集合。所以,默认的profile就是default。
properties结构
我们再看看properties的存储结构,如图
properties不是直接使用Set<Properties>这样的集合,而是被一个MutablePropertySources对象给包装起来了(mutable是可改变的意思)。我们看看MutablePropertySources对象。
最上层的Iterable接口表明了MutablePropertySources是像集合一样可以迭代的,所以我们也可以大胆猜测MutablePropertySources存储的key-value其实就是一个List集合。
往下,PropertySources接口指明MutablePropertySources可以执行属性的相关操作,我们打开PropertySources接口看看
我们看到PropertySources继承Iterable的时候置顶了被迭代元素的类型是PropertySource。也就是说MutablePropertySources存储的key-value结构就是由PropertySource来实现的。
我们看看PropertySource的实现
PropertySource是一个abstract指定的抽象类,包含了一个name,然后指定了一个泛型的数据结构。
这里要注意区分一点,这里的name并不是单独一个属性的key,而是多个key-value的集合名称。举个例子:
你创建了一个file.properties文件,其中包含了key-value,如
url=http://localhost:8080/index.html token=test123445
PropertySource中的name指的是file.properties的"file",而不是文件中的url或者token。
PropertySource是一个抽象类,spring将会根据properties的不同来源做不同的实现类。如上面的例子中的file.properties文件被你手动加载到内存中成为Properties的java对象,而这个Properties对象被追加到MutablePropertySources中以后将会作为PropertySource的实现PropertiesPropertySource存在。
PropertiesPropertySource将指定PropertySource的泛型T为Map<String, Object>,也就符合我们上面说的file.properties文件的file作为name,其内部的url和password作为Map中的key。
除了PropertiesPropertySource,PropertySource还有很多其它的实现,如下所示:
上图显示了PropertySource的所有实现,如:来自命令行的属性 -> CommandLinePropertySource、来自Servlet的 -> ServletConfigPropertySource和ServletContextPropertySource等等。
总之,Environment中相关的properties将会有不同的来源,但是最终都会汇聚到Environment这个抽象当中,作为开发者的你只需要面对Environment即可。
可以执行哪些API操作?
上面我们大体了解了spring中的Environment,下面我们再了解一下Environment有哪些相关Api操作。
PropertiesAPI
Properties相关的操作被分离到PropertyResolver接口和ConfigurablePropertyResolver接口,如:
PropertyResolver
public interface PropertyResolver { @Nullable String getProperty(String key); // 获取属性值 String getProperty(String key, String defaultValue); // 获取属性值,并指定默认值 @Nullable <T> T getProperty(String key, Class<T> targetType); // 获取指定属性值,并做类型转换 <T> T getProperty(String key, Class<T> targetType, T defaultValue); // 获取指定属性值,并指定默认值,并做类型转换 String getRequiredProperty(String key) throws IllegalStateException; // 获取必须存在的属性值,没有则抛出非法异常 <T> T getRequiredProperty(String key, Class<T> targetType) throws IllegalStateException; // 获取必须存在的属性值,没有则抛出非法异常 String resolvePlaceholders(String text); // 解析文本中包含的${key}占位符 String resolveRequiredPlaceholders(String text) throws IllegalArgumentException; // 解析文本中包含的${key}占位符,没有则抛出非法异常 }
ConfigurablePropertyResolver
public interface ConfigurablePropertyResolver extends PropertyResolver { ConfigurableConversionService getConversionService(); // 获取类型转换器 void setConversionService(ConfigurableConversionService conversionService); // 设置类型转换器 void setPlaceholderPrefix(String placeholderPrefix); // 设置占位符前缀 void setPlaceholderSuffix(String placeholderSuffix); // 设置占位符后缀 void setValueSeparator(@Nullable String valueSeparator); // 设置值的分隔符 void setIgnoreUnresolvableNestedPlaceholders(boolean ignoreUnresolvableNestedPlaceholders); // 设置是否忽略嵌套占位符的异常 void setRequiredProperties(String... requiredProperties); // 设置必须存在的属性 void validateRequiredProperties() throws MissingRequiredPropertiesException; // 校验必须存在的属性,否则抛出丢失异常 }
ProfileAPI
Profile相关的操作保留再Environment接口和ConfigurableEnvironment接口当中,如
Environment
public interface Environment extends PropertyResolver { String[] getActiveProfiles(); // 获取所有active的profile String[] getDefaultProfiles(); // 获取所有默认的profile @Deprecated boolean acceptsProfiles(String... profiles); // 指定profile是否active boolean acceptsProfiles(Profiles profiles); // 指定profile是否active }
ConfigurableEnvironment
public interface ConfigurableEnvironment extends Environment, ConfigurablePropertyResolver { void setActiveProfiles(String... profiles); // 设置active的profile void addActiveProfile(String profile); // 添加active的profile void setDefaultProfiles(String... profiles); // 设置默认的profile MutablePropertySources getPropertySources(); // 获取所有PropertySource Map<String, Object> getSystemProperties(); // 获取systemProperties的所有属性值 Map<String, Object> getSystemEnvironment(); // 获取systemEnvironment的所有属性值 void merge(ConfigurableEnvironment parent); // 合并Environment的值 }
其它API
public interface EnvironmentAware extends Aware { void setEnvironment(Environment environment); // 获取当前spring的Environment }
总结
spring将应用程序中的属性资源进行抽象整合,程序开发人员只需要面对Environment这个抽象,而无需关心具体资源以及资源来源的问题。
Environment包含了profile和properties两个概念,profile主要用来划分不同环境,properties用于存储key-value的属性值关系。properties的实现采用PropertySource抽象类,根据不同来源做不同的实现类。同时Environment将properties的操作给分离给了PropertyResolver,并且把getter操作和setter操作进行了分离,由此一定程序保护了Environment的安全。