Spring Framework 6.2.0-M1:那些小而美的事物

工程 | Stéphane Nicoll | 2024 年 4 月 11 日 | ...

Spring Framework 团队一直在大力审查问题跟踪器,并减少已打开问题的数量。这项工作早就应该进行了,其中许多问题无效或已被取代。这有助于团队专注于数量更易于管理的问题,我们借此机会解决了一些尚未有时间处理的长期存在的问题。

在这篇文章中,我想带大家了解一下那些相对较小但有时票数很高的问题的集合,它们最终在此里程碑版本中得以解决。

支持转义属性占位符

属性占位符是一种在任意字符串中替换来自环境的属性的方式。假设 Environment 中设置了 customer.name 为 "John Smith",那么 "Customer ${customer.name}" 将解析为 "Customer John Smith"。

在某些特殊情况下,您可能希望保留原始值,而不是让它被解析。一个问题于 2008 年创建,获得了不少投票。Spring Framework 6.2.0-M1 允许您使用可配置的转义字符(默认为反斜杠)来转义占位符。以上面的例子为例,"Customer \${customer.name}" 现在将解析为 "Customer ${customer.name}"。

这看起来像是一个无害的更改,为什么我们花了这么长时间才修复它?!事实证明,我们不得不重写解析器,这带来了一些积极的副作用:默认值现在是惰性解析的,并且在解析嵌套占位符时,异常消息提供了解析链。

支持回退 Bean

高票问题也已得到解决,让您在编写可能需要回退 Bean 的配置时有更多控制。如果在没有提供该类型的 Bean 时,则会使用回退 Bean。这实质上是 @Primary 的补充,而无需指定它带来的权衡。

考虑一个组件需要定义 MyService。您可以为该服务提供一个默认实现,但您希望如果用户指定了一个实现,它可以按类型透明地注入。到目前为止,用户必须使用 @Primary 配置他们的特定 Bean 以确保它被使用,因为现在定义了两个该类型的 Bean。

从 Spring Framework 6.2.0-M1 开始,您可以使用 @Fallback 来编写配置

@Configuration
class MyConfiguration {

	@Bean
	MyComponent myComponent(MyService service) {
    	...
	}

	@Bean
	@Fallback
	MyService defaultMyService() {
    	...
	}

}

正如您所猜测的,如果没有定义其他 MyService Bean,则使用 defaultMyService。否则,容器将透明地选择在外部定义的那个。

Bean 后台初始化

有史以来投票最多的问题之一是也在此里程碑版本中得到解决。单个 Bean 可以使用新引入的 bootstrap 属性在后台初始化。

@Configuration
class MyConfiguration {

    @Bean(bootstrap = BACKGROUND)
    MyExpensiveComponent myComponent() {
   	 ...
    }

}

查看参考文档了解有关此新功能的更多详细信息。

对计划任务的 TaskDecorator 支持

Spring Framework 6.2.0-M1 也允许对计划任务使用 TaskDecorator,从而在此过程中统一任务执行和调度。请参阅相关问题了解更多详情。

对 MockMvc 的 AssertJ 支持

我们喜欢AssertJ!虽然 Spring Boot 在一段时间前已经搭上了这趟列车并提供了许多使用它的测试工具,但框架团队一直比较保守。与此同时,我们认识到我们对 Hamcrest 的支持可能无法满足所有人的需求:使用静态导入使得 API 不易发现,并且编写自定义断言更困难。

Spring Framework 6.2.0-M1 为使用 MockMvc 和 AssertJ 测试您的 Web 应用程序提供了全面的支持。

构建 AssertableMockMvc 实例更加直接,类本身提供了专门的工厂方法。如果您手头有 WebApplicationContext,这就像 AssertableMockMvc.from(webApplicationContext) 一样简单。如果您只想在单元测试中测试一个控制器,可以如下进行

AssertableMockMvc mvc = AssertableMockMvc.of(List.of(new HelloController()), builder ->
    	builder.defaultRequest(get("/hello").accept(MediaType.APPLICATION_JSON)).build());

获得实例后,您可以执行常规请求,并将其包装在 AssertJ 的标准 assertThat

assertThat(mvc.perform(get("/vehicle/{id}", "12").accept(MediaType.TEXT_PLAIN))).hasStatusOk()
    	.body().isEqualTo("Honda Civic");

这个首个里程碑版本涵盖了与现有 Hamcrest matcher 相同的功能,并扩展了高级 JSON 支持,例如

assertThat(perform(get("/message"))).body().json()
    	.isLenientlyEqualTo(new ClassPathResource("samples/message.json"));

这是 API 的第一个版本,我们期待社区反馈来改进它。

还有更多!

有超过一百个问题得到解决,Spring Framework 6.2.0-M1 包含了许多增强功能,预计未来几周我们会提供更多信息。

在有基于它的 Spring Boot 3.4 快照版本之前,您必须将 spring-framework.version 覆盖为此里程碑版本。请尝试一下,并告诉我们结果如何。

编码愉快!

获取 Spring 新闻通讯

通过 Spring 新闻通讯保持联系

订阅

领先一步

VMware 提供培训和认证,为您的进步注入动力。

了解更多

获取支持

Tanzu Spring 通过一项简单的订阅提供对 OpenJDK™、Spring 和 Apache Tomcat® 的支持及二进制文件。

了解更多

即将举行的活动

查看 Spring 社区所有即将举行的活动。

查看全部