重磅发布!Spring 6.2 正式版震撼登场!新特性速览

文摘   2024-11-15 08:01   新疆  

最新实战案例锦集:《Spring Boot3实战案例合集》持续更新,每天至少更新一篇文章,订阅后将赠送文章最后展示的所有MD文档(学习笔记)。

环境:SpringBoot3.2.5



1. 多线程初始化Bean

在6.2之前的所以版本中Spring 容器在实例化单例Bean时,都是在一个for循环中,一个一个的实例化。自6.2起,单例bean的初始化支持多线程。底层通过Executor + CompletableFuture#runAsync 实现。同时你还可以自定义线程池对象,如下方式:

@Beanpublic Executor bootstrapExecutor() {  ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();  taskExecutor.setCorePoolSize(5) ;  taskExecutor.setMaxPoolSize(5) ;  taskExecutor.initialize() ;  return taskExecutor ;}

注意:bean的名称必须是bootstrapExecutor。

2. 新增注解@Fallback

当Spring容器中存在多个相同类型的Bean,并且需要确定在自动装配时应该使用哪个Bean时,@Primary注解就非常有用了,否则容器都无法正确启动。

Spring6.2新增了一个@Fallback注解,该注解表示该 bean 符合备用自动装配候选条件,这是 @Primary 注释的替代品。如果多个匹配候选者中只有少数几个被标记为fallback,则剩余的 bean 将被选中。与Primary bean 一样,备用 bean 仅在查找单个注入点的多个候选者时起作用。如下示例:


interface CommonDAO {}class UserDAO implements CommonDAO {}class PersonDAO implements CommonDAO {}@Configurationpublic class AppConfig { @Bean public UserDAO userDAO() { return new UserDAO() ; } @Bean @Fallback public PersonDAO personDAO() { return new PersonDAO() ; } @Bean public CommonService commonService(CommonDAO dao) { return new CommonService(dao) ; }}

在该示例中,CommonService注入的是UserDAO。当UserDAO Bean不存在时,才会注入PersonDAO。

3. @Bean定义2个相同的beanName

先看如下示例:

@Configurationpublic class AppConfig {  @Bean(name = "a")  Person personA() {    return new Person(1) ;  }  @Bean(name = "a")  Person personB() {    return new Person(2) ;  }}

这里通过@Bean声明2个Person bean对象,但是他们的名称相同。在6.2之前的版本中,容器中存在的将是

4. RestClient改进

RestClient新增了create(URI)方法,直接将URI解析为baseUrl。

改进

@GetMapping("/client")public String client() {  return RestClient.create("http://localhost:8080")      .get()      .uri(URI.create("/params/index"))      .retrieve()      .body(String.class) ; }

以上代码在6.2之前版本,运行后将抛出如下异常:

而在6.2版本开始,以上代码将没有任何问题。

5. 从请求Header中绑定数据

有如下接口:

@GetMapping("/{path}")public void get(Params params, @PathVariable long path,   @RequestParam String foo, @RequestHeader String accept) {  System.out.printf("path: %d%n", path);  System.out.printf("foo: %s%n", foo);  System.out.printf("accept: %s%n", accept);  System.out.printf("params: %s%n", params);}public static record Params(@PathVariable long path,   @RequestParam String foo, @RequestHeader String accept) {}

在6.2之前版本输出结果如下:

自6.2开始record中header值也能正常的绑定了。

6. 任务调度新增跟多元数据信息

目前,/actuator/scheduledtasks actuator 端点提供了关于计划任务的信息,包括任务的类型、目标和调度信息。本次新增了如下信息

  • 上次执行时间

  • 上次执行状态

  • 下次执行时间

     

