scala 自我意识特征
我制作了一个 Logging 特征,它封装了日志记录实现的细节,它也很好而且很懒惰,所以非常有效,特别是当特定日志级别不活动时。
/**
* A SLF4J based logging trait
*/
trait Log {
import org.slf4j.Logger
import org.slf4j.LoggerFactory
val loggedClazz: Class[_]
lazy val logger: Logger = LoggerFactory.getLogger(loggedClazz.getClass)
def logDebug(codeblock: => String) = {
if (logger.isDebugEnabled) {
logger.debug(codeblock)
}
}
def logError(codeblock: => String) = {
if (logger.isErrorEnabled) {
logger.error(codeblock)
}
}
def logInfo(codeblock: => String) = {
if (logger.isInfoEnabled) {
logger.info(codeblock)
}
}
def logWarn(codeblock: => String) = {
if (logger.isWarnEnabled) {
logger.warn(codeblock)
}
}
}
然而,它需要混合该特征的类来实现以下功能。
object MyServer extends Log {
val loggedClazz = MyServer.getClass
}
我的问题是,是否有可能以某种方式使该特征知道它已混合到哪个类中?删除需要执行的操作:
val loggedClazz = MyServer.getClass
解决方案:根据提供的反馈,我按以下方式重写了该类。
/**
* A SLF4J based logging trait
*/
trait Log {
import org.slf4j.Logger
import org.slf4j.LoggerFactory
lazy val logger: Logger = LoggerFactory.getLogger(getClass)
def logDebug(codeblock: => String) = {
if (logger.isDebugEnabled) {
logger.debug(codeblock)
}
}
def logError(codeblock: => String) = {
if (logger.isErrorEnabled) {
logger.error(codeblock)
}
}
def logInfo(codeblock: => String) = {
if (logger.isInfoEnabled) {
logger.info(codeblock)
}
}
def logWarn(codeblock: => String) = {
if (logger.isWarnEnabled) {
logger.warn(codeblock)
}
}
}
完全简单。当你第一次就做对了;)
I've made a Logging trait which encapsulates the details of a logging implementation, it's also nice and lazy so is efficient especially when a particular log level is not active.
/**
* A SLF4J based logging trait
*/
trait Log {
import org.slf4j.Logger
import org.slf4j.LoggerFactory
val loggedClazz: Class[_]
lazy val logger: Logger = LoggerFactory.getLogger(loggedClazz.getClass)
def logDebug(codeblock: => String) = {
if (logger.isDebugEnabled) {
logger.debug(codeblock)
}
}
def logError(codeblock: => String) = {
if (logger.isErrorEnabled) {
logger.error(codeblock)
}
}
def logInfo(codeblock: => String) = {
if (logger.isInfoEnabled) {
logger.info(codeblock)
}
}
def logWarn(codeblock: => String) = {
if (logger.isWarnEnabled) {
logger.warn(codeblock)
}
}
}
However it requires the class into which this trait is mixed-in to implement the following..
object MyServer extends Log {
val loggedClazz = MyServer.getClass
}
My question is, is it possible to somehow enable the Trait to know into which class it has been mixed into? Removing the need to do:
val loggedClazz = MyServer.getClass
SOLUTION: Following the provided feedback, I rewrote the class in the following manner.
/**
* A SLF4J based logging trait
*/
trait Log {
import org.slf4j.Logger
import org.slf4j.LoggerFactory
lazy val logger: Logger = LoggerFactory.getLogger(getClass)
def logDebug(codeblock: => String) = {
if (logger.isDebugEnabled) {
logger.debug(codeblock)
}
}
def logError(codeblock: => String) = {
if (logger.isErrorEnabled) {
logger.error(codeblock)
}
}
def logInfo(codeblock: => String) = {
if (logger.isInfoEnabled) {
logger.info(codeblock)
}
}
def logWarn(codeblock: => String) = {
if (logger.isWarnEnabled) {
logger.warn(codeblock)
}
}
}
Totally simple. When you do it right, first time ;)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以将
valloggingClazz: Class[_]
替换为valloggingClazz = getClass
。You could replace
val loggedClazz: Class[_]
withval loggedClazz = getClass
.您当前的代码将无法按预期工作,因为返回的记录器将始终针对类
Class[Class[_]]
,因为您在上调用
对象。getClass
>Class[_]请使用以下代码:
lazy val logger: Logger = LoggerFactory.getLogger(getClass)
您可能还想看看SLF4S,SLF4J 的薄包装,与您正在做的非常相似。
Your current code won't work as expected as the returned logger will always be for class
Class[Class[_]]
, as you're callinggetClass
on aClass[_]
object.Use this instead:
lazy val logger: Logger = LoggerFactory.getLogger(getClass)
You may also want to have a look SLF4S, a thin wrapper around SLF4J, which is very similar to what you're doing.