Lombok @Slf4j和接口?

13

我正在尝试为我的接口默认方法添加日志记录。例如:

@Slf4j // not allowed
interface MyIFace {
    default ThickAndThin doThisAndThat() {
        log.error("default doThisAndThat() called"); 
    }
}

问题是我遇到了以下错误:

@Slf4j 仅适用于类和枚举。

正确的处理方式是什么?

1
最好抛出UnsupportedOperationException("default doThisAndThat()")而不是记录错误。如果类中未实现该方法并被调用,异常会阻止代码继续执行,而记录日志则会让代码悄悄地继续执行,然后可能有人最终会读取日志并意识到代码存在严重问题。 - Andreas
@Andreas 是的,你说得对,但实际上只是为了记录任何东西,而不仅仅是错误。所以我选择记录错误是我的错 :) - pirho
2个回答

27

因为该注释会生成以下内容,您无法在这里使用Lombok:


private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(YourClass.class);

在接口中,您不能使用private关键字。

解决方法是直接编写代码。


interface MyIFace {

   org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(MyIFace.class);

   default ThickAndThin doThisAndThat() {
     log.error("default doThisAndThat() called"); 
   }

}



1
是的,我现在明白了,感谢delombok。那么唯一的方法就是不使用Lombok并将其声明为public。除此之外,我还考虑将MyIFace更改为具有方法“Logger getLogger()”,以便实现类必须返回带有@ Slf4j的内容。优点是在记录日志时可以获得实际类,但另一方面,它会公开每个单独实现类的记录器。因此,由于接口的公共性质,您无法获得“完美”的解决方案。 - pirho
这进一步引发了声纳问题-鱿鱼:S1214(常量不应该在接口中定义)。 - iAmLearning
在接口中,您可以执行LoggerFactory.getLogger(getClass());,这将为实际类提供记录器,而不是MyIFace... - Ilario

1

使用Java 9+,您可以使用私有方法来防止日志记录器成为public static。

public interface MyIFace {
    private Logger log() {
        return LoggerFactory.getLogger(MyIFace.class);
    }

    default void doThisAndThat() {
        log().error("default doThisAndThat() called");
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接