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 】
又是两个类,看一眼。

/*** Create a new {@link MutablePropertySources} object.*/
public MutablePropertySources() {}
@Nullable
private final PropertySources propertySources;/*** Create a new resolver against the given property sources.* @param propertySources the set of {@link PropertySource} objects to use*/
public PropertySourcesPropertyResolver(@Nullable PropertySources propertySources) {this.propertySources = propertySources;
}

PropertySourcesPropertyResolver有父类【AbstractPropertyResolver】
有一些实例属性。

protected final Log logger = LogFactory.getLog(getClass());@Nullable
private volatile ConfigurableConversionService conversionService;@Nullable
private PropertyPlaceholderHelper nonStrictHelper;@Nullable
private PropertyPlaceholderHelper strictHelper;private boolean ignoreUnresolvableNestedPlaceholders = false;private String placeholderPrefix = SystemPropertyUtils.PLACEHOLDER_PREFIX;private String placeholderSuffix = SystemPropertyUtils.PLACEHOLDER_SUFFIX;@Nullable
private String valueSeparator = SystemPropertyUtils.VALUE_SEPARATOR;private final Set<String> requiredProperties = new LinkedHashSet<>();

里面涉及到一个类【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】这个类,看看。

private static final Log logger = LogFactory.getLog(PropertyPlaceholderHelper.class);private static final Map<String, String> wellKnownSimplePrefixes = new HashMap<>(4);static {wellKnownSimplePrefixes.put("}", "{");wellKnownSimplePrefixes.put("]", "[");wellKnownSimplePrefixes.put(")", "(");
}private final String placeholderPrefix;private final String placeholderSuffix;private final String simplePrefix;@Nullable
private final String valueSeparator;private final boolean ignoreUnresolvablePlaceholders;
/*** Creates a new {@code PropertyPlaceholderHelper} that uses the supplied prefix and suffix.* @param placeholderPrefix the prefix that denotes the start of a placeholder* @param placeholderSuffix the suffix that denotes the end of a placeholder* @param valueSeparator the separating character between the placeholder variable* and the associated default value, if any* @param ignoreUnresolvablePlaceholders indicates whether unresolvable placeholders should* be ignored ({@code true}) or cause an exception ({@code false})*/
public PropertyPlaceholderHelper(String placeholderPrefix, String placeholderSuffix,@Nullable String valueSeparator, boolean ignoreUnresolvablePlaceholders) {Assert.notNull(placeholderPrefix, "'placeholderPrefix' must not be null");Assert.notNull(placeholderSuffix, "'placeholderSuffix' must not be null");this.placeholderPrefix = placeholderPrefix;this.placeholderSuffix = placeholderSuffix;String simplePrefixForSuffix = wellKnownSimplePrefixes.get(this.placeholderSuffix);if (simplePrefixForSuffix != null && this.placeholderPrefix.endsWith(simplePrefixForSuffix)) {this.simplePrefix = simplePrefixForSuffix;}else {this.simplePrefix = this.placeholderPrefix;}this.valueSeparator = valueSeparator;this.ignoreUnresolvablePlaceholders = ignoreUnresolvablePlaceholders;
}

一点点退回去。
【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()
后面两个都是有值的。

