Log4j2 惰性 lambda 评估:Groovy 有机会吗?
Log4j2 lazy lambda evaluation: Any chance in Groovy?
问题似乎是 Log4j2 的纯 Java 实现不提供 Closure 参数(或 lambda 参数,如果有的话),而是在方法签名中提供一个简单的 Object 参数。 Groovy (3.0.8) 将 Java 风格的 lambda 和方法引用转换为闭包,而 Log4j 似乎只是在它们上调用 .toString() 。因此,下面代码的日志输出看起来像这样,这显然不是预期的结果,来自 Java:
13:55:39.417 [main] INFO Messenger - test$_runCode_closure1@f391e52
13:55:39.417 [main] INFO Messenger - test$_runCode_closure2@4b518645
13:55:39.417 [main] INFO Messenger - org.codehaus.groovy.runtime.MethodClosure@294a3f2a
import org.apache.logging.log4j.LogManager
def log2 = LogManager.getLogger("Messenger")
log2.info("{}", () -> "Expensive message")
log2.info ("{}") { "Expensive message" }
log2.info("{}", this::someString)
static String someString() {
return "Expensive message"
}
在 Groovy 中有什么方法可以用 Java lambda 而不是 Groovy 闭包结束吗? Groovy 为 Logger 方法提供带有闭包的方法签名的扩展可以作为答案吗?
免责声明:不是正确答案,而是解决方法。
Groovys GString 也可以使用闭包,每次调用
GString 必须显示为 String。
例如
def a = 42
def gs = "${a} ${-> a}"
println gs
// → 42 42
a = 666
println gs
// → 42 666
所以你可以使用:
log2.info ("${ -> "Expensive message" }")
郑重声明:所有这些都给了我 Object
而不是 Supplier
摆弄的版本:
log2.info('{}', {42} as Supplier)
log2.info('{}', [{42}].toArray())
log2.info('{}', [{42}] as Supplier[])
log2.info('{}', [{42}] as Supplier<Long>[])
log2.info('{}', new Supplier() { Object get() { 42 } })
log2.info('{}', *[{42}])
都不能与 @CompileStatic
一起使用(最后一个除外,它根本无法编译)。使用 Groovy 4.0.0-alpha3
测试
有一个仅将供应商作为参数的变体:
log2.info({ "Expensive message" } as Supplier)
问题似乎是 Log4j2 的纯 Java 实现不提供 Closure 参数(或 lambda 参数,如果有的话),而是在方法签名中提供一个简单的 Object 参数。 Groovy (3.0.8) 将 Java 风格的 lambda 和方法引用转换为闭包,而 Log4j 似乎只是在它们上调用 .toString() 。因此,下面代码的日志输出看起来像这样,这显然不是预期的结果,来自 Java:
13:55:39.417 [main] INFO Messenger - test$_runCode_closure1@f391e52
13:55:39.417 [main] INFO Messenger - test$_runCode_closure2@4b518645
13:55:39.417 [main] INFO Messenger - org.codehaus.groovy.runtime.MethodClosure@294a3f2a
import org.apache.logging.log4j.LogManager
def log2 = LogManager.getLogger("Messenger")
log2.info("{}", () -> "Expensive message")
log2.info ("{}") { "Expensive message" }
log2.info("{}", this::someString)
static String someString() {
return "Expensive message"
}
在 Groovy 中有什么方法可以用 Java lambda 而不是 Groovy 闭包结束吗? Groovy 为 Logger 方法提供带有闭包的方法签名的扩展可以作为答案吗?
免责声明:不是正确答案,而是解决方法。
Groovys GString 也可以使用闭包,每次调用 GString 必须显示为 String。
例如
def a = 42
def gs = "${a} ${-> a}"
println gs
// → 42 42
a = 666
println gs
// → 42 666
所以你可以使用:
log2.info ("${ -> "Expensive message" }")
郑重声明:所有这些都给了我 Object
而不是 Supplier
摆弄的版本:
log2.info('{}', {42} as Supplier)
log2.info('{}', [{42}].toArray())
log2.info('{}', [{42}] as Supplier[])
log2.info('{}', [{42}] as Supplier<Long>[])
log2.info('{}', new Supplier() { Object get() { 42 } })
log2.info('{}', *[{42}])
都不能与 @CompileStatic
一起使用(最后一个除外,它根本无法编译)。使用 Groovy 4.0.0-alpha3
有一个仅将供应商作为参数的变体:
log2.info({ "Expensive message" } as Supplier)