使用 Kotlin+SpringBoot 进行 web 开发

2,735 阅读4分钟

Kotlin已经发布1.1.0版本了,玩过后已经被其先进的语法深深迷恋。这里不再陈述Kotlin的强大,只说明一下如何与SpringBoot进行集成开发。

Demo地址:github.com/gefangshuai…

第一步:获取项目脚手架

移步start.spring.io定制下载项目基本雏形,我的配置如下:


基本

下载下来后,在Idea中导入,并建立基本的目录结构,如下:


Paste_Image.png

环境准备

加入jsp支持

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <scope>provided</scope>
</dependency>

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
</dependency>
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
    <scope>provided</scope>
</dependency>

加入postgresql数据库支持

<dependency>
    <groupId>postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <version>9.3-1102.jdbc41</version>
</dependency>

加入开发者工具

用于自动部署

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <optional>true</optional>
</dependency>

开启视图及jpa支持

修改application.properties文件,配置如下:

server.port=8082

spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp

spring.devtools.restart.exclude=static/**,public/**

# database
spring.datasource.url= jdbc:postgresql://localhost:5432/test
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.testWhileIdle = true
spring.datasource.validationQuery = SELECT 1

# jpa+hibernate
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQL9Dialect
spring.jpa.hibernate.ddl-auto=update
spring.jpa.open-in-view=true
spring.jpa.show-sql = true

至此,项目环境准备完毕。

业务开发

下面我们来进行简单的业务开发。

构造Model类

假设我们要维护一个客户信息,客户包含两个信息“firstName”和“lastName”。model类如下:

@Entity
@Table(name = "customer")
data class Customer (
        @Id @GeneratedValue(strategy = GenerationType.AUTO) var id: Int?,
        var firstName: String?,
        var lastName: String?
        ){
    constructor() : this(null, null, null)  // Spring 需要
}

这里我们用到了kotlin的数据类,因为通常我们的model类只是用来保存数据,很少做业务操作,而用数据类的好处是:可以自动帮我们生成equals()hashCode()toString()componentN()
函数
,并具有强大的copy()功能。
参见:kotlin-zhcn.github.io/docs/refere…

这里需要注意

  1. 在 JVM 中,如果生成的类需要含有一个无参的构造函数,则所有的属性必须指定默认值。 (参见构造函数)。

    data class User(val name: String = "", val age: Int = 0)

    因为Spring在进行对象绑定的时候,需要model类具有无参构造,所以此处我们声明的Customer类必须指定构造参数默认值。否则Spring进行对象绑定会报错!!!

  2. 由于Spring依赖注入需要默认无参构造,所以我们需要为其创建一个默认无参的构造函数

    constructor() : this(null, null, null)

    当然,为了解决这个比较鸡肋的问题,Kotlin还是为我们提供了工具支持。这里只说一下Maven的配置方法:
    加入依赖:

    <dependency>
       <groupId>org.jetbrains.kotlin</groupId>
       <artifactId>kotlin-maven-noarg</artifactId>
       <version>${kotlin.version}</version>
    </dependency>

    开启对jpa的支持:


    Paste_Image.png

这样我们写model类就不需要主动实现空构造了,编译器会帮我们实现

@Entity
@Table(name = "customer")
data class Customer (
        @Id @GeneratedValue(strategy = GenerationType.AUTO)
        var id: Int?,
        var firstName: String?,
        var lastName: String?
        ): Serializable{
//    constructor() : this(null, null, null)  // Spring 需要
}

准备Dao类

interface CustomerRepository : CrudRepository<Customer, Long> {
    fun findByLastName(lastName: String): MutableIterable<Customer>

}

这里可以看到,Kotlin与Java语法上的区别,用法其实是一样的!

编写Service类

@Service
@Transactional(readOnly = true)
class CustomerService {
    @Autowired
    lateinit var customerReposity: CustomerRepository

    @Transactional
    fun save(customer: Customer) = customerReposity.save(customer)

    fun findAll(): MutableIterable<Customer>? = customerReposity.findAll();

}

CustomerController类

@Controller
@RequestMapping("/customer")
class CustomerController {
    @Autowired
    lateinit var customerService: CustomerService

    @RequestMapping("/add")
    fun addForm(): String = "form"

    @RequestMapping(value = "save", method = arrayOf(RequestMethod.POST))
    fun saveCustomer(customer: Customer): String {
        customerService.save(customer)

        return "redirect:/"
    }
}

注意:Controller中我们注入Service用到Kotlin的属性懒加载机制

lateinit var customerService: CustomerService

因为Spring会帮我们实例化Service及其他Bean。
其他也是语法上的区别,不了解的可以自行补脑。

视图页面不再介绍,大家可以将项目下载下来看具体代码:github.com/gefangshuai…

运行示例

启动Maven配置如下:


Maven配置

运行后,会看到首页


首页

点击添加,跳转到添加表单页:


表单

提交表单,会刷新首页,出现我们添加的信息


列表

总结

附源码地址: SpringBoot Kotlin Demo

好了,至此一个简单的Kotlin+SpringBoot Demo已开发完成,大家可以以此项目为基本雏形,进行更深入的业务扩展。
总之,Kotlin带来的不仅仅是开发效率上的提高,其100% interoperable with Java™的原则弥补了Java很多的不足,绝对是一门值得学习并使用的新型语言。

看看大家的评价吧:
知乎-如何评价Kotlin语言
知乎-如何评价kotlin1.1正式发布?
说一个笑话:
有了val, 在也不用纠结 static final 和 final static 了。 :-)