使用 Kotlin 协程时未初始化 Vertx 实例

Vertx Instance not initialized when using Kotlin Coroutines

我正在尝试使用 Vert.x CoroutineVerticle 编写 HTTP 服务器,但出现错误 lateinit property vertxInstance has not been initialized。似乎在部署 Verticle 时未调用 CoroutineVerticleinit(...) 函数。

package http

import io.vertx.core.DeploymentOptions
import io.vertx.core.Vertx
import io.vertx.ext.web.Router
import io.vertx.kotlin.core.http.listenAwait
import io.vertx.kotlin.coroutines.CoroutineVerticle

class CoTest : CoroutineVerticle() {
    private var router = createRouter()

    override suspend fun start() {

        vertx.createHttpServer()
            .requestHandler(router)
            .listenAwait(config.getInteger("http.port", 8182))
    }

    private fun createRouter() = Router.router(vertx).apply {
        get("/favicon.ico").handler { req ->
            req.response().end("NO")
        }
    }
}
fun main() {    
    class V : ServerVertxCo(8182) {}
    Vertx.vertx().deployVerticle(CoTest::class.java.canonicalName)
}

问题是您在 class 中做事的顺序。

顶点的顺序是:

  1. 创建顶点实例
  2. 部署verticle
  3. Verticle class 构造函数被调用(vertx 还没有“注入”到它)
  4. Vertx 进行一些内部初始化
  5. Vertx 调用 Verticle 的 start 函数

您在 class 中使用 private var router = createRouter()(在 start 块之外),此时 vertx 尚未“注入”到 class 所以你得到一个例外。

如果您将它移动到 start 块,它应该会按您预期的那样工作:

class CoTest : CoroutineVerticle() {

  override suspend fun start() {
    val router = createRouter()

    vertx.createHttpServer()
      .requestHandler(router)
      .listenAwait(config.getInteger("http.port", 8182))
  }

  private fun createRouter() = Router.router(vertx).apply {
    get("/favicon.ico").handler { req ->
      req.response().end("NO")
    }
  }
}

suspend fun main() {
  val vertx = Vertx.vertx()
  vertx.deployVerticleAwait(CoTest::class.java.canonicalName)
}