面试题答案
一键面试创建自定义日志记录插件
- 定义插件:
import io.ktor.application.* import io.ktor.http.* import io.ktor.request.* import io.ktor.response.* import io.ktor.routing.* import io.ktor.util.* import java.util.Date class RequestLoggingPlugin(private val logMessage: String) { companion object Feature : ApplicationFeature<Application, RequestLoggingPlugin.Config, RequestLoggingPlugin> { override val key = AttributeKey<RequestLoggingPlugin>("RequestLoggingPlugin") override fun install(pipeline: Application, configure: Config.() -> Unit): RequestLoggingPlugin { val config = Config().apply(configure) val plugin = RequestLoggingPlugin(config.logMessage) pipeline.intercept(ApplicationCallPipeline.Application) { val startTime = Date() call.attributes.put(key, plugin) val requestMethod = call.request.httpMethod.value val requestPath = call.request.uri println("$logMessage - Request received: $requestMethod $requestPath at $startTime") try { proceed() } finally { val endTime = Date() println("$logMessage - Request completed at $endTime. Duration: ${endTime.time - startTime.time} ms") } } return plugin } data class Config { var logMessage: String = "Default Log Message" } } }
- 使用插件:
fun main(args: Array<String>): Unit = io.ktor.server.netty.EngineMain.main(args) @Suppress("unused") // Referenced in application.conf @kotlin.jvm.JvmOverloads fun Application.module(testing: Boolean = false) { install(RequestLoggingPlugin) { logMessage = "My Request Logging" } routing { get("/") { call.respondText("Hello, World!") } } }
插件加载和执行流程解释
- 加载流程:
- 当在
Application
中调用install(RequestLoggingPlugin)
时,install
函数会被执行。 - 首先,
Config
对象被创建并应用传入的配置闭包(这里设置了logMessage
)。 - 然后,
RequestLoggingPlugin
实例被创建,并且通过pipeline.intercept
方法在ApplicationCallPipeline.Application
阶段插入拦截逻辑。 - 最后,
RequestLoggingPlugin
实例被返回并存储在ApplicationCall
的属性中(通过call.attributes.put(key, plugin)
)。
- 当在
- 执行流程:
- 当一个请求到达时,进入
ApplicationCallPipeline.Application
阶段。 - 首先,记录请求开始时间,打印请求的方法、路径等信息。
- 然后,
proceed()
方法被调用,它会继续执行管道中的下一个阶段(比如处理路由等)。 - 当请求处理完成(无论是成功还是异常),会执行
finally
块中的代码,记录请求结束时间和执行时长。
- 当一个请求到达时,进入