今日咱们尝试Spring Boot整合Kotlin,并决议建立一个十分简略的Spring Boot微服务,运用Kotlin作为编程语言进行编码构建。

创立一个简略的Spring Boot运用程序。我会在这里运用maven构建项目:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.edurt.ski</groupId>
    <artifactId>springboot-kotlin-integration</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>
    <name>springboot kotlin integration</name>
    <description>SpringBoot Kotlin Integration is a open source springboot, kotlin integration example.</description>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <!-- plugin config -->
        <plugin.maven.kotlin.version>1.2.71</plugin.maven.kotlin.version>
    </properties>
    <dependencies>
        <!-- spring boot -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- kotlin -->
        <dependency>
            <groupId>com.fasterxml.jackson.module</groupId>
            <artifactId>jackson-module-kotlin</artifactId>
        </dependency>
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-stdlib-jdk8</artifactId>
        </dependency>
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-reflect</artifactId>
        </dependency>
    </dependencies>
    <build>
        <sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
        <testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <artifactId>kotlin-maven-plugin</artifactId>
                <groupId>org.jetbrains.kotlin</groupId>
                <configuration>
                    <args>
                        <arg>-Xjsr305=strict</arg>
                    </args>
                    <compilerPlugins>
                        <plugin>spring</plugin>
                        <plugin>jpa</plugin>
                        <plugin>all-open</plugin>
                    </compilerPlugins>
                    <pluginOptions>
                        <option>all-open:annotation=javax.persistence.Entity</option>
                    </pluginOptions>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>org.jetbrains.kotlin</groupId>
                        <artifactId>kotlin-maven-allopen</artifactId>
                        <version>${plugin.maven.kotlin.version}</version>
                    </dependency>
                    <dependency>
                        <groupId>org.jetbrains.kotlin</groupId>
                        <artifactId>kotlin-maven-noarg</artifactId>
                        <version>${plugin.maven.kotlin.version}</version>
                    </dependency>
                </dependencies>
                <executions>
                    <execution>
                        <id>kapt</id>
                        <goals>
                            <goal>kapt</goal>
                        </goals>
                        <configuration>
                            <sourceDirs>
                                <sourceDir>src/main/kotlin</sourceDir>
                            </sourceDirs>
                            <annotationProcessorPaths>
                                <annotationProcessorPath>
                                    <groupId>org.springframework.boot</groupId>
                                    <artifactId>spring-boot-configuration-processor</artifactId>
                                    <version>${project.parent.version}</version>
                                </annotationProcessorPath>
                            </annotationProcessorPaths>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

添加所有必需的依靠项:

  • kotlin-stdlib-jdk8 kotlin jdk8的lib包
  • kotlin-reflect kotlin反射包

一个简略的运用类:

package com.edurt.ski
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
@SpringBootApplication
class SpringBootKotlinIntegration
fun main(args: Array<String>) {
    runApplication<SpringBootKotlinIntegration>(*args)
}

添加Rest API接口功用


创立一个HelloController Rest API接口,咱们只提供一个简略的get恳求获取hello,kotlin输出信息:

package com.edurt.ski.controller
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController
@RestController
class HelloController {
    @GetMapping(value = "hello")
    fun hello(): String {
        return "hello,kotlin"
    }
}

修正SpringBootKotlinIntegration文件添加以下设置扫描路径

@ComponentScan(value = [
    "com.edurt.ski",
    "com.edurt.ski.controller"
])

添加页面功用


  • 修正pom.xml文件添加以下页面依靠
<!-- mustache -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mustache</artifactId>
</dependency>
  • src/main/resources路径下创立templates文件夹

  • templates文件夹下创立一个名为hello.mustache的页面文件

<h1>Hello, Kotlin</h1>
  • 创立页面转换器HelloView
package com.edurt.ski.view
import org.springframework.stereotype.Controller
import org.springframework.ui.Model
import org.springframework.web.bind.annotation.GetMapping
@Controller
class HelloView {
    @GetMapping(value = "hello_view")
    fun helloView(model: Model): String {
        return "hello"
    }
}
  • 浏览器拜访http://localhost:8080/hello_view即可看到页面内容