/** 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";

【systemProperties】是虚拟机系统属性。
【systemEnvironment】是系统环境属性。
通过【systemProperties】往下找,找到:

@Override
@SuppressWarnings({"rawtypes", "unchecked"})
public Map<String, Object> getSystemProperties() {try {return (Map) System.getProperties();}catch (AccessControlException ex) {return (Map) new ReadOnlySystemAttributesMap() {@Override@Nullableprotected String getSystemAttribute(String attributeName) {try {return System.getProperty(attributeName);}catch (AccessControlException ex) {if (logger.isInfoEnabled()) {logger.info("Caught AccessControlException when accessing system property '" +attributeName + "'; its value will be returned [null]. Reason: " + ex.getMessage());}return null;}}};}
}
/*** Determines the current system properties.* <p>* First, if there is a security manager, its* <code>checkPropertiesAccess</code> method is called with no* arguments. This may result in a security exception.* <p>* The current set of system properties for use by the* {@link #getProperty(String)} method is returned as a* <code>Properties</code> object. If there is no current set of* system properties, a set of system properties is first created and* initialized. This set of system properties always includes values* for the following keys:* <table summary="Shows property keys and associated values">* <tr><th>Key</th>*     <th>Description of Associated Value</th></tr>* <tr><td><code>java.version</code></td>*     <td>Java Runtime Environment version</td></tr>* <tr><td><code>java.vendor</code></td>*     <td>Java Runtime Environment vendor</td></tr>* <tr><td><code>java.vendor.url</code></td>*     <td>Java vendor URL</td></tr>* <tr><td><code>java.home</code></td>*     <td>Java installation directory</td></tr>* <tr><td><code>java.vm.specification.version</code></td>*     <td>Java Virtual Machine specification version</td></tr>* <tr><td><code>java.vm.specification.vendor</code></td>*     <td>Java Virtual Machine specification vendor</td></tr>* <tr><td><code>java.vm.specification.name</code></td>*     <td>Java Virtual Machine specification name</td></tr>* <tr><td><code>java.vm.version</code></td>*     <td>Java Virtual Machine implementation version</td></tr>* <tr><td><code>java.vm.vendor</code></td>*     <td>Java Virtual Machine implementation vendor</td></tr>* <tr><td><code>java.vm.name</code></td>*     <td>Java Virtual Machine implementation name</td></tr>* <tr><td><code>java.specification.version</code></td>*     <td>Java Runtime Environment specification  version</td></tr>* <tr><td><code>java.specification.vendor</code></td>*     <td>Java Runtime Environment specification  vendor</td></tr>* <tr><td><code>java.specification.name</code></td>*     <td>Java Runtime Environment specification  name</td></tr>* <tr><td><code>java.class.version</code></td>*     <td>Java class format version number</td></tr>* <tr><td><code>java.class.path</code></td>*     <td>Java class path</td></tr>* <tr><td><code>java.library.path</code></td>*     <td>List of paths to search when loading libraries</td></tr>* <tr><td><code>java.io.tmpdir</code></td>*     <td>Default temp file path</td></tr>* <tr><td><code>java.compiler</code></td>*     <td>Name of JIT compiler to use</td></tr>* <tr><td><code>java.ext.dirs</code></td>*     <td>Path of extension directory or directories*         <b>Deprecated.</b> <i>This property, and the mechanism*            which implements it, may be removed in a future*            release.</i> </td></tr>* <tr><td><code>os.name</code></td>*     <td>Operating system name</td></tr>* <tr><td><code>os.arch</code></td>*     <td>Operating system architecture</td></tr>* <tr><td><code>os.version</code></td>*     <td>Operating system version</td></tr>* <tr><td><code>file.separator</code></td>*     <td>File separator ("/" on UNIX)</td></tr>* <tr><td><code>path.separator</code></td>*     <td>Path separator (":" on UNIX)</td></tr>* <tr><td><code>line.separator</code></td>*     <td>Line separator ("\n" on UNIX)</td></tr>* <tr><td><code>user.name</code></td>*     <td>User's account name</td></tr>* <tr><td><code>user.home</code></td>*     <td>User's home directory</td></tr>* <tr><td><code>user.dir</code></td>*     <td>User's current working directory</td></tr>* </table>* <p>* Multiple paths in a system property value are separated by the path* separator character of the platform.* <p>* Note that even if the security manager does not permit the* <code>getProperties</code> operation, it may choose to permit the* {@link #getProperty(String)} operation.** @return     the system properties* @exception  SecurityException  if a security manager exists and its*             <code>checkPropertiesAccess</code> method doesn't allow access*              to the system properties.* @see        #setProperties* @see        java.lang.SecurityException* @see        java.lang.SecurityManager#checkPropertiesAccess()* @see        java.util.Properties*/public static Properties getProperties() {SecurityManager sm = getSecurityManager();if (sm != null) {sm.checkPropertiesAccess();}return props;}

