日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Kotlin+SpringBoot服務(wù)端開發(fā)

Kotlin是什么?

創(chuàng)新互聯(lián)于2013年成立,先為五指山等服務(wù)建站,五指山等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為五指山企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。

著名IDE廠商JetBrains開發(fā)的基于JVM的靜態(tài)類型編程語言,聲稱100% interoperable with Java。Kotlin是由工程師設(shè)計(jì)的,各種細(xì)節(jié)設(shè)計(jì)非常切合工程師的需要。語法近似Java和Scala,且已活躍在Android開發(fā)領(lǐng)域,被譽(yù)為Android平臺(tái)的Swift。

Kotlin能與Java混合使用,并且直接復(fù)用Java的生態(tài)系統(tǒng)(庫、框架、工具)。一個(gè)已有的Java項(xiàng)目,只需引用Kotlin的Maven/Gradle插件,以及引用Kotlin標(biāo)準(zhǔn)庫的依賴,就可以逐漸摻入Kotlin代碼。你完全可以當(dāng)它是a better Java。

Kotlin的學(xué)習(xí)曲線極其平緩,學(xué)習(xí)量相當(dāng)于一個(gè)框架。有經(jīng)驗(yàn)的程序員閱讀了文檔就能立刻用起來了。不信你看:

  • 原版文檔 http://kotlinlang.org/docs/re...
  • 中文文檔 http://kotlindoc.com

舉幾個(gè)例子來說明Kotlin的優(yōu)點(diǎn)吧,上代碼:

 
 
  1. //句尾不用寫分號(hào)
  2. // 自動(dòng)推導(dǎo)變量類型,無需聲明
  3. val a = "Hello"
  4. // 簡單的println
  5. println(a.length() == 5)
  6. // 不用寫new, 直接調(diào)構(gòu)造函數(shù)
  7. val b = String("Hello")
  8. // 字符串插值
  9. "$a $b" == "Hello Hello"
  10. // if-else是表達(dá)式, 真方便!
  11. // ==相當(dāng)于equals, 再也不怕忘寫equals了!
  12. val oneOrTwo = if (a == "Hello") 1 else 2
  13. // ===相當(dāng)于Java的==
  14. (a === b) == false
  15. // Lambda用{}包起來,若有唯一參數(shù),參數(shù)名默認(rèn)為it
  16. // 集合的函數(shù)式操作, 無需Java 8繁瑣的stream.collect(Collectors.toList())
  17. listOf(-1, 0, 1).map{it + 1}.filter{it > 0}) == listOf(1, 2)
  18. // 用一個(gè)默認(rèn)值給null兜底
  19. val number = getNumberOrNull() ?: 0
  20. // 自動(dòng)關(guān)閉的資源
  21. FileInputStream("MyFile").use { stream -> // 可指定參數(shù)名為stream, 取代默認(rèn)的it
  22.   val firstByte = stream.read()
  23. }
  24. // 可以更簡單,一行
  25. val fileContent = File("MyFile").readText()
  26. // lazy, 延遲初始化
  27. class CPU {
  28.   val cpuCores by lazy { Runtime.getRuntime().availableProcessors() }

Kotlin為厭煩Java而疑慮Scala的人提供了避風(fēng)港,為喜歡Groovy而想要靜態(tài)類型的人提供了避風(fēng)港。啊!生活。

Spring Boot是什么?

Spring Boot是流行的Web快速開發(fā)框架,使基于Spring的開發(fā)更便捷。我們已經(jīng)知道Spring很好用,而Spring Boot的設(shè)計(jì)目標(biāo)是:

  • 為一切Spring開發(fā)提供極速、通用的上手體驗(yàn)
  • 開箱即用,但是當(dāng)默認(rèn)值不適合需求時(shí)不會(huì)妨礙你做改變
  • 提供一組適用于各種項(xiàng)目類型的非功能性特性(如內(nèi)嵌服務(wù)器、安全、度量、健康檢查、外部配置)
  • 完全不需要代碼生成和XML配置

Kotlin + Spring Boot

Kotlin能輕松集成Spring Boot,用Java怎么寫,用Kotlin基本上也怎么寫。

Spring能在線生成項(xiàng)目,免去創(chuàng)建項(xiàng)目的煩惱,請(qǐng)猛擊鏈接http://start.spring.io/ 。

我們用Gradle構(gòu)建,寫一個(gè)build.gradle文件:

 
 
  1. buildscript {
  2.   ext {
  3.     springBootVersion = '1.3.5.RELEASE'
  4.     kotlinVersion = '1.0.4'
  5.   }
  6.   repositories {
  7.     mavenCentral()
  8.   }
  9.   dependencies {
  10.     classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
  11.     classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}")
  12.   }
  13. }
  14. apply plugin: 'kotlin'
  15. apply plugin: 'spring-boot'
  16. jar {
  17.   baseName = 'myapp'
  18.   version = '0.1-SNAPSHOT'
  19. }
  20. sourceCompatibility = 1.8
  21. targetCompatibility = 1.8
  22. // class文件保留參數(shù)名稱
  23. compileJava.options.compilerArgs.add '-parameters'
  24. compileTestJava.options.compilerArgs.add '-parameters'
  25. springBoot {
  26.   mainClass = 'myapp.ApplicationKt'
  27. }
  28. dependencies {
  29.   compile 'org.springframework.boot:spring-boot-starter-aop'
  30.   compile 'org.springframework.boot:spring-boot-starter-web'
  31.   compile "org.jetbrains.kotlin:kotlin-stdlib:${kotlinVersion}"

先寫一個(gè)主類Application.kt,放在src/main/kotlin目錄下(自己想一個(gè)包名哈),來啟動(dòng)整個(gè)應(yīng)用:

 
 
  1. @SpringBootApplication
  2. open class Application {
  3.   @Bean
  4.   open fun json(): MappingJackson2JsonView {
  5.     return MappingJackson2JsonView(ObjectMapper())
  6.   }
  7. }
  8. fun main(args: Array) {
  9.   SpringApplication.run(Application::class.java, *args)

Kotlin的函數(shù)可定義在類外面,而特殊的main函數(shù)要么放在外面,要么放在伴生對(duì)象(companion object)里面。這里就放在外面吧!

你會(huì)發(fā)現(xiàn)class和fun前面有open修飾符,它的意思是非final,Kotlin默認(rèn)一切都是final的,如果不想要final救要加上open。由于Spring有時(shí)要?jiǎng)?chuàng)建代理,要求類和方法不能為final,因此我們每一處都寫上open,以免忘記。

