本文已被 https://yourbatman.cn收录; 女娲Knife-Initializr工程可公开访问啦;程序员专用网盘 https://wangpan.yourbatman.cn;技术专栏源代码大本营: https://github.com/yourbatman/tech-column-learning;公号后台回复“ 专栏列表”获取全部小而美的 原创技术专栏
你好,我是YourBatman:一个俗人,贪财好色。
Title | Link |
---|---|
所属专栏 | [[YourBatman]-资讯/新特性](https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzI0MTUwOTgyOQ==&action=getalbum&album_id=1608175058441551875#wechat_redirect),[[YourBatman]-Spring技术栈新特性](https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzI0MTUwOTgyOQ==&action=getalbum&album_id=2408123804142403585#wechat_redirect) |
源代码 | https://github.com/yourbatman/FXP-java-ee |
程序员专用网盘公益上线啦,注册送1G超小容量,帮你实践做减法 | https://wangpan.yourbatman.cn |
Java开发软件包(Mac) | https://wangpan.yourbatman.cn/s/rEH0 提取码:javakit |
女娲工程 | http://152.136.106.14:8761 |
版本约定 | [Mac OS 13.0.1],[IDEA 2022.2.4] |
📚前言
在云原生发展势头下,Spring被冠以太重的标签,被新兴框架Quarkus
、Micronaut
等嘲笑“廉颇老矣”。可亲是否可知,最初Spring就是以轻量级出圈(interface 21就是佐证),横扫Java EE。
笔者在年初的文章早有“预告”,Spring团队2022年会有大动作。从年初到年底,可谓千呼万唤始出来:Sprng Framework 6终于GA(同时期的还有Spring Boot和Spring Cloud在前后脚都会发布RELEASE版本)。
Sprng Framework 5于2017年9月份发布,距今已有5年多了。作为Spring技术栈的底座:本次Spring Framework大版本号升级是阻断式的,不向下兼容。
值得注意的是,本文并不尝试解释Spring Framework为何一跃将JDK的baseline从JDK 8提到JDK 17,以及废弃javax启用全新的jakarta命名空间,那是另一个系列的话题了。本文仅尝试介绍新特性。
🌈what’s new(新特性)
老规矩,将我们关心的功能爽一遍。
🚀最低要求JDK 17
Spring Framework 6基于JDK 17构建。换句话讲,若想使用Spring Framework 6那么你的JDK环境最低要求JDK 17。市占率方面目前JDK 8其实已跌落至第二,曾经的“你发任你发,我用Java 8”终将成为历史,这不Spring这次就来引领潮流。
问:同为LTS版本的JDK,Spring团队为何没选择受众更多的JDK 11而一跃选择了更高版本的JDK 17呢?不怕栽跟头吗?
现在我创建一个Spring Framework 6的项目(基于maven构建):
点确定后,加入依赖:
启动Spring容器的代码:
/**
* 在此处添加备注信息
*
* @author YourBatman
* @since 0.0.1
*/
@ComponentScan
public class Application {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(Application.class);
System.out.println(context.getBean(DemoConfiguration.class));
}
}
成功运行程序!
当然若你不信邪,执意用JDK 8运行这段程序,那么你得到的将是这个:
🚀从Java EE迈向Jakarta EE
javax命名空间其实早已成为过去式,毕竟现在已快2023年了。这次Spring团队也是跟着JDK一起,顺势的完全摒弃掉了javax命名空间,拥抱Jakarta EE。
Jakarta EE估摸不少读者可能没听过,没关系!关于Java EE和Jakarta EE的“恩怨情仇(历史渊源)”,感兴趣的一定要看看笔者的这个系列:[[YourBatman]-Java EE](https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzI0MTUwOTgyOQ==&action=getalbum&album_id=1940957171895058444#wechat_redirect),给你说得门清。
从Jakarta EE 9开始,便使用了全新的jakarta.*
命名空间。本次建议使用从Jakarta EE 10起步。对应的技术主要有:
- Jakarta Servlet 6.0
- Jakarta Servlet JSP JSTL 3.0
- Jakarta Validation 3.0
- Jakarta WebSocket 2.1
- Jakarta Persistence 3.1
- Jakarta JMS 3.1
- Jakarta JSON 2.1
- Jakarta JSON Bind 3.0
- Jakarta Activation 2.1
- Jakarta Mail 2.1
- Jakarta Transaction 2.0
- Jakarta WS RS 3.1
- Jakarta XML SOAP 3.0
- Jakarta XML WS 4.0
另外,之前有些内置进JDK里面的Java EE注解,现在也换“包名”啦,如具有代表性的:JSR-330的@Inject
、JSR 250的@PostConstruct
、@Predestroy
以及及其常用的@Resource
注解。
🚀LocalVariableTableParameterNameDiscoverer标记为过时
LocalVariableTableParameterNameDiscoverer是ParameterNameDiscoverer
的一个实现类,用于找出参数名。它是Spring的一个经典实现,早在Spring Framework 2.0就已出现。我们知道java代码编译后,默认情况下参数名是不会保留的,而它利用了LocalVariableTable + ASM
字节码技术实现了参数名的查找。
直到Spring Framework 4.0(此版本开始支持JDK 8),才出现了它的替代者:StandardReflectionParameterNameDiscoverer
,基于JDK 8标准的参数化实现的。
JDK支持编译时加上
"-parameters
参数,便可保留方法参数的名字
一直以来,Spring Framework为了考虑兼容性只能降低LocalVariableTableParameterNameDiscoverer
的优先级但并“不敢”打干掉它的注意。这次显然不一样勒,已经标记为过时了:
按照Spring OSS标准,标记为过时的类,在下个中型版本将会被移除。为此,Spring为了防止“乱用”,如若在运行过程中发现你使用到了此类,会收到如下warn警告:
Using deprecated '-debug' fallback for parameter name resolution. Compile the
affected code with '-parameters' instead or avoid its introspection: 处理的类的全类名
这是一个优秀框架该有的样子:完成了太多的非功能性需求,可谓想犯错都难。
🚀ListenableFuture被标记为过时
JDK最初有Futrue,而后Spring搞了一个增强版的ListenableFuture
。直到Java 8的出现:有了CompletableFuture
再也不用使用ListenableFuture了。这不,这次顺势就把它拿下了。
除了ListenableFuture
本身,与其相关的类都已被标记为过时,如:ListenableFutureCallback、SuccessCallback、FailureCallback等。
🚀移除调CommonsMultipart等类
一直以来spring-web支持两种上传文件方式:
- 基于Apache Commons Fileuplod库的
CommonsMultipartResolver
的解决方案 - 基于标准Servlet规范的
StandardServletMultipartResolver
解决方案
对应的就是MultipartResolver
接口的两个实现类,如下图所示(6之前的版本有两个实现):
从本版本(Spring Framework 6)起,基于Apache Commons实现方案正式退出历史舞台,相关类也已从源代码里删除。自此MultipartResolver
有且仅有唯一实现:
值得一提的是:起初Spring框架上传文件推荐选择的是基于Apache Commons库的方案(也就是CommonsMultipartResolver
),因为那会基于Servlet的方案性能有较大问题;但随着Servlet的更新(从Servlet 3.0开始,javax.servlet.http.Part
技术出现就不再有性能问题了),问题得到解决。
🚀HttpMethod不再是枚举,改为了类
HttpMethod是web开发中比较常见的一个类,本次从enum -> class
类型的变更绝大部分情况下都能兼容,只在某些特殊case下注意一下即可(比如不能再使用switch而需改为if else来做分支逻辑了)。
PS:HttpMethod改为类后重写了hashcode和equals方法,因此等值
==
比较也是不会有问题的,请放心食用
Spring Framework 5.x版本:
Spring Framework 6版本:
🚀RestTemplate最低要求HttpClient 5.x
RestTemplate是spring-web对http请求的抽象,它底层的实现技术可以是Apache HttpClient、OkHttp、JDK实现等等,具体采用什么技术是由ClientHttpRequestFactory
的实现类决定的。
本次Spring Framework 6针对Apache的实现,彻底摒弃Apache HttpClient 4.x,拥抱Apache HttpClient 5。
虽然底层实现有所变更,但若你代码里是面向Spring的RestTemplate进行编程的,那就可做到无感知。
🚀仅标注@RequestMapping注解不再被扫描为Controller了
喜大普奔!喜大普奔!喜大普奔!重说三,懂的都懂。
在之前的Spring Framework版本中,spring-web会将标注有@Controller
注解或者标注有@RequestMapping
注解的扫描为一个控制器(controller):
这个动作看似合理方便了使用,但这在Spring Cloud场景下非常“烦人”:@FeignClient
+ API Jar包是现行微服务通信的典型使用方式。
在Spring Boot大一统的包扫描背景下,多数团队@EnableFeignClients
也采用大一统的扫描策略,然而这就是“灾难”的开始:非常容易得就将一个@FeignClient
接口扫描为一个controller从而对外暴露了其所有接口,除了大大拖慢启动速度、造成URL冲突之外,进而产生了重大安全隐患。
PS:虽然一般的公司在脚手架层面会默默的解决掉这个问题,但据我了解绝大多数团队其实并未关注过此问题,比如笔者写过的:
这下好了,Spring Framework 6帮我们解决了这个烦恼,这是它的判断逻辑:控制器只认@Controller
注解了。
这让我想起来有些同学使用@Bean
去声明一个控制器,现在是不行了(之前可以大概率是因为类上有@RequestMapping
注解而误打误撞了),需要引起重视。
🚀GenericApplicationContext支持AOT
支持AOT是Spring拥抱Native、拥抱云原生的基础,当然这也是为何必须基于至少JDK 17构建的原因之一。
🚀对GraalVM native images提供一流的支持
GraalVM嘛,等下篇文章聊Spring Boot 3.0.0时再谈。
🚀PathMatchingResourcePatternResolver使用NIO和module方式扫描加速
Spring的scan一直是导致容器启动慢的重要愿意之一,甚至没有之一。Spring Framework 6版本对此做了很大的优化。
其实,早在Spring Framework 5就采用了index方式进行scan优化,效果还是比较显著的。但是此方式并不够100%通用且使用起来不太方便,因此没击起什么浪花(默认情况下并不会启用)。这次不一样了:将可选项变为了必选项,更是唯一选项。
在此之前PathMatchingResourcePatternResolver
只能通过扫xxx路径下的所有文件(同步阻塞IO)来发现Bean。多module是JDK瘦身的一种方式,这次就利用多模块 + GraalVM双重优势,来大大加快扫描的速度,核心代码在这里:
🚀强依赖micrometer的可观测性
在Spring Framework 6的几个(不是全部)子项目中使用micrometer
进行了直接的观测性。比如:spring-web模块现在就强依赖包io.micrometer:micrometer-observation
来完成(编译)工作:
micrometer之前只被用在Spring Boot中,现在Spring Framework部分子项目也接入了,这样观察将会更直接、更全面,这就是生态整合能力了吧。
✍总结
Spring Framework作为Java领域最为流行的框架(没有之一),有非常庞大的用户群体、项目历史。这些历史现在看来即是它的优势,有时也会成为较重的包袱。
Spring团队自然能感知到“危机”,故有了Spring Native项目回应“尚能饭否”。这次Spring Framework 6直接以JDK 17起底,并且对GraalVM native images提供一流支持,目的非常明确:(适当的)甩掉包袱,证明我还行。
最后分享一句话:上山的人永远不要嘲笑下山的神。况且Spring依旧如日中天~
推荐阅读
- [[YourBatman]使用IDEA的60+个快捷键分享给你,权为了提效(Git&Other&完结篇)](https://mp.weixin.qq.com/s/0MXKWnfh7QHPESLiK-cKAw)
- [[YourBatman]使用IDEA的60+个快捷键分享给你,权为了提效(Live Template&Postfix Completion篇)](https://mp.weixin.qq.com/s/Pev8GseObHTtNiQzH5vdwg)
- [[YourBatman]使用IDEA的60+个快捷键分享给你,权为了提效(重构篇)](https://mp.weixin.qq.com/s/D4pA-Rt2REpQdLF8OfIUEw)
- [[YourBatman]使用IDEA的60+个快捷键分享给你,权为了提效(代码补全篇)](https://mp.weixin.qq.com/s/n4Qznj5CkT-I1t0NLHvZBA)
- [[YourBatman]使用IDEA的60+个快捷键分享给你,权为了提效(运行/调试篇)](https://mp.weixin.qq.com/s/BNtNlJBCcXUZxbD0LyPi5Q)
- [[YourBatman]使用IDEA的60+个快捷键分享给你,权为了提效(视窗、选择篇)](https://mp.weixin.qq.com/s/7b4GEs3_2HLA6hWk0YNh_w)
- [[YourBatman]使用IDEA的60+个快捷键分享给你,权为了提效(导航篇)](https://mp.weixin.qq.com/s/bbm23FBXxDW9dJQMjYGE9g)
- [[YourBatman]使用IDEA的60+个快捷键分享给你,权为了提效(操作系统、终端篇)](https://mp.weixin.qq.com/s/V32Xq2eijPH1V7hzdCPKKw)
我是YourBatman:前25年不会写Hallo World、早已毕业的大龄程序员。高中时期《梦幻西游》骨灰玩家,网瘾失足、清考、延期毕业、房产中介、保险销售、送外卖...是我不可抹灭的黑标签
- 🎓2013.07 清考、毕业答辩3次未通过、延期毕业
- 🏷2013.08-2014.07 宁夏中介公司卖二手房1年,毕业后第1份工作
- ️️🏷2014.07-2015.05 荆州/武汉,泰康人寿卖保险3月、饿了么送外卖2月,还有炸鸡排、直销等第2345份工作
- 🏷2015.08 开始从事Java开发,闯过外包,呆过大厂!擅长抽象思维,任基础架构团队负责人
- 🏷2021.08 因“双减政策”失业!历经9面,终获美团外卖L8的offer
- 🙅🏻♀️Java架构师、Spring开源贡献者、CSDN博客之星年度Top 10、领域建模专家、写作大赛1/2届评委
- 📚高质量代码、规范践行者;DDD领域驱动深度实践;即将出版书籍
《Spring奇淫巧技》