在Spring Framework 5.0中引入Kotlin支持
因最近一直在业余做Spring Framework 5.0 M4 文档的翻译工作(也就进度稍慢了),所以对5里面的各种比较关注,尤其是新东西,发现就拿来先翻译分享给大家了
我们几个月前有介绍关于Kotlin在start.spring.io上的支持,我们有一直在进行工作,以确保Spring和Kotlin在一起玩得很好。 Kotlin的一个关键优势是它提供了一个与用Java编写的库之间非常好的互操作性。但是有更多的方法可以进一步,允许编写完全成熟的Kotlin代码,当开发您的下一个Spring应用程序。除了Spring Framework对Java 8的支持,Kotlin应用程序可以利用类似功能的Web或bean注册API,还有其他Kotlin专用功能,应该可以让你的生产力水平达到一个新的高度。
这就是为什么我们在Spring Framework 5.0 M4中引入了一个专门的Kotlin支持,我想在这篇博客中总结的功能,旨在使您的开发人员体验无缝的在Spring中一起使用这些技术。你可以使用这个链接在Spring Framework bug tracker中查找Kotlin的相关问题。
利用Kotlin可空信息(nullable information)
Spring最初基于来自Raman Gupta的社区贡献,现在利用Kotlin null-safety support以确定是否需要HTTP参数,而不必显式地定义required
属性。 这意味着@RequestParam name:String?
被视为不需要(not required),@RequestParam name:String
视为必需。 这也支持Spring消息@Header
注解。
以类似的方式,使用@Autowired
或@Inject
的Spring bean注入使用此信息来知道是否需要bean。 @Autowired lateinit var foo:Foo
意味着Foo
类型的bean必须在应用程序上下文中注册,而@Autowired lateinit var foo:Foo?
不会引发错误,如果这样的bean不存在。
RestTemplate和Functional Web API的扩展
Kotlin extensions 允许以非侵入方式扩展现有的API,提供了一个更好的替代实用程序类或在Kotlin特定类层次结构中添加Kotlin专用功能到Spring中。一些类似Mario Arias的KotlinPrimavera已经展示了我们可以带给Spring的各种Kotlin助手API,以允许编写更多的惯用代码。使用Spring Framework 5,我们集成了Spring框架中最有用和最受欢迎的扩展,并添加了新的扩展。
例如,Kotlin reified type parameters为JVM 泛型类型擦除提供了一个解决方法,因此我们介绍了一些扩展,以利用此功能在可能的情况下提供更好的API。
这允许为RestTemplate提供方便的API(感谢来自Netflix的Jon Schneider为此做出贡献)。例如,要在Java中检索“Foo”对象的列表,必须写:1
List<Foo> result = restTemplate.exchange(url, HttpMethod.GET, null, new ParameterizedTypeReference<List<Foo>>() { }).getBody();
或者,如果你使用中间数组:1
List<Foo> result = Arrays.asList(restTemplate.getForObject(url, Foo[].class));
而在Kotlin与Spring Framework 5扩展中,你将能够写:
1 | val result : List<Foo> = restTemplate.getForObject(url) |
请注意,Kotlin扩展名是静态解析的,你必须导入它们。 在上面的示例中,您需要添加import org.springframework.web.client.RestOperationsExtension.getForObject
才能使用它。 Kotlin扩展通常由IDE(如IntelliJ IDEA)(如静态导入)自动建议,但对于嵌套在容器object
中的扩展,它仍然无效(您可以投票KT-15440),所以直到它被修复,你将不得不手动添加Spring Kotlin扩展导入。
Spring Framework 5.0 M4中目前可用的“RestTemplate”或功能性Web API扩展包括:
- RestOperationsExtension
- ServerRequestExtension
- BodyInsertersExtension
- BodyExtractorsExtension
- ClientResponseExtension
这些扩展还提供了支持本地KotlinKClass
的成员函数,允许你指定Foo :: class
参数而不是Foo :: class.java
。
Reactor Kotlin extensions
Reactor是Spring Framework 5.0的反应基础,并且有很好的机会你将使用它的Mono,Flux和[StepVerifier] (https://projectreactor.io/docs/test/release/api/reactor/test/StepVerifier.html) 开发reactive Web应用程序时的API。
所以今天我们还通过新的reactor-kotlin项目在Reactor中引入Kotlin支持!它提供了扩展,能够通过写入foo.toMono()
从任何类实例创建Mono
实例,许多人喜欢Mono.just(foo)
。它还支持例如使用stream.toFlux()
从Java 8Stream
实例创建Flux
。还提供了Iterable
,CompletableFuture
和Throwable
扩展以及基于KClass的Reactor API变体。
这仍然是这个项目的早期,所以如果你想提供没有的功能,随时自由地贡献你自己的扩展。
Functional bean registration with Kotlin
Spring Framework 5.0引入了一种新的方式来注册bean,使用lambda作为XML或JavaConfig的替代,使用@Configuration
和@Bean
。 简而言之,它使得有可能注册bean与一个Supplier
lambda,充当一个FactoryBean
。
在Java中,你将会写如下的代码:
1 | AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); |
而在Kotlin中,reified类型参数允许我们简单地写:
1 | val context = AnnotationConfigApplicationContext() |
你可以看到Spring应用程序的一个具体例子,在https://github.com/mix-it/mixit /使用函数web和 bean注册API。
ApplicationContext
相关Kotlin可用扩展如下:
No need to declare your bean class as open anymore
直到现在,使用Kotlin构建Spring Boot应用程序时遇到的几个问题之一是需要在每个类上添加一个open
关键字,并且使用CGLIB(如@Configuration
类)来代替Spring bean的成员函数。 这个需求的根本原因来自于在Kotlin里的classes are final by default这个事实。
幸运的是,Kotlin 1.0.6现在提供了一个kotlin-spring
插件,在默认情况下打开类和它们的成员函数,注解或元注解使用以下注解之一:
@Component
@Async
@Transactional
@Cacheable
元注解支持意味着用@Configuration
,@Controller
,@RestController
,@Service
或@Repository
注解的类会自动打开,因为这些注解是使用@Component
进行的元注解。
我们更新了start.spring.io默认启用它。 你可以看看这个Kotlin 1.0.6博客帖子了解更多详情,包括 新的kotlin-jpa
和kotlin-noarg
插件对Spring Data实体非常有用。
Kotlin based Gradle build configuration
回到5月,Gradle 宣布,他们将支持在Groovy之外的Kotlin中编写构建和配置文件。这使得可以在IDE中具有完全自动完成和验证,因为这些文件是常规静态类型的Kotlin脚本文件。这很可能成为基于Kotlin的项目的自然选择,但这也对Java项目也很有价值。
自5月以来,gradle-script-kotlin项目不断发展,现在可以使用2个警告:
- 你需要Kotlin 1.1-EAP IDEA插件来获得自动完成(但如果你使用
kotlin-spring
插件,因为1.1-M04
不能可靠地使用这个插件,等待Kotlin1.1-M05
) - 文档不完整,但Gradle团队对Kotlin Slack的#gradle频道非常有帮助。
两个spring-boot-kotlin-demo项目使用这种基于Kotlin的Gradle构建,可以随意看看。我们)在start.spring.io讨论上添加了这样的支持。
Kotlin Script based templates
从4.3版本开始,Spring Framework提供了一个ScriptTemplateView使用支持JSR-223的脚本引擎来渲染模板。 Kotlin 1.1-M04提供了这样的支持,并允许渲染基于Kotlin的模板,有关详细信息,请参阅此提交。
这使得出现了一些有趣的使用情况,如使用kotlinx.htmlDSL或简单的Kotlin multiline(多线)’String’插值,编写类型安全模板,例如此kotlin -script-templating项目。 这可以允许您在IDE中编写具有完全自动完成功能和重构支持的这类模板:
1 | import io.spring.demo.User |
这个功能仍在进行中,但我正在与Kotlin团队合作,暂时使其准备好对Spring Framework 5.0 GA上的嵌套模板和i18n在MVC和Reactive两方面的支持。
结语
我使用Kotlin编写Spring Boot应用程序越多,我觉得这两种技术有着共同的目标,允许您使用表达性,简短和可读的代码来更高效地编写应用程序,而Spring Framework 5 Kotlin支持将这些技术以更加自然,简单和强大的方式来展现给我们。
Kotlin可以用来编写基于注解的Spring Boot应用程序,但作为一种新的functional and reactive applications也将是一种很好的尝试,Spring Framework 5.0将会启用。
Kotlin团队做了一个伟大的工作,修复几乎所有的bug点,我们报告,所以非常感谢他们。即将到来的Kotlin 1.1版本预计也修复KT-11235,以允许指定数组注解标记单个属性值,无须使用arrayOf()
。你将面临的主要问题可能是KT-14984,它将需要明确指定lambda类型(如Supplier {}
或HandlerFunction {}
)其中只需指定{}
应该就足够了。
通过转到start.spring.io并生成一个Spring Boot2.0.0(SNAPSHOT)
项目,可以自由测试Spring Framework 5.0 Kotlin支持并在这里或者在Kotlin Slack的“#spring”频道向我们发送您的反馈。你也可以贡献你需要的Kotlin扩展;-)
翻译自:https://spring.io/blog/2017/01/04/introducing-kotlin-support-in-spring-framework-5-0
[ 转载请保留原文出处、译者和译文链接。]