日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring Environment

發布時間:2024/4/13 javascript 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring Environment 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Environment是當前應用運行環境的公開接口,主要包括應用程序運行環境的兩個關鍵方面:配置文件(profiles)和屬性(properties)。

  • profiles:

profile配置是一個被命名的、bean定義的邏輯組,這些bean只有在給定的profile配置激活時才會注冊到容器

  • properties:

properties屬性可能來源于properties文件、JVM properties、system環境變量、JNDI、servlet context parameters上下文參數、專門的properties對象,Maps等等.

?

類圖

源碼解析

PropertyResolver

PropertyResolver提供屬性訪問功能,并能夠解析占位符屬性(${...})。

public interface PropertyResolver {boolean containsProperty(String key);@NullableString 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);String resolveRequiredPlaceholders(String text) throws IllegalArgumentException; }

ConfigurablePropertyResolver

ConfigurablePropertyResolver,繼承自PropertyResolver,主要提供屬性類型轉換(基于org.springframework.core.convert.ConversionService)功能。

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; }


Environment

Environment繼承自PropertyResolver,提供訪問和判斷profiles的功能。

public interface Environment extends PropertyResolver {String[] getActiveProfiles();String[] getDefaultProfiles();@Deprecatedboolean acceptsProfiles(String... profiles);//判斷profiles是否被激活boolean acceptsProfiles(Profiles profiles); }

ConfigurableEnvironment

ConfigurableEnvironment繼承自ConfigurablePropertyResolver和Environment,提供設置激活的profile和默認的profile的功能以及合并profiles,

public interface ConfigurableEnvironment extends Environment, ConfigurablePropertyResolver {void setActiveProfiles(String... profiles);void addActiveProfile(String profile);void setDefaultProfiles(String... profiles);MutablePropertySources getPropertySources();//返回System#getProperties()的值,應用了SecurityManagerMap<String, Object> getSystemProperties();//返回System#getenv()的值,應用了SecurityManagerMap<String, Object> getSystemEnvironment();void merge(ConfigurableEnvironment parent);}

ConfigurableWebEnvironment

ConfigurableWebEnvironment繼承自ConfigurableEnvironment,并且提供配置Servlet上下文Servlet參數的功能。

public interface ConfigurableWebEnvironment extends ConfigurableEnvironment {void initPropertySources(@Nullable ServletContext servletContext, @Nullable ServletConfig servletConfig); }

ConfigurableReactiveWebEnvironment

專為reactive項目制定的ConfigurableEnvironment

public interface ConfigurableReactiveWebEnvironment extends ConfigurableEnvironment {}

AbstractPropertyResolver

AbstractPropertyResolver是ConfigurablePropertyResolver接口的抽象實現類,提供了大部分接口方法的默認實現,將核心的getProperty(String key, Class<T> targetType)方法留給子類實現,resolvePlaceholders(String text)方法則由PropertyPlaceholderHelper提供默認實現。

屬性

//轉換服務@Nullableprivate volatile ConfigurableConversionService conversionService;@Nullableprivate PropertyPlaceholderHelper nonStrictHelper;@Nullableprivate PropertyPlaceholderHelper strictHelper;private boolean ignoreUnresolvableNestedPlaceholders = false;//占位符前綴,默認:"${"private String placeholderPrefix = SystemPropertyUtils.PLACEHOLDER_PREFIX;//占位符后綴,默認:"}"private String placeholderSuffix = SystemPropertyUtils.PLACEHOLDER_SUFFIX;//默認值分隔符,默認:":"@Nullableprivate String valueSeparator = SystemPropertyUtils.VALUE_SEPARATOR;//必需屬性private final Set<String> requiredProperties = new LinkedHashSet<>();

conversionService

轉換服務是轉換器(Converter)的容器(ConverterRegistry)。

public interface ConverterRegistry {void addConverter(Converter<?, ?> converter);<S, T> void addConverter(Class<S> sourceType, Class<T> targetType, Converter<? super S, ? extends T> converter);void addConverter(GenericConverter converter);void addConverterFactory(ConverterFactory<?, ?> factory);void removeConvertible(Class<?> sourceType, Class<?> targetType); }

如果沒有設置,默認使用:DefaultConversionService

解析占位符

private String doResolvePlaceholders(String text, PropertyPlaceholderHelper helper) {return helper.replacePlaceholders(text, this::getPropertyAsRawString);}

獲取原始值,再替換占位符。?

PropertyPlaceholderHelper

public String replacePlaceholders(String value, PlaceholderResolver placeholderResolver) {Assert.notNull(value, "'value' must not be null");return parseStringValue(value, placeholderResolver, null);}

parseStringValue遞歸解析占位符。遇到${開頭就會查找最后一個}符號,將最外層占位符內的內容作為新的value再次傳入 parseStringValue()方法中,這樣最深層次也就是最先返回的就是最里層的占位符名字。調用placeholderResolver將占位符名字轉換成它代表的值。如果值為null,則考慮使用默認值(valueSeparator后的內容)賦值給propVal。由于placeholderResolver轉換過的值有可能還會包含占位符所以在此調用parseStringValue()方法將帶有占位符的propVal傳入返回真正的值,用propVal替換占位符。如果propVal==null,判斷是否允許忽略不能解析的占位符,如果可以重置startIndex繼續解析同一層次的占位符。否則拋出異常。這個函數的返回值就是它上一層次的占位符解析值。

需要注意的一點是:判斷嵌套的占位符是依據simplePrefix。

PropertySourcesPropertyResolver

PropertySourcesPropertyResolver是體系中唯一的完整實現類。它以PropertySources屬性源集合(內部持有屬性源列表List<PropertySource>)為屬性值的來源,按序遍歷每個PropertySource,獲取到一個非null的屬性值則返回。

protected <T> T getProperty(String key, Class<T> targetValueType, boolean resolveNestedPlaceholders) {if (this.propertySources != null) {for (PropertySource<?> propertySource : this.propertySources) { ......Object value = propertySource.getProperty(key);if (value != null) {if (resolveNestedPlaceholders && value instanceof String) {value = resolveNestedPlaceholders((String) value);}logKeyFound(key, propertySource, value);return convertValueIfNecessary(value, targetValueType);}}}return null;}protected String getPropertyAsRawString(String key) {return getProperty(key, String.class, false);}

AbstractEnvironment

屬性

//是否忽略系統環境(System#getenv())的屬性名稱public static final String IGNORE_GETENV_PROPERTY_NAME = "spring.getenv.ignore";//激活的profiles的屬性名稱(屬性值以逗號分隔)public static final String ACTIVE_PROFILES_PROPERTY_NAME = "spring.profiles.active";//激活的profiles的屬性名稱(屬性值以逗號分隔)public static final String DEFAULT_PROFILES_PROPERTY_NAME = "spring.profiles.default";//默認profile的名稱:defaultprotected static final String RESERVED_DEFAULT_PROFILE_NAME = "default";//激活的profilesprivate final Set<String> activeProfiles = new LinkedHashSet<>();//默認的profilesprivate final Set<String> defaultProfiles = new LinkedHashSet<>(getReservedDefaultProfiles());//propertySourcesprivate final MutablePropertySources propertySources = new MutablePropertySources();private final ConfigurablePropertyResolver propertyResolver =new PropertySourcesPropertyResolver(this.propertySources);

由子類設置PropertySource

protected void customizePropertySources(MutablePropertySources propertySources) {}

獲取profiles

protected Set<String> doGetActiveProfiles() {synchronized (this.activeProfiles) {if (this.activeProfiles.isEmpty()) {String profiles = getProperty(ACTIVE_PROFILES_PROPERTY_NAME);if (StringUtils.hasText(profiles)) {setActiveProfiles(StringUtils.commaDelimitedListToStringArray(StringUtils.trimAllWhitespace(profiles)));}}return this.activeProfiles;}}


StandardEnvironment

StandardEnvironment繼承自AbstractEnvironment,非Servlet(Web)環境下的標準Environment實現。提供系統屬性以及系統環境變量的獲取。

public class StandardEnvironment extends AbstractEnvironment {/** System environment property source name: {@value}. */public static final String SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME = "systemEnvironment";/** JVM system properties property source name: {@value}. */public static final String SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME = "systemProperties";@Overrideprotected void customizePropertySources(MutablePropertySources propertySources) {propertySources.addLast(new PropertiesPropertySource(SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, getSystemProperties()));propertySources.addLast(new SystemEnvironmentPropertySource(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, getSystemEnvironment()));}}


StandardServletEnvironment

StandardServletEnvironment繼承自StandardEnvironment,Servlet(Web)環境下的標準Environment實現。

public class StandardServletEnvironment extends StandardEnvironment implements ConfigurableWebEnvironment {/** Servlet context init parameters property source name: {@value}. */public static final String SERVLET_CONTEXT_PROPERTY_SOURCE_NAME = "servletContextInitParams";/** Servlet config init parameters property source name: {@value}. */public static final String SERVLET_CONFIG_PROPERTY_SOURCE_NAME = "servletConfigInitParams";/** JNDI property source name: {@value}. */public static final String JNDI_PROPERTY_SOURCE_NAME = "jndiProperties";@Overrideprotected void customizePropertySources(MutablePropertySources propertySources) {propertySources.addLast(new StubPropertySource(SERVLET_CONFIG_PROPERTY_SOURCE_NAME));propertySources.addLast(new StubPropertySource(SERVLET_CONTEXT_PROPERTY_SOURCE_NAME));if (JndiLocatorDelegate.isDefaultJndiEnvironmentAvailable()) {propertySources.addLast(new JndiPropertySource(JNDI_PROPERTY_SOURCE_NAME));}super.customizePropertySources(propertySources);}@Overridepublic void initPropertySources(@Nullable ServletContext servletContext, @Nullable ServletConfig servletConfig) {WebApplicationContextUtils.initServletPropertySources(getPropertySources(), servletContext, servletConfig);}}

StandardReactiveWebEnvironment

用于reactive web 應用。

public class StandardReactiveWebEnvironment extends StandardEnvironment implements ConfigurableReactiveWebEnvironment {}

MutablePropertySources

提供PropertySource的容器。內部存儲為CopyOnWriteArrayList

PropertySource

PropertySource 類 設計用來存放<key,value>對象的抽象類。同時name,source都是final在初始化后不在變化。

PropertySource的最常用子類是MapPropertySource、PropertiesPropertySource、ResourcePropertySource、StubPropertySource、ComparisonPropertySource:

