我是Spring Boot和Vaadin的粉丝,这并不奇怪。 当Spring Boot Vaadin插件成为GA时 ,我欣喜若狂。 最近,我对由JetBrains提供的基于JVM的语言Kotlin产生了兴趣。 因此,我想检查一下如何在Kotlin中开发一个小型Spring Boot Vaadin演示应用程序-并在此过程中学到一些东西。 这是我的发现,无特定顺序。
春天需要非最终的东西
看来Spring需要@Configuration
类和@Bean
方法是非最终的。 由于我以前的Spring项目是用Java编写的,所以我从未意识到这一点,因为我从未使用过final
关键字。 但是, 默认情况下 ,Kotlin类和方法是最终的 :因此,您必须在Kotlin中使用open关键字。
@Configuration
openclassAppConfiguration{
@Bean
@UIScope
openfunmainScreen()=MainScreen()
}
没有主班
Spring Boot应用程序需要一个带有public static void main(String… args)
方法的类来引用以@SpringBootApplication
注释的类。 通常,这两个类是相同的。
Kotlin没有这种静态方法的概念,但是提供了纯函数和对象。 我试图通过在同一文件中使用纯函数引用带注释的对象来发挥创造力。
@SpringBootApplication
openclassBootVaadinKotlinDemoApplication
funmain(varargargs:String){
SpringApplication.run(arrayOf(BootVaadinKotlinDemoApplication::class.java),args)
}
不同的入口点参考
由于主函数未附加到类,因此没有要引用的主类可在IDE内部启动。 但是,Kotlin创建的.class与后缀为Kt
的文件名相同。
我的文件名为BootVaadinKotlinDemoApplication.kt
,因此生成的类名称为BootVaadinKotlinDemoApplicationKt.class
。 这是在IDE中启动应用程序所引用的类。 请注意,在命令行上使用mvn spring-boot:run
时无需担心,因为Spring Boot似乎会扫描main方法。
简短易读的Bean定义
Java语法被视为冗长的。 与有用代码量相比,其冗余性非常低时,我认为这不是大问题。 但是,在某些情况下,即使是我也不得不承认这是很多仪式。 在这种情况下,可以使用Java语法定义bean:
@Bean@UIScope
publicMainScreenmainScreen(){
returnnewMainScreen();
}
Kotlin切断了所有仪式,只保留了肉:
- 无需分号
- 没有新关键字
- 因为主体由单个表达式组成,所以块用等号替换
- 由于没有障碍,因此无需返回关键字
- 无需返回类型,因为可以轻松推断
@Bean@UIScope
funmainScreen()=MainScreen()
Spring配置文件通常很长,很难阅读。 Kotlin使它们变得更短,而又不影响可读性。
初始化块是你的朋友
在Java中,构造函数用于不同的操作:
- 将参数存储到属性中
- 将参数传递给超级构造函数
- 其他初始化代码
第一步很容易,因为属性是Kotlin中类签名的一部分。 同样,调用超级构造函数由类签名处理。 其余的初始化代码不属于类签名,而应属于init
块。 大多数应用程序不包含此部分,但Vaadin需要设置布局和相关内容。
classMainScreenPresenter(tablePresenter:TablePresenter,buttonPresenter:NotificationButtonPresenter,
view:MainScreen,eventBus:EventBus):Presenter<MainScreen>(view,eventBus){
init{
view.setComponents(tablePresenter.view,buttonPresenter.view)
}
}
使用套用方法
Kotlin有一个提供小型专用功能的标准库。 其中之一是套用,定义为inline fun T.apply(f: T.() → Unit): T (source)
。 这是一个扩展函数,这意味着每种类型在导入到作用域后都将拥有它。 此函数需要一个作为函数的参数,并且不返回任何内容。 在此函数内部,可以this
方式访问已应用的对象( this
是隐式的,如在标准Java代码中一样)。 它允许这样的代码:
VerticalLayout(button,table).apply{
setSpacing(true)
setMargin(true)
setSizeFull()
}
将视图和演示者分解到同一文件中
Kotlin使代码变得非常小,因此某些文件可能只有一行长(不算导入)。 打开不同的文件来检查相关的类是没有用的。 包是一种组织代码的方式; 我认为文件可能是Kotlin中的另一种方式。 例如,可以将Vaadin视图和演示者放入同一文件中。
classNotificationButton:Button("Click me")
classNotificationButtonPresenter(view:NotificationButton,eventBus:EventBus):
Presenter<NotificationButton>(view,eventBus){...}
Lambda吸引了很多听众
从Java 8开始,可以将实现为匿名内部类的单方法接口替换为lambda。 Kotlin具有相同的功能,另外:
- 如果lambda是唯一的参数,则它允许省略括号
- 如果lambda有一个参数,则其默认名称是
it
,不需要声明
与Vaadin API结合使用时,两者的语法都非常可读:
view.addValueChangeListener{
valrowId=it.property.value
valrowItem=view.containerDataSource.getItem(rowId)
eventBus.publish(SESSION,rowItem)
}
不过,应该将更复杂的逻辑放入自己的函数中。
翻译自: https://blog.frankel.ch/playing-spring-boot-vaadin-kotlin/