這里只有一個(gè)json()方法,用來在Spring中初始化Jackson,這樣我們就能使用JSON了。

現(xiàn)在來寫一個(gè)RestController,提供RESTful API吧:

 
 
  1. @RestController
  2. @RequestMapping("/api/users")
  3. open class UserApi {
  4.     @RequestMapping("/{id}",  method = arrayOf(RequestMethod.GET))
  5.       open fun get(@PathVariable id: Long) = "User(id=$id, name=admin, password=123)"

好簡單啊!現(xiàn)在,在IDE中運(yùn)行Application.kt文件,就開始運(yùn)行了!用瀏覽器打開http://localhost:8080/api/use...

現(xiàn)在要把數(shù)據(jù)保存到數(shù)據(jù)庫了:

Spring Boot使用JPA非常簡單(照著官網(wǎng)的getting started學(xué)吧),但我要介紹另一種ORM框架——Ebean,它模仿了Rails的Active Record,支持常用的JPA注解。值得一提的是,Ebean的作者也喜歡Kotlin。

需要一個(gè)配置文件src/main/resources/ebean.properties :

 
 
  1. # 是否生成建表SQL
  2. ebean.db.ddl.generate=true
  3. # 是否執(zhí)行建表SQL
  4. ebean.db.ddl.run=false
  5. datasource.db.username=DB用戶名
  6. datasource.db.password=DB密碼
  7. datasource.db.databaseUrl=jdbc:mysql://localhost:3306/你的database名稱
  8. datasource.db.databaseDriver=com.mysql.jdbc.Driver 

我們對(duì)ebean.db.ddl.run(是否執(zhí)行建表SQL)選擇了false。因?yàn)镋bean會(huì)生成建表SQL,我們可以手動(dòng)執(zhí)行,避免每次都重新建表,把數(shù)據(jù)丟棄了。編寫實(shí)體類后再運(yùn)行,SQL會(huì)生成在項(xiàng)目目錄下,手動(dòng)執(zhí)行一下吧!(亦可在***啟動(dòng)前把ebean.db.ddl.run改成true)

然后在Spring中初始化Ebean吧:

 
 
  1. // 把這個(gè)方法添加到Application類
  2.   @Bean(autowire = Autowire.BY_TYPE)
  3.   open fun getEbeanServer(): EbeanServer {
  4.     val config = ServerConfig()
  5.     config.name = "db"
  6.     config.loadFromProperties()
  7.     config.isDefaultServer = true
  8.     return EbeanServerFactory.create(config)
  9.   } 