  • MapPropertySource:source指定為Map實例的PropertySource實現。
  • PropertiesPropertySource:source指定為Map實例的PropertySource實現,內部的Map實例由Properties實例轉換而來。
  • ResourcePropertySource:繼承自PropertiesPropertySource,source指定為通過Resource實例轉化為Properties再轉換為Map實例。
  • StubPropertySource:PropertySource的一個內部類,source設置為null,實際上就是空實現。
  • ComparisonPropertySource:所有屬性訪問方法強制拋出異常,作用就是一個不可訪問屬性的空實現。
public abstract class PropertySource<T> {protected final String name;protected final T source;public boolean equals(@Nullable Object other) {return (this == other || (other instanceof PropertySource &&ObjectUtils.nullSafeEquals(this.name, ((PropertySource<?>) other).name)));}public int hashCode() {return ObjectUtils.nullSafeHashCode(this.name);} }

SpringBoot啟動

在Spring boot 啟動時,會準備環境Environment,在Environment準備好之后,會廣播一個ApplicationEnvironmentPreparedEvent:調用各listener的environmentPrepared(ConfigurableEnvironment environment)方法,

listeners.environmentPrepared(environment);void environmentPrepared(ConfigurableEnvironment environment) {for (SpringApplicationRunListener listener : this.listeners) {listener.environmentPrepared(environment);}}@Overridepublic void environmentPrepared(ConfigurableEnvironment environment) {this.initialMulticaster.multicastEvent(new ApplicationEnvironmentPreparedEvent(this.application, this.args, environment));}

此時獲取到的事件監聽器包括:ConfigFileApplicationListener

public void onApplicationEvent(ApplicationEvent event) {if (event instanceof ApplicationEnvironmentPreparedEvent) {onApplicationEnvironmentPreparedEvent((ApplicationEnvironmentPreparedEvent) event);}if (event instanceof ApplicationPreparedEvent) {onApplicationPreparedEvent(event);}}private void onApplicationEnvironmentPreparedEvent(ApplicationEnvironmentPreparedEvent event) {List<EnvironmentPostProcessor> postProcessors = loadPostProcessors();postProcessors.add(this);AnnotationAwareOrderComparator.sort(postProcessors);for (EnvironmentPostProcessor postProcessor : postProcessors) {postProcessor.postProcessEnvironment(event.getEnvironment(), event.getSpringApplication());}}List<EnvironmentPostProcessor> loadPostProcessors() {return SpringFactoriesLoader.loadFactories(EnvironmentPostProcessor.class, getClass().getClassLoader());}

在onApplicationEnvironmentPreparedEvent()方法中,會處理EnvironmentPostProcessor,默認4個:

# Environment Post Processors org.springframework.boot.env.EnvironmentPostProcessor=\ org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,\ org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor,\ org.springframework.boot.env.SystemEnvironmentPropertySourceEnvironmentPostProcessor,\ org.springframework.boot.reactor.DebugAgentEnvironmentPostProcessor

同時ConfigFileApplicationListener 繼承EnvironmentPostProcessorpostProcessEnvironment()實現如下:

@Overridepublic void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {addPropertySources(environment, application.getResourceLoader());}protected void addPropertySources(ConfigurableEnvironment environment, ResourceLoader resourceLoader) {RandomValuePropertySource.addToEnvironment(environment);new Loader(environment, resourceLoader).load();}

會使用封裝的Loader加載配置

Loader

Loader類是ConfigFileApplicationListener 的一個內部類,用于加載配置。

屬性

private class Loader {//環境信息private final ConfigurableEnvironment environment;//占位符解析器private final PropertySourcesPlaceholdersResolver placeholdersResolver;//資源加載器//private final ResourceLoader resourceLoader;屬性加載器private final List<PropertySourceLoader> propertySourceLoaders;//profileprivate Deque<Profile> profiles;//處理的profileprivate List<Profile> processedProfiles;private boolean activatedProfiles;//已加載的配置private Map<Profile, MutablePropertySources> loaded;private Map<DocumentsCacheKey, List<Document>> loadDocumentsCache = new HashMap<>(); }

初始化

Loader(ConfigurableEnvironment environment, ResourceLoader resourceLoader) {this.environment = environment;//構造PlaceholdersResolverthis.placeholdersResolver = new PropertySourcesPlaceholdersResolver(this.environment);this.resourceLoader = (resourceLoader != null) ? resourceLoader : new DefaultResourceLoader();//從factories中加載類this.propertySourceLoaders = SpringFactoriesLoader.loadFactories(PropertySourceLoader.class,getClass().getClassLoader());} # PropertySource Loaders org.springframework.boot.env.PropertySourceLoader=\ org.springframework.boot.env.PropertiesPropertySourceLoader,\ org.springframework.boot.env.YamlPropertySourceLoader

?

使用

Properties

properties配置文件

<context:property-placeholder location="classpath:db.properties" />

注解方式

@Configuration @PropertySource("classpath:db.properties") public class TestProperties {@AutowiredEnvironment env;public void getProperty() {environment.getProperty("jdbc.driverClassName");} }

Profiles

配置

<beans profile="test"><context:property-placeholder location="/WEB-INF/test.properties" /> </beans><beans profile="beta"><context:property-placeholder location="/WEB-INF/beta.properties" /> </beans>

激活

  • 代碼指定
ConfigurableEnvironment.setActiveProfiles("test")
  • 配置文件指定
<init-param><param-name>spring.profiles.active</param-name><param-value>beta</param-value> </init-param>
  • 啟動參數指定

JAVA_OPTS="-Dspring.profiles.active=test"

Enviorment

引用

  • Autoware
@Autowired private Environment environment;
  • 實現EnvironmentAware接口

?

?

?

?

總結

以上是生活随笔為你收集整理的Spring Environment的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。