使用kotlin開(kāi)發(fā)最新版的spring boot應(yīng)用 | SpringBoot實(shí)踐

kotlin是由IntelliJ IDEA的開(kāi)發(fā)商Jetbrain推出的一種基于JVM的開(kāi)發(fā)語(yǔ)言,目標(biāo)是簡(jiǎn)化Java中很多繁瑣的設(shè)計(jì),可以和Java無(wú)縫的集成,之前一直在單元測(cè)試的時(shí)候試著使用,最近正好由契機(jī),試著用來(lái)寫(xiě)一下Spring Boot腳手架。

官方定義: Statically typed programming language for the JVM, Android and the browser

項(xiàng)目介紹

長(zhǎng)期目標(biāo)是使用kotlin開(kāi)發(fā)一個(gè)完整的spring boot應(yīng)用,目前搭建了最小量的腳手架。

在本次實(shí)踐中增加了gradle docker插件的使用,使用gradle一站式的完成從開(kāi)發(fā)、測(cè)試、打包到發(fā)布docker鏡像的整個(gè)過(guò)程。

項(xiàng)目結(jié)構(gòu)

structure
SpringBootKotlon
│
├─── build.gradle
└─── src
     ├───main
     │   ├─── docker
     │   ├─── java
     │   ├─── kotlin
     │   └─── resources
     │        └─── config/application.properties
     └───test
          ├─── java
          ├─── kotlin
          └─── resources

在main目錄的java、kotlin、resources下面,包名是一樣的。也就是說(shuō)在kotlin/com/app和java/com/app下的類(lèi),在classpath引用的時(shí)候是同一個(gè)包。

創(chuàng)建Spring Boot項(xiàng)目

Spring Boot項(xiàng)目的創(chuàng)建,可以參考《用Gradle和SpringBoot實(shí)現(xiàn)簡(jiǎn)單的RESTful框架應(yīng)用》。

為了支持kotlin本項(xiàng)目的build.gradle中需要增加kotlin的支持,并且配置docker插件。

buildscript {
    ext.kotlin_version = '1.1.0'
    ext.spting_boot_version = '1.5.2.RELEASE'

    ... ...

    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath("org.springframework.boot:spring-boot-gradle-plugin:$spting_boot_version")
    }
}

... ...
apply plugin: "kotlin"
apply plugin: 'org.springframework.boot'

dependencies {
    ... ...

    compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"

    testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
    testCompile "org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version"
}

sourceSets{
    main{
        ... ...
        kotlin {srcDir "src/main/kotlin"}
    }
    test{
        ... ...
        kotlin {srcDir "src/test/kotlin"}
    }
}

配置完之后,運(yùn)行gradle idea,下載相應(yīng)的gradle依賴(lài)包。在repositories中使用國(guó)內(nèi)鏡像和自建的本地nexus,可以加快依賴(lài)包的下載速度maven{ url 'http://maven.aliyun.com/nexus/content/groups/public/'}

配置sourceSets增加kotlin的包之后,可以自己創(chuàng)建一個(gè)gradle task,自動(dòng)創(chuàng)建sourceSets對(duì)應(yīng)的目錄;gradle createJavaProject會(huì)根據(jù)sourceSets中配置的路徑,創(chuàng)建指定set對(duì)應(yīng)的目錄。

task createJavaProject << {
    sourceSets*.java.srcDirs*.each { it.mkdirs() }
    sourceSets*.kotlin.srcDirs*.each { it.mkdirs() }
    sourceSets*.resources.srcDirs*.each { it.mkdirs()}
}

運(yùn)行spring boot程序

項(xiàng)目的application入口類(lèi),使用kotlin語(yǔ)言實(shí)現(xiàn),在kotlin中是沒(méi)有靜態(tài)方法的,所以如果要實(shí)現(xiàn)main函數(shù),有兩種方法,一種是將main函數(shù)寫(xiě)在class的外面;或者使用companion object {},將需要靜態(tài)調(diào)用的方法寫(xiě)在{}中。

@SpringBootApplication
open class SpringBootKotlinApplication

fun main(args: Array<String>){
    SpringApplication.run(SpringBootKotlinApplication::class.java,*args)
}