7. 其它功能

  1. 更新 UndertowHttpHandlerAdapter 以进行调度

  2. 优化 @Contract Javadoc 以提及此更改和新的返回值

  3. AOT 处理 Bean 验证时不考虑级联和容器元素约束

  4. 避免通过 @Lazy 代理重复解析单例 Bean

  5. 注册 @TestBean 完全限定方法名的运行时提示

  6. 引入 @DisabledInAotMode 中对自定义原因的支持

  7. 在 ResponseBodyEmitter 中尽可能使用乐观锁

  8. 修订 WebClient 和 WebTestClient 中使用 Apache HTTP 组件的 Cookie 支持

  9. 从 @Contract 中移除纯属性

  10. 引入 @CheckReturnValue 注解

  11. 如果资源路径不以斜杠结尾,ResourceHttpRequestHandler 抛出 IllegalArgumentException 会导致某些第三方库失效

  12. 在 ThreadPoolTaskExecutor 和 ThreadPoolTaskScheduler 上提供虚拟线程的一流选项

  13. 如果 @RequestParam 从 null 转换为空字符串,HttpServiceProxyFactory 应该省略可选参数

  14. Reactor Netty 响应不应缓冲完整响应

  15. 放宽 MockMVC DSL 构造函数的可见性

  16. 支持从 Publisher 转换为 InputStream

  17. 验证静态资源位置以斜杠结尾

  18. 在 BeanUtils 中支持记录规范构造函数

  19. 重命名 OverrideMetadata 用于 Bean 覆盖

  20. 重命名 BeanOverrideStrategy 枚举常量

  21. 优化 ServletWebRequest

  22. 移除静态资源处理中的相对路径支持

  23. 为 @MockitoBean 和 @MockitoSpyBean 添加 value 属性别名

  24. 拒绝带有工厂前缀的 Bean 名称用于 Bean 覆盖

  25. 修订 WhatWG URL 解析器中 URI 变量语法的处理

  26. 在 preDetermineBeanTypes 中也检查预注册的单例

  27. 移除不必要的数组长度检查

  28. 优化 CorsConfiguration

  29. 添加 RFC 3986 URL 解析器

  30. 在 ReactorServerHttpRequest 中处理由 Reactor-Netty 解析的 X-Forwarded-Prefix

  31. RestClient 应自动检测 ReactorClientHttpRequestFactory

  32. 改进 SockJS 支持中的随机源

  33. 停止用伪定义替换现有的 Bean 覆盖定义

  34. 在 @TestBean 和 @MockitoBean 中引入 enforceOverride 标志

  35. 重构 unwrapOptional 方法以提高可读性和性能

  36. ServerSentEvent 应实现 equals() 和 hashCode()

  37. 减少因 NoTransactionInContextException 实例引起的 GC 压力

  38. 将 DynamicPropertyRegistrarBeanInitializer 设为公共类

  39. 改进AbstractBeanDefinition 和 BeanMetadataAttribute 的 toString() 方法

  40. 添加用于资源处理器检查的工具方法

  41. UrlHandlerFilter 不应从上下文路径 URL 中删除尾部斜杠

  42. AbstractGenericHttpMessageConverter 没有接受 Charset 的构造函数

  43. JdbcClient ResultQuerySpec 提供 optionalValue() 方法

  44. 在 HttpComponentsClientHttpRequestFactory 中添加读取超时设置器

  45. 修复由 EclipseLinkJpaDialect 中的同步块导致的虚拟线程固定问题

  46. 添加 RestClient.Builder#messageConverters(List)

  47. 优化附加 Assert 方法的空安全性

  48. 当 @Transactional 传播级别不是 REQUIRES_NEW 或 NOT_SUPPORTED 时,抛出运行时错误

  49. 启用虚拟线程时,长时间运行的固定延迟任务会阻塞固定速率任务

  50. 提供一种公共机制来检测 AOT 处理是否正在进行

  51. 在 JdkClientHttpRequest 中仅使用一种请求超时机制

  52. 使用 AOT 和原生镜像支持 Bean 覆盖特性

  53. 在 Spring AOT 中限制 BeanInstanceSupplier 中的反射操作

  54. 使用 IntroductionInterceptor 创建的 Mixin 导致动态代理而不是 CGLIB 代理

  55. 在 ServletServerHttpRequest 中宽松地解析 URI

  56. 排除 StompSubProtocolHandler 中的授权消息的 ERROR 日志记录

  57. 在 AbstractContextLoaderInitializer 中传播完整的 ServletContext(用于访问 SessionCookieConfig)

     

以上是本篇文章的全部内容,如对你有帮助帮忙点赞+转发+收藏

推荐文章

速看!Spring Boot任务调度你不知道的使用技巧

自己动手实现Agent统计API接口调用耗时

Spring Boot + 事务钩子,完美解决事务并发问题

AOP高级应用,优雅实现异常重试机制

进阶!@ConfigurationProperties注解高级用法你知道吗?

我100%确定,你对@ComponentScan注解的了解仅限于皮毛

基于Spring Boot REST API设计指南

自己动手实现精简版SpringBoot原来如此简单

确保Spring Boot定时任务只执行一次方案

Spring Boot中通过3种方式初始化数据,你们如何选择?

基于Spring Boot给所有Controller接口添加统一前缀的5种方式

强大!基于Spring Boot HTTP请求响应日志记录组件,值得一用

在SpringBoot中拦截修改请求Body的2种正确方式

Spring Boot自定义注解玩转Controller接口参数任意转换

Spring全家桶实战案例源码
spring, springboot, springcloud 案例开发详解
 最新文章