注释上面已经给的很清楚了。
拉出来做成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)相关推荐

  1. springboot员工日志管理信息系统的设计与开发毕业设计源码201834

    Springboot员工日志管理信息系统 摘  要 传统的纸质办公方式可能会有这样的问题:作为一名管理人员,你可能每天都有许多工作要安排自己或下属去完成,但常常会忘记自己给谁安排了哪些任务,也不知道这 ...

  2. (附源码)springboot员工日志管理信息系统的设计与开发 毕业设计201834

    Springboot员工日志管理信息系统 摘 要 传统的纸质办公方式可能会有这样的问题:作为一名管理人员,你可能每天都有许多工作要安排自己或下属去完成,但常常会忘记自己给谁安排了哪些任务,也不知道这些 ...

  3. 【Springboot】日志

    springBoot日志 1.目前市面上的日志框架: 日志门面 (日志的抽象层):                JCL(Jakarta Commons Logging)                ...

  4. Java开发面试题及答案,SpringBoot统一日志处理原理

    <artifactId>slf4j-api</artifactId> <version>1.7.28</version> ``` 按照slf4j官方的说 ...

  5. SpringBoot之日志

    一.日志框架简介 1.SpringBoot选用日志抽象层SLF4j和日志实现logback(Log4j的升级版). 2.SLF4j使用  2.1SLF4j使用组合  2.2SLF4j使用例子.SLF4 ...

  6. 玩转springboot:日志的使用

    一.SLF4j使用 1.在系统中使用SLF4J 以后开发的时候,日志记录方法的调用,不应该来直接调用日志的实现类,而是调用日志抽象层里面的方法: 给系统里面导入slf4j的jar和 logback的实 ...

  7. SpringBoot的日志管理(输出级别,输出到文件)

    场景 SpringBoot实战项目搭建专栏地址: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/column/info/35688 1.SpringBoot使用默 ...

  8. SpringBoot生成日志文件---logback和log4j

    SpringBoot生成日志文件---logback和log4j 一.logback logback是SpringBoot自带的日志文件,默认会为控制台输出INFO级别的日志,并且不会将日志文件保存. ...

  9. SpringBoot使用日志

    转载自  SpringBoot使用日志 1.选什么日志框架 首先列举一下日志门面和实现 SpringBoot默认选用SLF4J和Logback 日志级别:springboot默认已经帮我们配置好了日志 ...

最新文章

  1. 为什么U-Net在医学图像上表现优越?
  2. cgroup介绍、安装和控制cpu,内存,io示例
  3. 平均获客成本_获客成本创新高,英语流利说(LAIX.US)获客难流利
  4. 转载:缓存 Cache
  5. kubeadm reset后安装遇到的错误:Unable to connect to the server: x509: certificate signed by unknown authority
  6. 网页中文乱码--UTF-8和GB2312互转
  7. Cesium获取经度 ,纬度,高度
  8. android 4.3 模拟器,模拟器上的Android 4.3
  9. C语言网络编程——基础
  10. 配置svn忽略 node_modules等文件
  11. matlab资产组合最优配置,[转载]资产组合有效前沿的解和最优解(MATLAB语言)
  12. 加强自定义菜单 即更换浏览器默认右击菜单栏
  13. 了解如何在Windows中安全删除文件
  14. OSM学习之路(一):OSM介绍
  15. S2-052的POC测试
  16. XTUOJ-1272-Robot
  17. Langevin dynamic 和 Hamiltonian Monte Carlo
  18. Linux超级用户(root)的密码
  19. android支付宝运动修改器,支付宝运动步数修改器下载-无需root刷支付宝运动步数工具下载_飞翔下载...
  20. selenium模拟浏览器解决反监测,获取cookies解决登录问题

热门文章

  1. 周志明jvm第三版笔记-第一部分:第一章 走进java
  2. krait和kryo_各种Java序列化性能比较
  3. STM32F103+RTT从零开始(三)—— S50门禁卡复制
  4. 点击邮件自动弹出发送邮件窗口
  5. 微米纳米机器人 课件_部编版四年级语文下册7 纳米技术就在我们身边ppt课件1(共23张ppt)...
  6. 利用随机森林预测股票大盘涨跌
  7. m.soudashi.cn 地图_搜索引擎网站推广优化有什么技巧?
  8. 计算机开机最快设置,如何让电脑启动速度变快
  9. Excel常用的操作
  10. SQL Server数据库mdf文件中了勒索病毒.FREEMAN。扩展名变为FREEMAN