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 】
又是两个类,看一眼。
/*** 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)相关推荐
- springboot员工日志管理信息系统的设计与开发毕业设计源码201834
Springboot员工日志管理信息系统 摘 要 传统的纸质办公方式可能会有这样的问题:作为一名管理人员,你可能每天都有许多工作要安排自己或下属去完成,但常常会忘记自己给谁安排了哪些任务,也不知道这 ...
- (附源码)springboot员工日志管理信息系统的设计与开发 毕业设计201834
Springboot员工日志管理信息系统 摘 要 传统的纸质办公方式可能会有这样的问题:作为一名管理人员,你可能每天都有许多工作要安排自己或下属去完成,但常常会忘记自己给谁安排了哪些任务,也不知道这些 ...
- 【Springboot】日志
springBoot日志 1.目前市面上的日志框架: 日志门面 (日志的抽象层): JCL(Jakarta Commons Logging) ...
- Java开发面试题及答案,SpringBoot统一日志处理原理
<artifactId>slf4j-api</artifactId> <version>1.7.28</version> ``` 按照slf4j官方的说 ...
- SpringBoot之日志
一.日志框架简介 1.SpringBoot选用日志抽象层SLF4j和日志实现logback(Log4j的升级版). 2.SLF4j使用 2.1SLF4j使用组合 2.2SLF4j使用例子.SLF4 ...
- 玩转springboot:日志的使用
一.SLF4j使用 1.在系统中使用SLF4J 以后开发的时候,日志记录方法的调用,不应该来直接调用日志的实现类,而是调用日志抽象层里面的方法: 给系统里面导入slf4j的jar和 logback的实 ...
- SpringBoot的日志管理(输出级别,输出到文件)
场景 SpringBoot实战项目搭建专栏地址: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/column/info/35688 1.SpringBoot使用默 ...
- SpringBoot生成日志文件---logback和log4j
SpringBoot生成日志文件---logback和log4j 一.logback logback是SpringBoot自带的日志文件,默认会为控制台输出INFO级别的日志,并且不会将日志文件保存. ...
- SpringBoot使用日志
转载自 SpringBoot使用日志 1.选什么日志框架 首先列举一下日志门面和实现 SpringBoot默认选用SLF4J和Logback 日志级别:springboot默认已经帮我们配置好了日志 ...
最新文章
- 为什么U-Net在医学图像上表现优越?
- cgroup介绍、安装和控制cpu,内存,io示例
- 平均获客成本_获客成本创新高,英语流利说(LAIX.US)获客难流利
- 转载:缓存 Cache
- kubeadm reset后安装遇到的错误:Unable to connect to the server: x509: certificate signed by unknown authority
- 网页中文乱码--UTF-8和GB2312互转
- Cesium获取经度 ,纬度,高度
- android 4.3 模拟器,模拟器上的Android 4.3
- C语言网络编程——基础
- 配置svn忽略 node_modules等文件
- matlab资产组合最优配置,[转载]资产组合有效前沿的解和最优解(MATLAB语言)
- 加强自定义菜单 即更换浏览器默认右击菜单栏
- 了解如何在Windows中安全删除文件
- OSM学习之路(一):OSM介绍
- S2-052的POC测试
- XTUOJ-1272-Robot
- Langevin dynamic 和 Hamiltonian Monte Carlo
- Linux超级用户(root)的密码
- android支付宝运动修改器,支付宝运动步数修改器下载-无需root刷支付宝运动步数工具下载_飞翔下载...
- selenium模拟浏览器解决反监测,获取cookies解决登录问题
热门文章
- 周志明jvm第三版笔记-第一部分:第一章 走进java
- krait和kryo_各种Java序列化性能比较
- STM32F103+RTT从零开始(三)—— S50门禁卡复制
- 点击邮件自动弹出发送邮件窗口
- 微米纳米机器人 课件_部编版四年级语文下册7 纳米技术就在我们身边ppt课件1(共23张ppt)...
- 利用随机森林预测股票大盘涨跌
- m.soudashi.cn 地图_搜索引擎网站推广优化有什么技巧?
- 计算机开机最快设置,如何让电脑启动速度变快
- Excel常用的操作
- SQL Server数据库mdf文件中了勒索病毒.FREEMAN。扩展名变为FREEMAN