Каков идиоматический способ 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() для каждого использования (недопустимо) также возвращает регистратор для подтипа (а не того, где он был объявлен).
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")
}
}
Во-первых, вы можете добавить функции расширения для создания регистратора.
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.
}