添加数据持久化功用


  • 修正pom.xml文件添加以下依靠(由于测验功用咱们运用h2内存数据库)
<!-- data jpa and db -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>runtime</scope>
</dependency>
  • 创立User实体
package com.edurt.ski.model
import javax.persistence.Entity
import javax.persistence.GeneratedValue
import javax.persistence.Id
@Entity
//class UserModel(
//        @Id
//        @GeneratedValue
//        private var id: Long? = 0,
//        private var name: String
//)
class UserModel {
        @Id
        @GeneratedValue
        var id: Long? = 0
                get() = field
                set
        var name: String? = null
                get() = field
                set
}
  • 创立UserSupport dao数据库操作工具类
package com.edurt.ski.support
import com.edurt.ski.model.UserModel
import org.springframework.data.repository.PagingAndSortingRepository
interface UserSupport : PagingAndSortingRepository<UserModel, Long> {
}
  • 创立UserService服务类
package com.edurt.ski.service
import com.edurt.ski.model.UserModel
interface UserService {
    /**
     * save model to db
     */
    fun save(model: UserModel): UserModel
}
  • 创立UserServiceImpl完成类
package com.edurt.ski.service
import com.edurt.ski.model.UserModel
import com.edurt.ski.support.UserSupport
import org.springframework.stereotype.Service
@Service(value = "userService")
class UserServiceImpl(private val userSupport: UserSupport) : UserService {
    override fun save(model: UserModel): UserModel {
        return this.userSupport.save(model)
    }
}
  • 创立用户UserController进行持久化数据
package com.edurt.ski.controller
import com.edurt.ski.model.UserModel
import com.edurt.ski.service.UserService
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
@RestController
@RequestMapping(value = "user")
class UserController(private val userService: UserService) {
    @PostMapping(value = "save/{name}")
    fun save(@PathVariable name: String): UserModel {
        val userModel = UserModel()
//        userModel.id = 1
        userModel.name = name
        return this.userService.save(userModel)
    }
}
  • 运用控制台窗口履行以下指令保存数据
curl -X POST http://localhost:8080/user/save/qianmoQ

收到回来结果

{"id":1,"name":"qianmoQ"}

表明数据保存成功

添加数据读取烘托功用


  • 修正UserService添加以下代码
/**
 * get all model
 */
fun getAll(page: Pageable): Page<UserModel>
  • 修正UserServiceImpl添加以下代码
override fun getAll(page: Pageable): Page<UserModel> {
    return this.userSupport.findAll(page)
}
  • 修正UserController添加以下代码
@GetMapping(value = "list")
fun get(): Page<UserModel> = this.userService.getAll(PageRequest(0, 10))
  • 创立UserView文件烘托User数据
package com.edurt.ski.view
import com.edurt.ski.service.UserService
import org.springframework.data.domain.PageRequest
import org.springframework.stereotype.Controller
import org.springframework.ui.Model
import org.springframework.ui.set
import org.springframework.web.bind.annotation.GetMapping
@Controller
class UserView(private val userService: UserService) {
    @GetMapping(value = "user_view")
    fun helloView(model: Model): String {
        model["users"] = this.userService.getAll(PageRequest(0, 10))
        return "user"
    }
}
  • 创立user.mustache文件烘托数据(自行解析回来数据即可)
{{users}}
  • 浏览器拜访http://localhost:8080/user_view即可看到页面内容

添加单元功用


  • 修正pom.xml文件添加以下依靠
<!-- test -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <scope>test</scope>
</dependency>
  • 创立UserServiceTest文件进行测验UserService功用
package com.edurt.ski
import com.edurt.ski.service.UserService
import org.junit.jupiter.api.AfterAll
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.data.domain.PageRequest
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class UserServiceTest(@Autowired private val userService: UserService) {
    @Test
    fun `get all`() {
        println(">> Assert blog page title, content and status code")
        val entity = this.userService.getAll(PageRequest(0, 1))
        print(entity.totalPages)
    }
}

源码地址:GitHub