javascript
Springboot漫游日志(18)
Springboot漫游日志(18)
- StandardServletEnvironment
- StandardEnvironment
- AbstractEnvironment
- customizePropertySources方法
先不繼續,梳理一下遺漏。
StandardServletEnvironment
這個類是在【SpringApplication】457行。
new StandardServletEnvironment();在貼一波繼承關系。
靜態屬性
/** 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";構造方法為無參構造。
接著看父類。
StandardEnvironment
靜態屬性
/** 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";接著往上看,父類。
AbstractEnvironment
靜態屬性
/*** System property that instructs Spring to ignore system environment variables,* i.e. to never attempt to retrieve such a variable via {@link System#getenv()}.* <p>The default is "false", falling back to system environment variable checks if a* Spring environment property (e.g. a placeholder in a configuration String) isn't* resolvable otherwise. Consider switching this flag to "true" if you experience* log warnings from {@code getenv} calls coming from Spring, e.g. on WebSphere* with strict SecurityManager settings and AccessControlExceptions warnings.* @see #suppressGetenvAccess()*/ public static final String IGNORE_GETENV_PROPERTY_NAME = "spring.getenv.ignore";/*** Name of property to set to specify active profiles: {@value}. Value may be comma* delimited.* <p>Note that certain shell environments such as Bash disallow the use of the period* character in variable names. Assuming that Spring's {@link SystemEnvironmentPropertySource}* is in use, this property may be specified as an environment variable as* {@code SPRING_PROFILES_ACTIVE}.* @see ConfigurableEnvironment#setActiveProfiles*/ public static final String ACTIVE_PROFILES_PROPERTY_NAME = "spring.profiles.active";/*** Name of property to set to specify profiles active by default: {@value}. Value may* be comma delimited.* <p>Note that certain shell environments such as Bash disallow the use of the period* character in variable names. Assuming that Spring's {@link SystemEnvironmentPropertySource}* is in use, this property may be specified as an environment variable as* {@code SPRING_PROFILES_DEFAULT}.* @see ConfigurableEnvironment#setDefaultProfiles*/ public static final String DEFAULT_PROFILES_PROPERTY_NAME = "spring.profiles.default";/*** Name of reserved default profile name: {@value}. If no default profile names are* explicitly and no active profile names are explicitly set, this profile will* automatically be activated by default.* @see #getReservedDefaultProfiles* @see ConfigurableEnvironment#setDefaultProfiles* @see ConfigurableEnvironment#setActiveProfiles* @see AbstractEnvironment#DEFAULT_PROFILES_PROPERTY_NAME* @see AbstractEnvironment#ACTIVE_PROFILES_PROPERTY_NAME*/ protected static final String RESERVED_DEFAULT_PROFILE_NAME = "default";實例屬性
protected final Log logger = LogFactory.getLog(getClass());private final Set<String> activeProfiles = new LinkedHashSet<>();private final Set<String> defaultProfiles = new LinkedHashSet<>(getReservedDefaultProfiles());private final MutablePropertySources propertySources = new MutablePropertySources();private final ConfigurablePropertyResolver propertyResolver =new PropertySourcesPropertyResolver(this.propertySources);構造方法及相關方法
/*** Create a new {@code Environment} instance, calling back to* {@link #customizePropertySources(MutablePropertySources)} during construction to* allow subclasses to contribute or manipulate {@link PropertySource} instances as* appropriate.* @see #customizePropertySources(MutablePropertySources)*/ public AbstractEnvironment() {customizePropertySources(this.propertySources); } /*** Customize the set of {@link PropertySource} objects to be searched by this* {@code Environment} during calls to {@link #getProperty(String)} and related* methods.** <p>Subclasses that override this method are encouraged to add property* sources using {@link MutablePropertySources#addLast(PropertySource)} such that* further subclasses may call {@code super.customizePropertySources()} with* predictable results. For example:* <pre class="code">* public class Level1Environment extends AbstractEnvironment {* @Override* protected void customizePropertySources(MutablePropertySources propertySources) {* super.customizePropertySources(propertySources); // no-op from base class* propertySources.addLast(new PropertySourceA(...));* propertySources.addLast(new PropertySourceB(...));* }* }** public class Level2Environment extends Level1Environment {* @Override* protected void customizePropertySources(MutablePropertySources propertySources) {* super.customizePropertySources(propertySources); // add all from superclass* propertySources.addLast(new PropertySourceC(...));* propertySources.addLast(new PropertySourceD(...));* }* }* </pre>* In this arrangement, properties will be resolved against sources A, B, C, D in that* order. That is to say that property source "A" has precedence over property source* "D". If the {@code Level2Environment} subclass wished to give property sources C* and D higher precedence than A and B, it could simply call* {@code super.customizePropertySources} after, rather than before adding its own:* <pre class="code">* public class Level2Environment extends Level1Environment {* @Override* protected void customizePropertySources(MutablePropertySources propertySources) {* propertySources.addLast(new PropertySourceC(...));* propertySources.addLast(new PropertySourceD(...));* super.customizePropertySources(propertySources); // add all from superclass* }* }* </pre>* The search order is now C, D, A, B as desired.** <p>Beyond these recommendations, subclasses may use any of the {@code add*},* {@code remove}, or {@code replace} methods exposed by {@link MutablePropertySources}* in order to create the exact arrangement of property sources desired.** <p>The base implementation registers no property sources.** <p>Note that clients of any {@link ConfigurableEnvironment} may further customize* property sources via the {@link #getPropertySources()} accessor, typically within* an {@link org.springframework.context.ApplicationContextInitializer* ApplicationContextInitializer}. For example:* <pre class="code">* ConfigurableEnvironment env = new StandardEnvironment();* env.getPropertySources().addLast(new PropertySourceX(...));* </pre>** <h2>A warning about instance variable access</h2>* Instance variables declared in subclasses and having default initial values should* <em>not</em> be accessed from within this method. Due to Java object creation* lifecycle constraints, any initial value will not yet be assigned when this* callback is invoked by the {@link #AbstractEnvironment()} constructor, which may* lead to a {@code NullPointerException} or other problems. If you need to access* default values of instance variables, leave this method as a no-op and perform* property source manipulation and instance variable access directly within the* subclass constructor. Note that <em>assigning</em> values to instance variables is* not problematic; it is only attempting to read default values that must be avoided.** @see MutablePropertySources* @see PropertySourcesPropertyResolver* @see org.springframework.context.ApplicationContextInitializer*/ protected void customizePropertySources(MutablePropertySources propertySources) { } /*** Return the set of reserved default profile names. This implementation returns* {@value #RESERVED_DEFAULT_PROFILE_NAME}. Subclasses may override in order to* customize the set of reserved names.* @see #RESERVED_DEFAULT_PROFILE_NAME* @see #doGetDefaultProfiles()*/ protected Set<String> getReservedDefaultProfiles() {return Collections.singleton(RESERVED_DEFAULT_PROFILE_NAME); }【customizePropertySources】方法,注釋很長,實現為空。
所以根據多態,這里調用【StandardServletEnvironment】的【customizePropertySources】方法。
先看看屬性【propertySources 】【propertyResolver 】
又是兩個類,看一眼。
PropertySourcesPropertyResolver有父類【AbstractPropertyResolver】
有一些實例屬性。
里面涉及到一個類【SystemPropertyUtils】使用了靜態屬性,看看。
/** Prefix for system property placeholders: "${". */ public static final String PLACEHOLDER_PREFIX = "${";/** Suffix for system property placeholders: "}". */ public static final String PLACEHOLDER_SUFFIX = "}";/** Value separator for system property placeholders: ":". */ public static final String VALUE_SEPARATOR = ":";private static final PropertyPlaceholderHelper strictHelper =new PropertyPlaceholderHelper(PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, VALUE_SEPARATOR, false);private static final PropertyPlaceholderHelper nonStrictHelper =new PropertyPlaceholderHelper(PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, VALUE_SEPARATOR, true);有五個靜態屬性,這時候都是要執行的。
【PropertyPlaceholderHelper】這個類,看看。
一點點退回去。
【AbstractEnvironment】持有一個【propertySources】和【propertyResolver】
【PropertySourcesPropertyResolver】持有一個【propertySources】,和【AbstractEnvironment】的
【propertySources】指向同一個對象。
customizePropertySources方法
/*** Customize the set of property sources with those contributed by superclasses as* well as those appropriate for standard servlet-based environments:* <ul>* <li>{@value #SERVLET_CONFIG_PROPERTY_SOURCE_NAME}* <li>{@value #SERVLET_CONTEXT_PROPERTY_SOURCE_NAME}* <li>{@value #JNDI_PROPERTY_SOURCE_NAME}* </ul>* <p>Properties present in {@value #SERVLET_CONFIG_PROPERTY_SOURCE_NAME} will* take precedence over those in {@value #SERVLET_CONTEXT_PROPERTY_SOURCE_NAME}, and* properties found in either of the above take precedence over those found in* {@value #JNDI_PROPERTY_SOURCE_NAME}.* <p>Properties in any of the above will take precedence over system properties and* environment variables contributed by the {@link StandardEnvironment} superclass.* <p>The {@code Servlet}-related property sources are added as* {@link StubPropertySource stubs} at this stage, and will be* {@linkplain #initPropertySources(ServletContext, ServletConfig) fully initialized}* once the actual {@link ServletContext} object becomes available.* @see StandardEnvironment#customizePropertySources* @see org.springframework.core.env.AbstractEnvironment#customizePropertySources* @see ServletConfigPropertySource* @see ServletContextPropertySource* @see org.springframework.jndi.JndiPropertySource* @see org.springframework.context.support.AbstractApplicationContext#initPropertySources* @see #initPropertySources(ServletContext, ServletConfig)*/ @Override protected 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); } private final List<PropertySource<?>> propertySourceList = new CopyOnWriteArrayList<>(); /*** Add the given property source object with lowest precedence.*/ public void addLast(PropertySource<?> propertySource) {synchronized (this.propertySourceList) {removeIfPresent(propertySource);this.propertySourceList.add(propertySource);} }給【propertySources】的屬性【propertySourceList 】添加四個元素。
分別是:
- new StubPropertySource(SERVLET_CONFIG_PROPERTY_SOURCE_NAME)
- new StubPropertySource(SERVLET_CONTEXT_PROPERTY_SOURCE_NAME)
- new PropertiesPropertySource(SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, getSystemProperties())
- new SystemEnvironmentPropertySource(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, getSystemEnvironment())
四個元素的name分別是:
- servletConfigInitParams
- servletContextInitParams
- systemProperties
- systemEnvironment
前兩個值都是new Object()
后面兩個都是有值的。
【systemProperties】是虛擬機系統屬性。
【systemEnvironment】是系統環境屬性。
通過【systemProperties】往下找,找到:
注釋上面已經給的很清楚了。
拉出來做成html,再用古哥翻譯一下。
再順著【systemEnvironment】找一波。
@Override @SuppressWarnings({"rawtypes", "unchecked"}) public Map<String, Object> getSystemEnvironment() {if (suppressGetenvAccess()) {return Collections.emptyMap();}try {return (Map) System.getenv();}catch (AccessControlException ex) {return (Map) new ReadOnlySystemAttributesMap() {@Override@Nullableprotected String getSystemAttribute(String attributeName) {try {return System.getenv(attributeName);}catch (AccessControlException ex) {if (logger.isInfoEnabled()) {logger.info("Caught AccessControlException when accessing system environment variable '" +attributeName + "'; its value will be returned [null]. Reason: " + ex.getMessage());}return null;}}};} } /*** Returns an unmodifiable string map view of the current system environment.* The environment is a system-dependent mapping from names to* values which is passed from parent to child processes.** <p>If the system does not support environment variables, an* empty map is returned.** <p>The returned map will never contain null keys or values.* Attempting to query the presence of a null key or value will* throw a {@link NullPointerException}. Attempting to query* the presence of a key or value which is not of type* {@link String} will throw a {@link ClassCastException}.** <p>The returned map and its collection views may not obey the* general contract of the {@link Object#equals} and* {@link Object#hashCode} methods.** <p>The returned map is typically case-sensitive on all platforms.** <p>If a security manager exists, its* {@link SecurityManager#checkPermission checkPermission}* method is called with a* <code>{@link RuntimePermission}("getenv.*")</code>* permission. This may result in a {@link SecurityException} being* thrown.** <p>When passing information to a Java subprocess,* <a href=#EnvironmentVSSystemProperties>system properties</a>* are generally preferred over environment variables.** @return the environment as a map of variable names to values* @throws SecurityException* if a security manager exists and its* {@link SecurityManager#checkPermission checkPermission}* method doesn't allow access to the process environment* @see #getenv(String)* @see ProcessBuilder#environment()* @since 1.5*/public static java.util.Map<String,String> getenv() {SecurityManager sm = getSecurityManager();if (sm != null) {sm.checkPermission(new RuntimePermission("getenv.*"));}return ProcessEnvironment.getenv();}注釋顯示,返回結果里面部會有空key或者空value,也不會有非String類型的鍵和值。
在所有平臺都是大小寫敏感的,也就是區分大小寫。
如果有安全管理器,就會檢查一下權限,可能會拋出一個安全異常。
將信息傳遞給Java子進程時,通常優先于環境變量使用系統屬性
這里大了一個斷點,看到環境屬性還是不少的。這里不貼了。
最后,【AbstractEnvironment】的屬性【propertySources】的屬性【propertySourceList】擁有四個元素。
到目前還未加載【applicationcontext.properties】里面的數據。
總結
以上是生活随笔為你收集整理的Springboot漫游日志(18)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Qt 摄像头
- 下一篇: 2.SpringBoot整合Mybati