然后要修改main方法,在Spring之前先執(zhí)行Ebean的agent,改寫實(shí)體類的字節(jié)碼:

 
 
  1. fun main(args: Array) {
  2.   val packageName = "com.iostate.**" // 改成你自己的包名,實(shí)體類要放在這個(gè)包里面
  3.   if (!AgentLoader.loadAgentFromClasspath("avaje-ebeanorm-agent",
  4.                                           "debug=1;packages=$packageName")) {
  5.     System.err.println(
  6.       "avaje-ebeanorm-agent not found in classpath - not dynamically loaded")
  7.   }
  8.   SpringApplication.run(Application::class.java, *args)

Ebean需要執(zhí)行agent來改寫字節(jié)碼(instrumenation),而Hibernate則選擇了給實(shí)體對(duì)象創(chuàng)建動(dòng)態(tài)代理(dynamic proxy),都是為了能對(duì)實(shí)體進(jìn)行AOP操作。

instrumenation使用復(fù)雜,調(diào)試簡單;dynamic proxy使用簡單,調(diào)試復(fù)雜。各有千秋,我更認(rèn)同改寫字節(jié)碼。

編寫實(shí)體類:

 
 
  1. import javax.persistence.*
  2. import com.avaje.ebean.Model
  3. import com.avaje.ebean.annotation.WhenCreated
  4. import com.avaje.ebean.annotation.WhenModified
  5. import java.sql.Timestamp
  6. import com.avaje.ebean.annotation.SoftDelete
  7. import com.fasterxml.jackson.annotation.JsonIgnore
  8. @MappedSuperclass
  9. abstract class BaseModel : Model() {
  10.   @Id @GeneratedValue
  11.   var id: Long = 0
  12.   @Version
  13.   var version: Long = 0
  14.   @WhenCreated
  15.   var whenCreated: Timestamp? = null
  16.   @WhenModified
  17.   var whenModified: Timestamp? = null
  18. }
  19. @Entity
  20. class User (
  21.     var name: String = "",
  22.     @JsonIgnore
  23.     var password: String = ""
  24.     @SoftDelete
  25.     var deleted: Boolean = false
  26. ) : BaseModel() {
  27.   companion object find : Find()

***個(gè)類是所有實(shí)體模型的基類,提供一些通用字段。id是自增主鍵,version是樂觀鎖的標(biāo)志,whenCreated是創(chuàng)建時(shí)間,whenModified是修改時(shí)間。有的變量類型以問號(hào)結(jié)尾,這個(gè)跟Swift語言是一樣的,表示可為null(默認(rèn)是非null的)。

第二類是User,行數(shù)很少,沒有繁瑣的getter/setter。@JsonIgnore的作用是防止敏感字段被泄露到JSON中,@SoftDelete的作用是軟刪除(數(shù)據(jù)不可見,但沒有真的刪除)。companion object find : Find()提供了一組快捷查詢方法,如byId(id)all() 。

現(xiàn)在把UserApi修改如下:

 
 
  1. @RestController
  2. @RequestMapping("/api/users")
  3. open class UserApi {
  4.   @RequestMapping("/{id}",  method = arrayOf(RequestMethod.GET))
  5.   open fun get(@PathVariable id: Long) = User.byId(id)
  6.   @RequestMapping("/new", method = arrayOf(RequestMethod.POST))
  7.   open fun create(@RequestParam name: String, @RequestParam password: String): User {
  8.     return User(name, password).apply {
  9.       save()
  10.     }
  11.   }

get方法真正向數(shù)據(jù)庫做查詢了!增加了create方法來創(chuàng)建用戶!如果想用瀏覽器快速測試,把RequestMethod.POST改成GET,輸入鏈接http://localhost:8080/api/use... 試試!

一個(gè)注意事項(xiàng)

Spring Boot能把程序打包成jar直接運(yùn)行,這是很方便群眾的!但是JSP和Ebean在jar模式都無法工作。

那么在生產(chǎn)環(huán)境要怎么解決呢?可以把jar解壓運(yùn)行!

參考文檔的exploded archives: http://docs.spring.io/spring-...

 
 
  1. # 解壓
  2. unzip -q myapp.jar
  3. # 運(yùn)行
  4. java org.springframework.boot.loader.JarLauncher
  5. # 生產(chǎn)模式用以下的nohup方式,以防程序隨著shell一起關(guān)閉
  6. nohup java org.springframework.boot.loader.JarLauncher & 

我自己用的命令不一樣:

 
 
  1. unzip -q myapp.jar
  2. nohup java -cp '.:./lib/*' com.myapp.ApplicationKt & 

注意當(dāng)前所在的工作目錄,日志目錄/logs會(huì)創(chuàng)建在當(dāng)前工作目錄下。

收工

我提供了一個(gè)示例項(xiàng)目,比較粗糙,請(qǐng)多多包涵 https://github.com/sorra/bms

老外也有幾個(gè)示例項(xiàng)目,可供參考:

Spring Boot Kotlin project with a REST Webservice and Spring Data: https://github.com/sdeleuze/s...

Demo Webapp using SpringBoot, Kotlin and React.js: https://github.com/winterbe/s...

順帶一提,輕境界就是用Kotlin + Spring Boot構(gòu)建的!


本文題目:Kotlin+SpringBoot服務(wù)端開發(fā)
標(biāo)題路徑:http://m.5511xx.com/article/dpiphgi.html