如何创建 Java mixins:@Slf4j

How to create Java mixins: @Slf4j

我正在尝试创建一个 Java mixin 并使用 @Slf4j 注释。但是 intellij 显示错误 @Slf4j is only legal for classes and enums.

import lombok.extern.slf4j.Slf4j;

@Slf4j
public interface Foo {
    default void foo() {
        log.info("Hello world");
    }
}

一种选择是向接口添加 getLogger 方法,并要求实现实现该方法。然后接口就可以调用那个方法了。

import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;

public interface Foo {

    Logger getLogger();

    default void foo() {
        getLogger().info("Hello world");
    }
}

@Slf4j
public class Bar implements Foo {

    public void bar() {
        foo();
    }

    @Override
    public Logger getLogger() {
        return log;
    }
}

一种选择是使用静态 getLogger 方法创建内部 class。

import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;

public interface Foo {

    @Slf4j
    class Log {
        public static Logger getLogger() {
            return log;
        }
    }

    default void foo() {
        Log.getLogger().info("Hello world");
    }
}

如果你想为接口使用日志记录,你可以使用常量:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public interface Foo {
    Logger log = LoggerFactory.getLogger(Foo.class);

    default void foo() {
        log.info("Hello from Foo");
    }
}

如果这个接口有一些实现,你可以覆盖一个记录器:

public class Bar implements Foo {
    Logger log = LoggerFactory.getLogger(Bar.class);

    public void bar() {
        log.info("Hello from Bar");
    }
}

使用 Lombok 可以做得更简单:

@Slf4j
class Bar implements Foo {
    public void bar() {
        log.info("Hello from Bar");
    }
}

演示代码:

public class LoggerDemo {
    public static void main(String[] args) {
        Bar bar = new Bar();
        bar.foo();
        bar.bar();
    }
}

输出:

20:40:48.010 [main] INFO demo.Foo - Hello from Foo 
20:40:48.014 [main] INFO demo.Bar - Hello from Bar

解决该问题的一个简单方法是将记录器传递给 foo() 方法:

import org.slf4j.Logger;

public interface Foo {
    default void foo(Logger log) {
        log.info("Hello world");
    }
}

然后在实现 Foo:

的 类 上使用 @Slf4j 注释
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class Bar implements Foo {
    public void bar() {
        foo(log);
    }
}