有用 kotlin 开发后端的老哥吗
目前只敢工具类用 kotlin,不知道 kotlin 和 spring 会不会有兼容上的坑,兼容 spring 各种注解么。 目前发现比较难受的是,数据类(DO, DTO)必须全部用可空,不然 fastjson 反序列化会有问题。 有生产环境用 kotlin 开发的老哥吗,目前有什么问题?
目前只敢工具类用 kotlin,不知道 kotlin 和 spring 会不会有兼容上的坑,兼容 spring 各种注解么。 目前发现比较难受的是,数据类(DO, DTO)必须全部用可空,不然 fastjson 反序列化会有问题。 有生产环境用 kotlin 开发的老哥吗,目前有什么问题?
用 kotlin 可以尝试一下其他东西,比如 quarkus vertx 啥的
1. 同时有 Java 和 Kotlin 的 RestController,Java 的找不到
2. 类型推断好像有点问题
有如下代码:
“`kt
val gridFsFile: GridFSFile? = gridFsTemplate.findOne(Query(Criteria.where(“_id”).`is`(id)))
“`
idea 提示我
“`
‘gridFsFile’ is always non-null type
“`
很明显 gridFsTemplate 是可空的,甚至在接口 GridFsOperations 中已经标注了 @Nullable 。
尝试加入判空逻辑:
“`
if (gridFsFile == null) {
// do something
}
“`
idea 提示:
“`
No method ‘equals(Any?): Boolean’ available
“`
猜想是不是 Kotlin 调用 java 都会有这样问题,结果未能在 demo 项目中复现。
目前用这样的方式判断,原理不明:
“`kt
if (gridFsFile === null) {
// do something
}
“`
Spring 5.0(2017 年) 开始, 除了 Reactive,Kotlin 就是最重要的特性之一,Spring 对 Kotlin 进行深度集成(远超过之差的 Groovy 语言支持)。针对很多 Kotlin 特性很多优化,例如,不必声明 open, data class 可以用于 JPA Entity 等。
Kotlin DSL 声明 beans 定义,安全 (参考 Spring 中 BeanDefinitionDSL )等。
val beans = beans {
bean {
CommandLineRunner {
println(“start data initialization…”)
val posts = ref<PostRepository>()
posts.deleteAll()
.thenMany<Post>(
posts.saveAll(
arrayListOf(
Post(null, “my first post”, “content of my first post”),
Post(null, “my second post”, “content of my second post”)
)
)
)
.log()
.subscribe(
{ println(it) },
{ println(it) },
{ println(“data initialization done…”) }
)
}
}
https://github.com/hantsy/spring-kotlin-dsl-sample/blob/master/reactive/src/main/kotlin/com/example/demo/DemoApplication.kt
现在 Spring 还有一个 Spring Kofu 孵化项目(提供完全 Kotlin DSL )。
val app = reactiveWebApplication {
configurationProperties<SampleProperties>(prefix = “sample”)
enable(dataConfig)
enable(webConfig)
listener<ApplicationReadyEvent> {
println(“start data initialization…”)
ref<PostRepository>().init()
}
profile(“foo”) {
beans { bean<Bar>() }
}
}
https://github.com/hantsy/spring-kotlin-dsl-sample/blob/master/kofu-reactive-mongo/src/main/kotlin/com/example/demo/DemoApplication.kt
话说干嘛要用 fastjson 呢?框架自己序列化反序列化用自带的 jackson 就行了啊,也就稍微配置一下的事
偶尔用 gson 也能搞定
Pros: the language, spring/spring boot, Func Programming, even coroutines & kotlin ReactiveX 这些都用过,没碰到过什么大坑
Cons: Kotlin 的强类型模式,在某些时候会不爽,比如对外接口。Data object 认为 String 就是 String , Int 就是 Int 。但是有可能对端实现变更或者多接一个调用方,应该传 “1” 的变成了 1,kotlin (看具体实现方式)就有可能报错。这种时候,最怀念 Groovy 或者 Ruby,你认为它是 Int 它就是 int,认为它是 string 它就是 string.
BTW:json 可以考虑使用 moshi 或者 jackson json
如果你用的是 Spring, 写的是 Web API 之类,还在用手动序列化,你的代码估计我看到要吐血。
手动序列化工具太多了。我觉得 JSONB 标准最简单。https://github.com/hantsy/cargotracker-regapp/blob/master/src/main/java/org/eclipse/cargotrakcer/regapp/client/internal/HttpClientHandlingReportService.java#L64
只有在一些没有框架支持的情况我才会用到手动序列化,比如上面的 Client 。
vertx 感觉没那么爽啊,
https://github.com/hantsy/vertx-sandbox/blob/master/kotlin-co/src/main/kotlin/com/example/demo/MainVerticle.kt#L103
这种,没有内部 API 支持吗?这个我实在不清楚。
关于 Jackson 的配置,没有一些接口(方法)暴露出来 , 太不灵活了,我提过 issue,官方回复就是这样的。
https://github.com/hantsy/vertx-sandbox/blob/master/kotlin-co/src/main/kotlin/com/example/demo/MainVerticle.kt#L42
写过 Kotlin 后,现在回到 Java, 我也比较喜欢 Constructor Injection ( Spring 4 支持自动注入依赖,如果类只有唯一 历非空参数 constructor ),结合 Lombok,直接声明成 final,使用 @RequiredArg 。。。,省掉了 constructor 。
另外 Dto (这个模式本来就是用于不可变的场景),也开始习惯了 of factory 方法构建,变成意义上的不可变。
而且因为 fastjson 的漏洞我们几个月之类升级了三次版本,每次几十个微服务都需要升级简直不要太酸爽。可能很多创业公司不会太在意安全问题,等招牌大了分分钟被搞事情。