KotlinKtor Singleton在开发模式下不工作(启用自动重新加载)

ryoqjall  于 2023-01-05  发布在  Kotlin
关注(0)|答案(1)|浏览(120)

我在Kotlin(Ktor框架)中遇到了一个破碎单例的问题。
问题特别是Ktor Development mode。当它被禁用时,一切都正常工作...
这两个调用打印出不同的示例!我很惊讶没有发现任何其他人提到这个问题..这是无用的!
有人有同样的问题吗?

# Application.kt

object Singleton {
    fun printInstanceId() {
        println("--> This is Singleton ${toString()}")
    }
}

fun main() {
    Singleton.printInstanceId() # <-- instance com.mallgroup.Singleton@27c170f0

    embeddedServer(Netty,port = 8080,module = Application::bootstrap).start(wait = true)
}

fun Application.bootstrap() {
    Singleton.printInstanceId() # <-- there is another instance!!! com.mallgroup.Singleton@18cebaa5

终端输出

❯ sh gradlew run

> Configure project :
Environment: development , isDevelopment: true

> Task :compileKotlin
'compileJava' task (current target is 19) and 'compileKotlin' task (current target is 1.8) jvm target compatibility should be set to the same Java version.
By default will become an error since Gradle 8.0+! Read more: https://kotl.in/gradle/jvm/target-validation
Consider using JVM toolchain: https://kotl.in/gradle/jvm/toolchain

> Task :run
!!! This is Singleton com.mallgroup.Singleton@27c170f0
...
2023-01-04 15:28:53.352 [main] DEBUG ktor.application - Java Home: /Users/whipstercz/Library/Java/JavaVirtualMachines/openjdk-19.0.1/Contents
2023-01-04 15:28:53.354 [main] DEBUG ktor.application - Class Loader: jdk.internal.loader.ClassLoaders$AppClassLoader@5b37e0d2: [...]
2023-01-04 15:28:53.370 [main] DEBUG ktor.application - Watching /Users/whipstercz/Desktop/mal/ktor-autoreload/build/classes/kotlin/main/com/mallgroup/plugins for changes.
...
!!! This is Singleton com.mallgroup.Singleton@18cebaa5
2023-01-04 15:28:53.897 [main] INFO  ktor.application - Application started in 0.715 seconds.
2023-01-04 15:28:54.086 [main] INFO  ktor.application - Responding at http://0.0.0.0:8080

这怎么可能是两个不同的例子呢?
我已经尝试了甚至不同的实现单例与相同的结果。

class Singleton private constructor() {
    companion object {
        @Volatile
        private lateinit var instance: Singleton
        fun getInstance(): Singleton {
            synchronized(this) {
                if (!::instance.isInitialized) {
                    instance = Singleton()
                }
                return instance
            }
        }
    }

    fun printInstanceId() {
        println("This is Singleton ${toString()}")
    }
}
hlswsv35

hlswsv351#

Ktor的Auto Reloading在每次修改类文件时都会通过类加载器加载类的新版本。由于object是通过静态初始化器(在加载类时执行)分配静态属性的类实现的,所以每次重载后都会得到一个新的对象示例。KTOR-4843是相关的问题。

相关问题