相比spring mvc,spring boot給人最大的感觸就是,用簡(jiǎn)單的注解和application.properties配置的方式,避免了spring mvc中繁瑣而且容易出錯(cuò)的xml配置文件,極大的簡(jiǎn)化了spring boot的配置。值得一提的是,application配置文件,也可以使用yaml文件。

application配置文件說(shuō)明

端口

通過(guò)在配置文件中設(shè)置server.port屬性,可以指定spring boot運(yùn)行時(shí)綁定的端口。

freemarker

spring.freemarker.*是spring boot提供的freemarker相關(guān)配置,可以配置的屬性,和注解或者xml文件是一樣的,要使用spring.freemarker配置,需要在gradle中,引入org.springframework.boot:spring-boot-starter-freemarker這個(gè)包。

此外,spring boot的application配置文件,還可以配置包括數(shù)據(jù)庫(kù)在內(nèi)的各種常見(jiàn)第三方工具或者庫(kù),應(yīng)該是將提供了一系列starter包,將注解和配置過(guò)程包裝起來(lái)了。

配置完成之后,就可以在Application類(lèi)的子目錄中編寫(xiě)Spring MVC的控制器代碼。

編寫(xiě)restful controller

一個(gè)最基本的RestController代碼如下:

@RestController
@RequestMapping(value = "/api/data")
class DataController {

    @RequestMapping(value = "",method = arrayOf(RequestMethod.GET,RequestMethod.PUT))
    fun index():Map<String,Any>{
        val resultMap = HashMap<String,Any>()

        resultMap["status"] = true
        resultMap["msg"] = "success"
        return resultMap
    }

    @RequestMapping(value = "show",method = arrayOf(RequestMethod.PUT),consumes = arrayOf(MediaType.APPLICATION_JSON_UTF8_VALUE))
    fun test(@RequestBody reqMap:Map<Any,Any>):Map<Any,Any>{
        return reqMap
    }
}

代碼解讀:

  • kotlin中使用arrayof來(lái)初始化數(shù)組;
  • 對(duì)于不指定類(lèi)型或者Obejct型的變量,kotlin使用Any類(lèi)型
  • method方法中可以指定對(duì)種請(qǐng)求頭,很靈活
  • 在consumes中,可以指定接受的contentType為JSON格式
  • 如果請(qǐng)求是json格式,用ResponseBody就可以接收J(rèn)SON對(duì)象

完成所有代碼之后,運(yùn)行gradle bootRun就可以啟動(dòng)服務(wù)。

curl 'http://localhost:8080/api/data/show'  \
    -X 'PUT'  \
    -H 'content-type: application/json'  \
    -H 'accept: application/json'  \
    --data-binary '{"data":"hello","who":"echo"}' --compressed

測(cè)試spring boot程序

spring boot和kotlin都提供了強(qiáng)大的測(cè)試套件,能夠很好的和JUnit集成,進(jìn)行集成測(cè)試和單元測(cè)試。編寫(xiě)一些基本的集成測(cè)試,檢查接口是否正常。

spring boot starter test集成了JUnit?、Mockito、AssertJ?、Hamcrest?、Spring Test & Spring Boot Test可以方便的開(kāi)始測(cè)試

@RunWith(SpringJUnit4ClassRunner::class)
@WebMvcTest(HomeController::class)
class HomeControllerStandaloneTest {

    @Autowired
    private var mvc: MockMvc? = null

    @Test
    @Throws(Exception::class)
    fun indexTest() {
        mvc!!.perform(MockMvcRequestBuilders.get("/").accept(MediaType.TEXT_HTML))
                .andExpect(status().isOk)
                .andExpect(model().attributeExists("data"))
                .andExpect { content().string(containsString("<title>Spring Boot Kotlin</title>")) }
    }
}

MockMvc可以依賴(lài)注入綁定通過(guò)WebMvcTest注解的HomeController控制器,然后針對(duì)指定的controller模擬請(qǐng)求。andExpect方法,檢查response的header,body是否符合測(cè)試的期望。

源代碼:https://github.com/liuwill-projects/SpringBootKotlin

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容