在开发过程中,快速反馈循环周期非常重要。 通常,重新启动服务器可能需要一些时间,因此Ktor提供了一个基本的自动重载工具,可以重新加载Application类。
注:自动重载不支持java 9,如果要使用该功能则需要使用JDK8;
类改变时自动重新加载
在这两种情况下,使用embeddedServer或配置文件时,您必须提供一个与您要监视的类加载器相匹配的监视子字符串列表。
例如,使用gradle时的典型类加载器如下所示:
/Users/user/projects/ktor-exercises/solutions/exercise4/build/classes/kotlin/main
复制代码
在这种情况下,您可以使用solutions/exercise4字符串或者仅使用exercise4字符串,它将匹配该类加载器。
使用embeddedServer
使用自定义主服务器和embeddedServer时,可以使用可选参数watchPaths提供将被监视和重新加载的子路径列表。
fun main(args: Array<String>) {
embeddedServer(
Netty,
watchPaths = listOf("solutions/exercise4"),
port = 8080,
module = Application::mymodule
).apply { start(wait = true) }
}
fun Application.mymodule() {
routing {
get("/plain") {
call.respondText("Hello World!")
}
}
}
复制代码
通过application.conf配置
使用配置文件时,例如使用EngineMain从命令行运行或托管在服务器容器中:要启用此功能,请将watch的key添加到ktor.deployment配置。
watch - 应该监视并自动重新加载的类路径条目的数组。
ktor {
deployment {
port = 8080
watch = [ module1, module2 ]
}
…
}
复制代码
现在,watch键只是与contains相匹配的字符串,与加载的应用程序中的类路径条目相对应,例如jar名称或项目目录名称。 然后使用特殊的ClassLoader加载这些类,该类在检测到更改时被回收。
注:类路径条目看起来像file:/path/to/project/build/classes/myproject.jar,所以/ project会匹配,但com.mydomain不会。
在源代码更改时自动重新编译
由于自动重载功能仅检测类文件中的更改,因此您必须自己编译应用程序。 你可以在运行时使用IntelliJ IDEA和Build - > Build Project来实现。
但是,您也可以使用gradle自动检测源更改并为您编译。 您只需在项目文件夹中打开另一个终端并运行:gradle -t build。 它将编译应用程序,在执行此操作后,它将侦听其他源更改并在必要时重新编译。 因此,触发自动类重新加载。 然后,您可以使用另一个终端以gradle run运行应用程序。
例子
您可以使用build.gradle或直接在IDE中运行应用程序。 执行示例文件中的main方法,或执行:io.ktor.server.netty.EngineMain.main。 使用commandLineEnvironment的EngineMain将负责加载application.conf文件(即HOCON格式)。
main.kt
package io.ktor.exercise.autoreload
import io.ktor.application.*
import io.ktor.http.*
import io.ktor.response.*
import io.ktor.routing.*
import io.ktor.server.engine.*
import io.ktor.server.netty.*
// Exposed as: `static void io.ktor.exercise.autoreload.MainKt.main(String[] args)`
fun main(args: Array<String>) {
//io.ktor.server.netty.main(args) // Manually using Netty's EngineMain
embeddedServer(
Netty, watchPaths = listOf("solutions/exercise4"), port = 8080,
module = Application::module
).apply { start(wait = true)
}
// Exposed as: `static void io.ktor.exercise.autoreload.MainKt.module(Application receiver)`
fun Application.module() {
routing {
get("/plain") {
call.respondText("Hello World!")
}
}
}
复制代码
application.conf
ktor {
deployment {
port = 8080
watch = [ solutions/exercise4 ]
}
application {
modules = [ io.ktor.exercise.autoreload.MainKt.module ]
}
}
复制代码