seo优化全解第1版-搜索引擎入门详解(【干货】SpringBoot细心的同学会发现里面其实有一个小坑)
优采云 发布时间: 2022-03-30 14:22seo优化全解第1版-搜索引擎入门详解(【干货】SpringBoot细心的同学会发现里面其实有一个小坑)
SpringBoot入门教程04-环境详解前言
上一节我们介绍了SpringBoot配置文件详细传送门
细心的同学会发现里面居然有一个小坑
比如我们修改user.properties文件,修改内容如下:
user.name=henry1111
user.age=16
重启应用,打开浏览器,打开浏览器输入:8080/user,浏览器显示:
Henry-16
和预想的Henry1111-16不一样,为什么?
让我们看另一个例子
介绍环境
在控制器包下,新建一个EnvController类,内容如下
@RestController
public class EnvController {
@Autowired
private Environment env;
@RequestMapping("/env")
public String env(){
System.out.println(env.getProperty("user.name"));
System.out.println(env.getProperty("user.age"));
return env.getProperty("user.name")+"-"+env.getProperty("user.age");
}
}
然后重启应用,打开浏览器,打开浏览器输入:8080/env,浏览器显示:
Henry-16
我们知道Environment类的实例存储了spring容器的配置信息。以上内容的输出与请求一致:8080/user,但与user.properties中的配置不一致。为什么?下面我们详细分析。
标准Servlet环境
在EnvController类的env()方法中打断点,然后请求:8080/env,可以在idea中查看env的详细信息
如图所示,env本质上是StandardServletEnvironment类的一个实例。如果继续跟踪代码,可以看到getProperty本质上是在遍历循环propertySources。如果propertySource.getProperty(key)的当前值为null,则继续遍历。如果值不为null,则直接返回该值。
PropertySourcesPropertyResolver类的getProperty方法代码如下
@Nullable
protected T getProperty(String key, Class targetValueType, boolean resolveNestedPlaceholders) {
if (this.propertySources != null) {
Iterator var4 = this.propertySources.iterator();
while(var4.hasNext()) {
PropertySource propertySource = (PropertySource)var4.next();
if (this.logger.isTraceEnabled()) {
this.logger.trace("Searching for key '" + key + "' in PropertySource '" + propertySource.getName() + "'");
}
Object value = propertySource.getProperty(key);
if (value != null) {
if (resolveNestedPlaceholders && value instanceof String) {
value = this.resolveNestedPlaceholders((String)value);
}
this.logKeyFound(key, propertySource, value);
return this.convertValueIfNecessary(value, targetValueType);
}
}
}
if (this.logger.isTraceEnabled()) {
this.logger.trace("Could not find key '" + key + "' in any property source");
}
return null;
}
本例中,env的propertySources有11个元素,最后一个元素对应我们自定义的配置文件user.properties,
可以看到该元素中的user.name 和user.age 与配置文件中的相同,但该元素位于列表的末尾。如果 user.name 可以在前一个元素中找到,则 env.getProperty("user.name") 返回其他内容。
然后尝试找到user.name,在systemProperties中找到user.name,第五个元素下标为4。
针对一个个找的麻烦,我们用代码打印环境中的键值,修改EnvController。代码如下:
@RestController
public class EnvController {
@Autowired
private Environment env;
@RequestMapping("/env")
public String env(){
StandardServletEnvironment environment = (StandardServletEnvironment) env;
MutablePropertySources propertySources = environment.getPropertySources();
Iterator iterator = propertySources.iterator();
while (iterator.hasNext()) {
PropertySource propertySource = iterator.next();
if (propertySource instanceof MapPropertySource) {
MapPropertySource mapPropertySource = (MapPropertySource) propertySource;
String[] propertyNames = mapPropertySource.getPropertyNames();
for (String s : propertyNames) {
System.out.println(s+":"+mapPropertySource.getProperty(s));
}
}
}
return env.getProperty("user.name")+"-"+env.getProperty("user.age");
}
}
执行日志我就不贴了,大家可以自己运行看看输出。
总结
学完本节,我们应该对Springboot配置文件的加载过程有了一个深入的了解。这是一个简短的总结。
踩坑
@PropertySource(""),idea开发环境也启动成功了,但是通过maven打包运行时,会报java.lang.IllegalArgumentException: Malformed \uxxxx encoding。
关于这个错误,网上大部分都说配置文件有'\'或者文件路径有中文。查了半天也没找到'\'和中文。一开始很纳闷,后来仔细研究了springboot的配置文件。开始加载的过程,只有这篇文章文章
看完文字我们就知道了,