Kotlin เป็นสำนวนในการรับ Logger คืออะไร [ทำซ้ำ]

ฉันกำลังมองหาที่จะแทนที่

private static final Logger log = Logger.getLogger(MyClass.class);

ด้วยสิ่งที่ละเอียดน้อยกว่าเล็กน้อยและมีสำนวนมากกว่า

class MyClass {
    companion object {
        val log = LoggerFactory.getLogger(MyClass::class.java)
    }

    fun usage() {
        log.debug("Success")
    }
}

คะแนนโบนัสไม่ต้องดูแลในทุกคลาส

ฉันเหนื่อย:

interface HasLogger {
    val log: Logger
        get() = LoggerFactory.getLogger(this.javaClass)
}

แต่ผลลัพธ์นี้ทำให้เกิดการเรียก getLogger() สำหรับทุกการใช้งาน (ยอมรับไม่ได้) และยังส่งคืนตัวบันทึกสำหรับประเภทย่อยด้วย (ไม่ใช่ประเภทที่ถูกประกาศ)


person atok    schedule 08.06.2016    source แหล่งที่มา
comment
ดู lib นี้: github.com/MicroUtils/kotlin.logging   -  person oshai    schedule 14.07.2016


คำตอบ (2)


คุณสามารถสร้างวิธีการอรรถประโยชน์ได้เช่น

inline fun <reified T:Any> loggerFor() = LoggerFactory.getLogger(T::class.java)

และเพียงแค่ใช้มันเหมือน

class MyClass {
    companion object {
        val log = loggerFor<MyClass>()
    }

    fun usage() {
        log.debug("Success")
    }
}

หรือคุณสามารถใช้ตัวบันทึกส่วนตัวระดับไฟล์ซึ่งช่วยให้คุณประหยัดการพิมพ์ซึ่งดูเหมือนว่าจะเป็นทางออกที่ดีเมื่อคุณไม่มีหลายคลาสที่มีตัวบันทึกของตัวเองกำหนดไว้ต่อไฟล์:

private val log = loggerFor<MyClass>()

class MyClass {
    fun usage() {
        log.debug("Success")
    }
}
person M Platvoet    schedule 08.06.2016
comment
นี่ยังน้อยไปสำหรับรสนิยมของฉัน แต่ดูเหมือนว่าจะสามารถทำงานได้โดยไม่ต้องใช้ ‹MyClass› โดยใช้ LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()) - person atok; 08.06.2016

ขั้นแรก คุณสามารถเพิ่มฟังก์ชันส่วนขยายสำหรับการสร้างตัวบันทึกได้

inline fun <reified T : Any> getLogger() = LoggerFactory.getLogger(T::class.java)
fun <T : Any> T.getLogger() = LoggerFactory.getLogger(javaClass)

จากนั้นคุณจะสามารถสร้างตัวบันทึกโดยใช้โค้ดต่อไปนี้

private val logger1 = getLogger<SomeClass>()
private val logger2 = getLogger()

ประการที่สอง คุณสามารถกำหนดอินเทอร์เฟซที่จัดให้มีตัวบันทึกและการใช้งานมิกซ์อิน

interface LoggerAware {
  val logger: Logger
}

class LoggerAwareMixin(containerClass: Class<*>) : LoggerAware {
  override val logger: Logger = LoggerFactory.getLogger(containerClass)
}

inline fun <reified T : Any> loggerAware() = LoggerAwareMixin(T::class.java)

อินเทอร์เฟซนี้สามารถใช้ได้ในลักษณะดังต่อไปนี้

class SomeClass : LoggerAware by loggerAware<SomeClass>() {
  // Now you can use a logger here.
}
person Michael    schedule 08.06.2016
comment
ว้าว! เจ๋งเลย! คุณยังสามารถแทนที่ reified T ด้วย MethodHandles.lookup().lookupClass() และรับผลลัพธ์เดียวกันโดยไม่ต้องสะกด SomeClass เป็นครั้งที่สอง: inline fun loggerAware() = HasLoggerMixin(MethodHandles.lookup().lookupClass()) - person atok; 08.06.2016
comment
@atok ใช่ดูเหมือนว่าคุณจะทำได้ - person Michael; 08.06.2016
comment
ขอบคุณ ฉันคิดว่าคุณควรโพสต์สิ่งนี้ในคำถามนี้: stackoverflow.com/questions/34416869/ เพราะมันดีกว่าผลลัพธ์ - person atok; 08.06.2016