【译注】本文是 Spring 官网博文的译文,英文原版在:https://spring.io/blog/2017/01/04/introducing-kotlin-support-in-spring-framework-5-0。
我们在几个月前介绍了 start.spring.io 对 Kotlin 的支持, 我们已继续努力以确保 Spring 与 Kotlin 更好地协作。 Kotlin 的主要优势之一是它提供了与 Java 编写的库非常好的互操作性。 但是当你开发下一个 Spring 应用程序时,有一些方式可以更进一步,让你能够编写完全是 Kotlin 惯用法的代码。 Spring 框架除了对 Java 8 的支持外,Kotlin 应用程序也可以利用像函数式 web 或者 bean 注册 API 这些功能,另外还有 Kotlin 专用的功能,可以让你达到新的生产力水平。
这就是为什么我们在 Spring Framework 5.0 M4 中引入 Kotlin 专有支持,我想在这篇博文中总结一下这些功能,旨在使开发人员在使用这些技术时无缝融入。 你可以使用这个链接在 Spring 框架 bug 跟踪系统中查找 Kotlin 相关问题。
我们 Kotlin 支持的关键组成部分是 Kotlin 扩展。 它们允许以非侵入式的方式扩展现有 API,提供了比实用程序类或 Kotlin 特有类继承结构更好的替代方法,来将 Kotlin 专用功能添加到 Spring。 像 Mario Arias 的 KotlinPrimavera 这样的一些库已经展示了我们可以为 Spring API 提供 Kotlin 助手的各种方式,以便能够编写更加合乎惯用法的代码。 使用 Spring Framework 5,我们将最有用与最受欢迎的扩展集成在 Spring 框架依赖中,并且我们也在添加新的扩展!请注意,Kotlin 扩展是静态解析的,你必须导入它们(类似 Java 中的静态导入)。
用 Kotlin 进行函数式 bean 注册
Spring Framework 5.0 引入了一种新的方式来注册 bean:使用 lambda 表达式作为 XML 方式或者用 @Configuration
与 @Bean
的 JavaConfig 方式的替代。 简而言之,它能够用 Supplier
lambda 表达式充当 FactoryBean
来注册 Bean。
例如在 Java 中你这么写:
GenericApplicationContext context = new GenericApplicationContext();
context.registerBean(Foo.class);
context.registerBean(Bar.class, () -> new
Bar(context.getBean(Foo.class))
);
而在 Kotlin 中,具体化的类型参数可以让我们简写为:
val context = GenericApplicationContext {
registerBean<Foo>()
registerBean { Bar(it.getBean<Foo>()) }
}
ApplicationContext
相关的 Kotlin 扩展有 BeanFactoryExtensions、 ListableBeanFactoryExtensions、 GenericApplicationContextExtensions 以及 AnnotationConfigApplicationContextExtensions。
Spring Web 函数式 API,Kotlin 的方式
Spring Framework 5.0 附带了一个 Kotlin 路由 DSL,允许你以干净、惯用的 Kotlin 代码来利用最近宣布的 Spring 函数式 Web API:
{
("/blog" and accept(TEXT_HTML)).route {
GET("/", this@BlogController::findAllView)
GET("/{slug}", this@BlogController::findOneView)
}
("/api/blog" and accept(APPLICATION_JSON)).route {
GET("/", this@BlogController::findAll)
GET("/{id}", this@BlogController::findOne)
}
}
感谢 Yevhenii Melnyk 的早期原型与帮助!你可以参见一个使用 函数式 web API 的 Spring Boot 应用程序的具体示例,该示例在 https://github.com/mix-it/mixit/。
利用 Kotlin 的可空性信息
原本基于 Raman Gupta 的社区贡献,Spring 现在利用 Kotlin 空安全支持来确定某个 HTTP 参数是否必需,而无需明确定义 required
属性。 这意味着 @RequestParam name: String?
会被视为非必需而 @RequestParam name: String
视为必需。 Spring Messaging 的 @Header
注解也支持这点。
类似地,以 @Autowired
或者 @Inject
注入的 Spring bean 使用这一信息来获悉一个 bean 是必需还是非必需。 @Autowired lateinit var foo: Foo
意味着在应用程序上下文中必须注册一个类型为 Foo
的 bean,而对于 @Autowired lateinit var foo: Foo?
则在这样的 bean 不存在时并不会引发错误。
用于 RestTemplate 与函数式 Web API 的扩展
例如,Kotlin 具体化的类型参数为 JVM 泛型类型擦除提供了一种解决方法,因此我们引入了一些扩展来利用这一优势尽可能提供更好的 API。
这允许为 RestTemplate
提供便利的 API(感谢 Netflix 的 Jon Schneider 对此贡献)。 例如,要在 Java 中检索 Foo
对象的列表,你不得不这样写:
List<Foo> result = restTemplate.exchange(url, HttpMethod.GET, null, new ParameterizedTypeReference<List<Foo>>() { }).getBody();
或者,如果你使用一个中间的数组:
List<Foo> result = Arrays.asList(restTemplate.getForObject(url, Foo[].class));
而用 Spring Framework 5 扩展,在 Kotlin 中,你可以这样够写:
val result: List<Foo> = restTemplate.getForObject(url)
Spring Framework 5.0 中提供的 Web API 的 Kotlin 扩展有 RestOperationsExtensions、ServerRequestExtensions、 BodyInsertersExtensions、 BodyExtractorsExtensions、ClientResponseExtensions、 ModelExtensions 以及 ModelMapExtensions。
这些扩展还提供了支持 Kotlin 原生 KClass
的成员函数,允许你指定 Foo::class
参数而不是 Foo::class.java
。
Reactor Kotlin 扩展
Reactor 是 Spring Framework 5.0 所基于的响应式基础,而在开发响应式 web 应用程序时,你会有很好的机会去使用其 Mono、 Flux 以及 StepVerifier API。
所以如今我们还通过新的 reactor-kotlin 扩展 项目在 Reactor 中引入 Kotlin 支持! 它提供了能够通过任何类实例这样写 foo.toMono()
来创建 Mono
实例的扩展,当然很多人倾向于使用 Mono.just(foo)
。 它也支持例如通过 stream.toFlux()
从 Java 8 Stream
实例创建 Flux
。 还提供了 Iterable
、 CompletableFuture
与 Throwable
扩展以及 KClass
基于 Reactor API 的变体。
目前该项目还在早期阶段,所以如果你发现缺了点什么,不妨贡献自己的扩展。
不再需要将你的 bean 类声明为 open
当目前为止,当你使用 Kotlin 构建 Spring Boot 应用程序时遇到的少数痛点之一就是,需要为每个由 CGLIB 如 @Configuration
类代理的 Spring bean 类及其成员函数添加 open
关键字。 这一要求的根本原因源于 Kotlin 中类是默认 final 的事实。
幸运的是,Kotlin 1.0.6 现在提供了一个 kotlin-spring
插件,对于由以下注解之一标注或元标注(meta-annotated)的类,会默认打开该类及其成员函数:
@Component
@Async
@Transactional
@Cacheable
元注解支持意味着用 @Configuration
、 @Controller
、 @RestController
、 @Service
或者 @Repository
标注的类会自动打开,鉴于这些注解都已被 @Component
注解元标注。
我们已经更新了 start.spring.io 默认启用了该插件。 你可以看下这篇 Kotlin 1.0.6 的博文了解更多详情,其中包括对 Spring Data 实体非常有用的新的 kotlin-jpa
与 kotlin-noarg
插件。
基于 Kotlin 的 Gradle 构建配置
去年 5 月份,Gradle 宣布 除了支持 Groovy 外,他们还将支持用 Kotlin 编写构建及配置文件。 这使在 IDE 中完整的自动补齐与验证成为可能,因为这些文件都是普通的静态类型的 Kotlin 脚本文件。 这可能会成为基于 Kotlin 的项目的自然选择,但这对 Java 项目也同样有价值。
自去年 5 月以来,gradle-script-kotlin 项目不断演进,现在已经可用,请记住以下两条警告:
- 你需要 Kotlin 1.1-EAP IDEA 插件来获取自动补齐功能(但是如果你要用
kotlin-spring
插件就要等到 Kotlin1.1-M05
因为1.1-M04
不能与该插件一起可靠运转)【译注】:目前 1.1 已发布,该问题已不存在。
- 其文档不够完整,但是 Gradle 团队对 Kotlin Slack 的 #gradle 频道帮助很大。
spring-boot-kotlin-demo 以及 mixit 项目都使用这种基于 Kotlin 的 Gradle 构建,所以不妨看看。 我们在讨论在 start.spring.io 上添加了这项支持。
基于模版的 Kotlin 脚本
从 4.3 版开始,Spring 框架提供了一个 ScriptTemplateView,它使用支持 JSR-223 的脚本引擎来渲染模版,而 Spring Framework 5.0 会更进一步支持 i18n 以及模版嵌套。 Kotlin 1.1 提供了这样的支持,并允许渲染基于 Kotlin 的模板,详见这次提交。
这带来了一些有趣的使用场景,例如使用 kotlinx.html DSL 或者简单使用带有内插的 Kotlin 多行 String
来编写类型安全的模版,如这个 kotlin-script-templating 项目所示。 这可以让你在 IDE 中用完整的自动补齐与重构支持来编写这种模板:
import io.spring.demo.*
"""
${include("header")}
<h1>${i18n("title")}</h1>
<ul>
${users.joinToLine{ "<li>${i18n("user")} ${it.firstname} ${it.lastname}</li>" }}
</ul>
${include("footer")}
"""
结论
我用 Kotlin 写的 Spring Boot 应用程序越多,我越觉得这两项技术共享相同的理念:都允许你使用表现力强、简短且可读性强的代码来更高效地编写应用程序,而 Spring Framework 5 的 Kotlin 支持是以自然、简单与强大的方式结合两项技术的重要一步。
Kotlin 可以用于编写基于注解的 Spring Boot 应用程序,但也会与 Spring Framework 5.0 即将启用的新型函数式与响应式应用程序非常契合。
Kotlin 团队做得非常棒,修复了我们报告的几乎所有的痛点,非常感谢他们。 即将推出的 Kotlin 1.1 发布版预计也会修复 KT-11235 以允许指定数组注解的属性用单个值而无需 arrayOf()
。 你会面对的主要剩余问题可能是 KT-14984:在只需指定 { }
就足够的地方需要显式指定 lambda 表达式的类型。
不妨这样测试下 Spring Framework 5.0 的 Kotlin 支持:打开 start.spring.io 并生成一个 Spring Boot 2.0.0 (SNAPSHOT)
项目,并在此(译注:Spring 官网)或者在 Kotlin Slack 的 #spring
频道向我们发送你的反馈。 你还可以贡献你需要的 Kotlin 扩展 ;-)
相关推荐
Spring5.0 对 Kotlin 有很好的支持。 7. 移除的特性 随着 Java、JavaEE 和其他一些框架基准版本的增加,SpringFramework5 取消了对几个框架的支持。例如: Portlet Velocity JasperReports XMLBeans JDO...
主要介绍了简单了解Spring Framework5.0新特性,涉及了核心框架修订,核心容器更新,使用Kotlin进行函数式编程等几个方面的介绍,具有一定参考价值,需要的朋友可以了解下。
Spring5.0官方中文文档新特性: 升级到 Java SE 8 和 Java EE 7 反应式编程模型 使用注解进行编程 函数式编程 使用 REST 端点执行反应式编程 HTTP/2 支持 Kotlin 和 Spring WebFlux 使用 Lambda 表达式注册 bean ...
Work on Spring Framework with Kotlin Who this book is for This book is for competent Spring developers who wish to understand how to develop complex yet flexible applications with Spring. You must ...
spring-kotlin-coroutine, Kotlin协同程序对 spring的支持 spring-kotlin-coroutine 是一个包含几个库和一个演示应用程序的库,它允许在 spring 应用程序中使用Kotlin协同程序作为第一类公民。项目模块这里项目包含...
Spring.5.0.By.Example 2018年7月新书 不可不懂得spring5 范例程序 包括以下重点内容: Reactive Web Clients Server-Sent Events Persistence with Spring Data and Reactive Kotlin Basics and Spring Data Redis,...
Kotlin is being used ... You’ll also learn to use Spring Security to beef up security of your application before testing it with the JUnit framework and then deploying it on a cloud platform like AWS.
Spring Boot Kotlin sample project This is the source code for the a sample Spring Boot application developed with Kotlin and Spring Data JPA. See also ...
kotlin-spring:Kotlin,Spring研究
spring boo2、java、kotlin整合简单的小例子(无前台页面)。 码云地址 https://gitee.com/yexg/kotlinDemo
The Spring Framework provides a comprehensive programming and configuration model for modern Java-based enterprise applications - on any kind of deployment platform. A key element of Spring is ...
kotlin官方中文pdf文档kotlin官方中文pdf文档kotlin官方中文pdf文档kotlin官方中文pdf文档kotlin官方中文pdf文档kotlin官方中文pdf文档kotlin官方中文pdf文档kotlin官方中文pdf文档kotlin官方中文pdf文档kotlin官方...
gradle-kotlin-spring:具有Gradle,Kotlin和带有Kotlin DSL的Spring的Multi-ProjectModule示例
TutorialsPoint SpringJDBC JSoup CouchDB Cassandra JSF Kotlin 教程
5.0之后的工程架构采用VirtualAPK实现了插件化,5.0之前采用Java编码实现,5.0之后采用Kotlin编码实现,编码架构由MVVM和MVP组成,工程架构和编码架构及编码语言开发者可根据自己具体的项目实际需求去决定选择使用,...
spring-boot-kotlin-app:使用Spring Boot和Spring MVCJAX-RS的Kotlin RESTful Web服务
中引入了一个专门针对Kotlin的支持。 本章我们就一起来学习怎样使用Kotlin集成SpringBoot、SpringMVC等框架来开发Web服务端应用,同时简单介绍Spring 5.0对Kotlin的支持特性。 《Kotlin极简教程》 出版社: 机械...
Sprint BootKotlin 这是spring boot kotlin的示例。现场演示登录ID : wonwoo Password : 123 ID : user Password : 456 怎么跑?克隆# git clone https://github.com/wonwoo/spring-boot-kotlin-example.git跑步# cd...
在Spring Boot 2中使用Kotlin的示例 Redis 使用Redis服务器的示例 弹性4j 这是在Spring Boot 2中使用的示例。 可以通过注释使用由resilience4j提供的功能,例如@CircuitBreaker , @Retry , @RateLimiter , @...
主要介绍了spring boot + jpa + kotlin入门实例详解 ,需要的朋友可以参考下