1 引言
想必學過Java
的人都知道一個@Slf4j
使用得多麼的舒服:
@Slf4j
public class TestController{
@GetMapping("/test")
public String test(){
log.debug("debug");
return "test";
}
}
但是很不幸在Kotlin
中並沒有這種註解,因此,本文給出了一種類似@Slf4j
註解在Kotlin
中的使用方法,以及介紹一個100%使用Kotlin
編寫的日誌庫。
2 動手寫@Slf4j
很簡單,先上代碼:
import org.slf4j.Logger
import org.slf4j.LoggerFactory
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
annotation class Slf4j{
companion object{
val <reified T> T.log: Logger
inline get() = LoggerFactory.getLogger(T::class.java)
}
}
逐行解釋如下:
@Target
:與Java
中的@Target
類似,註解的目標,這裏是類@Retention
:與Java
中的@Retention
類似,運行時保留annotation class
:聲明一個註解companion object
:伴生對象val <reified T> T.log:Logger
:聲明一個Logger
類型的泛型對象inline get() = LoggerFactory.getLogger(T::class.java)
:聲明getter
爲內聯,聲明爲內聯才能使用T
,這樣才能傳遞給後面的getLogger
,T::class.java
相當於Java
中的T.class
,也就是getLogger(T::class.java)
相當於getLogger(SomeClass.class)
使用很簡單:
@RestController
@Slf4j
class TestController {
@GetMapping("/test")
fun test():String{
log.warn("cc")
return "test"
}
}
直接類上加一個註解,就可以使用log.info
/log.warn
之類的方法了。
3 kotlin-logging
上面介紹了註解的使用方法,如果不想使用註解的話,可以使用別人的庫,比如kotlin-logging
。
kotlin-logging
是一個100%使用Kotlin
編寫的輕度封裝了slf4j
的開源日誌庫,已經收穫1.4k
的star
:
依賴如下:
<dependency>
<groupId>io.github.microutils</groupId>
<artifactId>kotlin-logging-jvm</artifactId>
<version>2.0.6</version>
</dependency>
Gradle
:
implementation 'io.github.microutils:kotlin-logging-jvm:2.0.6'
引入時,只需要在對應的類中創建一個屬性即可:
private val logger = KotlinLogging.logger {}
使用時,直接調用其中的info
/debug
/error
等即可:
import mu.KotlinLogging
private val logger = KotlinLogging.logger {}
class FooWithLogging {
val message = "world"
fun bar() {
logger.debug { "hello $message" }
}
}
4 兩者結合使用
當然,也可以將註解與kotlin-logging
結合一下使用,首先,筆者簡單地看了一下KotlinLogging
的接口:
提供了三個對外的logger
方法,參數分別是:
- 函數
- 字符串
org.slf4j.Logger
對外沒有提供類似getLogger(Class<?> clazz)
這樣的用類作爲參數的方法,因此,需要通過泛型獲取到具體類的名字並使用第二種方法構造mu.KLogger
:
import mu.KotlinLogging
import org.slf4j.Logger
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
annotation class Slf4j{
companion object{
val <reified T> T.log: Logger
inline get() = KotlinLogging.logger{T::class.java.name}
}
}
使用方法同上,直接加一個@Slf4j
即可使用。