一、概述
spring官方最近宣布,将在Spring Framework 5.0版本中正式支持Kotlin语言。这意味着Spring Boot 2.x版本将为Kotlin提供一流的支持。
这并不会令人意外,因为Pivotal团队以广泛接纳JVM语言(如Scala和Groovy)而闻名。下面我们用Spring Boot 2.x和Kotlin应用程序。
二、搭建环境
1、环境
IntelliJ和Eclipse都对Kotlin提供了支持,可以根据自己的喜好搭建Kotlin开发环境。
2、构建应用
首先创建一个Spring Boot 2项目,然后修改POM配置,让项目保护指定的Java版本和Kotlin版本。依赖关系如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jre8</artifactId>
<version> 1.1 . 2 </version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-reflect</artifactId>
<version> 1.1 . 2 </version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-kotlin</artifactId>
<version> 1.1 . 2 </version>
</dependency>
|
注意,我们正在为Kotlin源码文件和测试文件指定文件位置:
1
2
|
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
<testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
|
要编译Kotlin模块和源码,需要使用kotlin-maven-plugin插件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
<plugin>
<artifactId>kotlin-maven-plugin</artifactId>
<groupId>org.jetbrains.kotlin</groupId>
<version> 1.1 . 2 </version>
<configuration>
<compilerPlugins>
<plugin>spring</plugin>
</compilerPlugins>
<jvmTarget> 1.8 </jvmTarget>
</configuration>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-allopen</artifactId>
<version> 1.1 . 2 </version>
</dependency>
</dependencies>
</plugin>
|
到此为止,构建Kotlin应用程序所需的一切就搭建好了。注意,可以去Maven*仓库寻找以下组件的最新版本:spring-boot-starter-web、kotlin-stdlib-jre8、kotlin-reflect、jackson-module-kotlin、spring-boot-starter-test。
下面设置应用程序的上下文。
3、应用程序上下文
下面进入Kotlin的代码,编写熟悉的Spring Boot应用程序上下文:
1
2
3
4
5
|
@SpringBootApplication
class KotlinDemoApplication
fun main(args: Array<String>) {
SpringApplication.run(KotlinDemoApplication:: class .java, *args)
}
|
可以看到熟悉的@SpringBootApplication注解。
我们有一个类定义了KotlinDemoApplication类。在Kotlin中,类的默认范围是public,所以可以省略。另外,如果一个类没有变量、没有函数,它可以被声明为没有大括号。所以,从本质上讲,我们只是定义了一个类。
另外,方法或函数默认是公开的,所以不必在这里声明。另外,不返回任何内容的函数不需要指定一个void返回类型。
最后,在一个类的外部定义的任何函数都是自动静态的。这使得这些函数可以在启动时得到执行。
现在让我们从根目录运行我们的应用程序,使用mvn spring-boot: run。应用程序得以启动,应该可以看到应用程序在端口8080上运行。
接下来,构建一个控制器。
4、控制器
现在添加一个控制器到服务中:
1
2
3
4
5
6
7
|
@RestController
class HelloController {
@GetMapping ( "/hello" )
fun helloKotlin(): String {
return "hello world"
}
}
|
与标准的Spring控制器没有太大的不同,但是肯定代码量更精简。我们为此控制器添加一个测试类和案例来验证我们的工作:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
@RunWith (SpringRunner:: class )
@SpringBootTest (classes = arrayOf(KotlinDemoApplication:: class ),
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class KotlinDemoApplicationTests {
@Autowired
lateinit var testRestTemplate: TestRestTemplate
@Test
fun whenCalled_shouldReturnHello() {
val result = testRestTemplate
// ...
.getForEntity( "/hello" , String:: class .java)
assertNotNull(result)
assertEquals(result?.statusCode, HttpStatus.OK)
assertEquals(result?.body, "hello world" )
}
}
|
这个测试显示了Kotlin强大的功能之一——null安全!可以为null的Kotlin变量必须使用“?”声明。然后,编译器知道在访问该属性之前需要进行防御性编码。
在我们的测试中,TestRestTemplate被定义为可空类型,每次访问它时,我们使用null合并运算符“?”来实现——如果被调用对象为空,则返回null。
这声明了在程序中使用null,并强制开发人员在使用它们时编写安全的代码。
接下来,我们添加一个服务并将其集成到我们的控制器中。
5、服务
服务很容易添加到我们的项目中。这样做:
1
2
3
4
5
6
7
|
@Service
class HelloService {
fun getHello(): String {
return "hello service"
}
}
|
这里的简单服务与单个函数返回一个String。接下来,让我们将服务连接到控制器中并使用它来返回值:
1
2
3
4
5
6
7
8
9
|
@RestController
class HelloController(val helloService: HelloService) {
// ...
@GetMapping ( "/hello-service" )
fun helloKotlinService(): String {
return helloService.getHello()
}
}
|
啊,看起来不错!在Kotlin中,主构造函数可以与类声明一起定义。我们从构造函数中省略了@Autowired注释,因为它不是一段时间的强制性的。
这些参数将自动转换为类中的字段。Kotlin称它们为属性。无需定义getter或setter方法,因为它们是自动创建的。当然,如果需要,您可以覆盖这些默认值。
在Kotlin中,函数中的类和变量的属性可以使用var或val来定义。var表示可变属性,val表示final属性。这允许编译器检查非法访问。由于HelloService是一个单例,所以我们把它连接成一个val来防止突变。
接下来,我们为此控制器方法添加一个测试:
1
2
3
4
5
6
7
8
9
|
@Test
fun whenCalled_shouldReturnHelloService() {
var result = testRestTemplate
// ...
.getForEntity( "/hello-service" , String:: class .java)
assertNotNull(result)
assertEquals(result?.statusCode, HttpStatus.OK)
assertEquals(result?.body, "hello service" )
}
|
最后,我们来看看一个POJO在Kotlin中的样子。
6、Kotlin的数据类
在Java中,我们使用POJO来表示数据对象。在Kotlin中,可以更简洁地表达这种类型的对象——一个数据类。
我们写一个数据对象返回到控制器中:
1
|
data class HelloDto(val greeting: String)
|
这里没有什么窍门,自动省略。使用data修饰符,可以获得很多好处。此关键字会自动创建一个equals()方法和hashcode()方法,以及toString()方法和copy()方法。所有这些方法一个修饰符就搞定了。
现在我们来添加一个返回新数据类的方法:
1
2
3
4
5
|
// ...
@GetMapping ( "/hello-dto" )
fun helloDto(): HelloDto {
return HelloDto( "Hello from the dto" )
}
|
数据修饰符不添加默认构造函数,这对于像Jackson这样的库很重要。为了支持这种类型的类,我们将jackson-module-kotlin添加到我们的POM文件中以支持编组。
最后,我们添加一个这个控制器功能的测试:
1
2
3
4
5
6
7
8
9
10
|
@Test
fun whenCalled_shoudlReturnJSON() {
val result = testRestTemplate
// ...
.getForEntity( "/hello-dto" , HelloDto:: class .java)
assertNotNull(result)
assertEquals(result?.statusCode, HttpStatus.OK)
assertEquals(result?.body, HelloDto( "Hello from the dto" ))
}
|
三、结论
在本文中,结合Spring Boot 2.x和Kotlin语言,我们完成了一个Demo应用。从示例中可以看到,Kotlin可以通过强制来精简代码,保证更安全的代码来简化和增强我们的应用程序。
Kotlin还支持一些惊人的功能,如数据类、类扩展,并与现有的Java代码完全兼容。这意味着开发者可以编写Kotlin代码,并从Java类中调用它,反之亦然。此外,Kotlin是从一开始就建立起来的,在IDE中能得到非常好的支持。
Google和Spring都开始支持Kotlin语言,或许使用Kotlin的时候到了。
以上所述是小编给大家介绍的关于Spring Boot和Kotlin的联合开发,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对服务器之家网站的支持!