Spring Boot 2.4.0正式发布,全新的配置文件加载机制(不向下兼容)
The following article is from BAT的乌托邦 Author YourBatman
往期热门文章:
2、Insert into select语句引发的生产事故!
5、花30分钟,用Jenkins部署码云上的SpringBoot项目
前言
Spring Boot 2.4.0
正式发布。2.4.0是第一个使用新版本方案的Spring Boot发行版本。
注意:2.4.0版本号没有.RELEASE
后缀,没有.RELEASE
后缀,没有.RELEASE
后缀。使用的是Spring最新的版本发布规则。
还记得Spring Boot 2.3.0.RELEASE
版本发布时那会麽?前后相差将好半年:
一般来说,次版本号的升级会有点料,根据之前的爆料此次升级据说是做了大量的更新和改进。那么老规矩,作为小白鼠的我先代你玩一玩,初体验吧。
正文
Pivotal OSS
支持策略,从发布日期起支持主要版本3年(注意:是主要版本)。2.3.x
:支持的版本。2020.05发布,是现在的活跃的主干 2.2.x
:支持的版本。2019.10发布,是现在的活跃的主干 2.1.x
:2018.10发布,支持到2020.10月底,建议尽快升级2.0.x
:2018.3发布,2019.4.3停止维护 1.5.x
:生命已终止的版本。2017.1发布,是最后一个1.x分支,2019.8.1停止维护回忆2.3版本的新特性
spring.lifecycle.timeout-per-shutdown-phase=xxx
来配置,默认值是30s。/config/mysql/application.properties
/config/redis/application.properties
5.2.x
spring-boot-starter-web
不会再把validation带进来,所以若使用到,你需要自己添加这个spring-boot-starter-validation
依赖 2.4.0主要新特性
2.4.0.1、全新的配置文件处理(properties/yaml)
application.properties
和application.yml
文件的方式:application-profile.properties/yaml
这种(或者使用了Spirng Cloud的配置中心、(带有分隔符----的)多yaml文件),那么默认是不向下兼容的,需要你显式的做出些更改2.4.0.2、老版本版本配置属性迁移指南
application.poperties/yaml
的处理做了更新/升级。旨在简化和合理化外部配置的加载方式。它还提供了新功能:spring.config.import
支持。所以呢,对于Spring Boot 2.4.0之前的版本(老版本)若升级到2.4.0需要做些修改,指导建议如下:方式一:恢复旧模式(不推荐)
Environment
里增加一个属性spring.config.use-legacy-processing = true
就搞定。最简的方式就是把这个属性放在application.poperties/yaml里即可。spring.config.use-legacy-processing = true
ConfigFileApplicationListener
去解析。ConfigFileApplicationListener
属于Spring Boot非常核心的底层代码,这次做了不向下兼容的改进,可见它对进击云原生的决心// @since 1.0.0
// @deprecated since 2.4.0 in favor of {@link ConfigDataEnvironmentPostProcessor}
@Deprecated
public class ConfigFileApplicationListener implements EnvironmentPostProcessor, SmartApplicationListener, Ordered {
...
}
方式二:按新规则迁移(推荐)
spring.profiles
配置项 spring.config.import
,增加了对kubernetes配置的支持等等),并且还要学会如何迁移。2.4.0.3、从spring-boot-starter-test中删除Vintage Engine
Spring Boot 2.2.0
版本开始就引入JUnit 5作为单元测试默认库,在此之前,spring-boot-starter-test包含的是JUnit 4的依赖,Spring Boot 2.2.0版本之后替换成了Junit Jupiter(Junit5)。Spring Boot 2.4.0
这个版本决定了把Vintage Engine从spring-boot-starter-test正式移除。因此:若你的工程仍需要对JUnit4支持,那么请手动引入依赖项(如果工程量不大,强烈建议使用JUnit5,比4好用太多):<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
</exclusion>
</exclusions>
</dependency>
说明:其实在2.4.0之前,若你是从https://start.spring.io
生成的项目其实也是不会带有vintage-engine的。只不过它是通过显式的在pom里通过exclusion标签来排除的
2.4.0.4、嵌入式数据库检测
spring.datasource.username = sa
spring.datasource.initialization-mode
的值2.4.0.5、Logback配置属性
LogbackLoggingSystemProperties
用于对应,它继承自之前的LoggingSystemProperties
~~老(已废弃)~~ | 新 -------- | ----- ~~ROLLING_FILE_NAME_PATTERN ~~ | LOGBACK_ROLLINGPOLICY_FILE_NAME_PATTERN ~~LOG_FILE_CLEAN_HISTORY_ON_START~~ | LOGBACK_ROLLINGPOLICY_CLEAN_HISTORY_ON_START ~~LOG_FILE_MAX_SIZE~~ | LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE ~~LOG_FILE_TOTAL_SIZE_CAP~~ | LOGBACK_ROLLINGPOLICY_TOTAL_SIZE_CAP ~~LOG_FILE_MAX_HISTORY~~ | LOGBACK_ROLLINGPOLICY_MAX_HISTORY
2.4.0.6、不再注册DefaultServlet
DefaultServlet
。因为在绝大多数的应用中,Spring MVC提供的DispatcherServlet
是唯一需要被注册的Servlet。从源码处感受下这次改动:AbstractServletWebServerFactory:
// 2.4.0之前版本,默认值是true
private boolean registerDefaultServlet = true;
// 2.4.0以及之后版本,默认值是false
private boolean registerDefaultServlet = false;
server.servlet.register-default-servlet = true
把它注册上去。补课:什么是DefaultServlet?
/
),当别的servlet都没匹配上时就交给它来处理,一般用于处理静态资源如.jpg,.html,.js
这类的静态文件。DefaultServlet
在传统web容器里,会被配置在tomcat目录(此处以tomcat为例)下的conf/web.xml
里:<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
说明:tomcat下的web.xml对其加载的所有的Application都生效,并且最终和Application自己的web.xml内容合并,遇相同的话后者优先级更高
private void addDefaultServlet(Context context) {
Wrapper defaultServlet = context.createWrapper();
defaultServlet.setName("default");
defaultServlet.setServletClass("org.apache.catalina.servlets.DefaultServlet");
defaultServlet.addInitParameter("debug", "0");
defaultServlet.addInitParameter("listings", "false");
defaultServlet.setLoadOnStartup(1);
// Otherwise the default location of a Spring DispatcherServlet cannot be set
defaultServlet.setOverridable(true);
context.addChild(defaultServlet);
context.addServletMappingDecoded("/", "default");
}
DispatcherServlet
的path也是/
(覆盖掉了DefaultServelt
)。在Spring MVC环境下倘若是静态资源,也不用DefaultServelt费心,Spring MVC专门提供了一个DefaultServletHttpRequestHandler
用于处理静态资源(虽然最终还是Dispatcher给defaultServlet
去搞定)。DefaultServletHttpRequestHandler
和注册DefaultServlet
来增加不必要的开销喽。2.4.0.7、HTTP traces不再包含cookie头
Cookie
以及响应头Set-Cookie
。源码处感受一下:org.springframework.boot.actuate.trace.http.Include:
// 2.4.0版本之前:包含COOKIE_HEADERS这个头
static {
Set<Include> defaultIncludes = new LinkedHashSet<>();
defaultIncludes.add(Include.REQUEST_HEADERS);
defaultIncludes.add(Include.RESPONSE_HEADERS);
defaultIncludes.add(Include.COOKIE_HEADERS);
defaultIncludes.add(Include.TIME_TAKEN);
DEFAULT_INCLUDES = Collections.unmodifiableSet(defaultIncludes);
}
// 2.4.0版本以及之后:不包含COOKIE_HEADERS这个头
static {
Set<Include> defaultIncludes = new LinkedHashSet<>();
defaultIncludes.add(Include.REQUEST_HEADERS);
defaultIncludes.add(Include.RESPONSE_HEADERS);
defaultIncludes.add(Include.TIME_TAKEN);
DEFAULT_INCLUDES = Collections.unmodifiableSet(defaultIncludes);
}
management.trace.http.include = cookies, errors, request-headers, response-headers
自行控制。2.4.0.8、Neo4j
@ConfigurationProperties(prefix = "spring.data.neo4j")
public class Neo4jProperties implements ApplicationContextAware { ... }
// 无Neo4jDataProperties配置类
Spring Boot 2.4.0以及之后版本:
@ConfigurationProperties(prefix = "spring.neo4j")
public class Neo4jProperties { ... }
@ConfigurationProperties(prefix = "spring.data.neo4j")
public class Neo4jDataProperties { ... }
其它升级关注点
Spring Framework 5.3:Spring Boot 2.4.0使用的是5.3.0主线分支(之前使用的5.2.x或更低)
Spring Framework 5.3的新特性应该重点关注,请移步我上篇文章:Spring Framework 5.3.0正式发布,在云原生路上继续发力
Spring Data 2020.0:Spring Boot 2.4.0使用的是最新发布的Spring Data 2020.0
此版本的命名方式不同于之前,是因为使用了Spirng最新的release train命名方式。Spring在2020年4月份发布了最新的版本命名方式,可参考前面这篇文章:Spring改变版本号命名规则:此举对非英语国家很友好
支持Java 15:此版本的Spring Boot完全支持Java 15,最小支持依旧是Java 8自定义属性名支持:当使用构造函数绑定时,属性的名称需要和参数名称保持一样。如果您想使用Java保留关键字,这可能是一个问题。
如下例子:
@ConfigurationProperties(prefix = "sample")
public class SampleConfigurationProperties {
private final String importValue;
// import是Java关键字
public SampleConfigurationProperties(@Name("import") String importValue) {
this.importValue = importValue;
}
}
总结
这是A哥奉给大家的,对Spring Boot2.4.0版本新特性的介绍,希望对你有些帮助。
Spring Boot 2.4.0版本的升级目标,基本和Spring Framework 5.3.0保持一致:为云原生做努力。表现在除了删除些无用类,禁止不需要的类的加载外,重点还会体现在它对配置文件加载机制的重构上,也是本次升级的重头戏。
Spring Boot重写了对配置文件的加载机制,并且新引入了近40个类来处理(老方式仅有区区几个类),可见其重视、重要程度。因此,为了适应未来的发展,你一定要掌握,并且越早越好。