Java 如何基于Log4J中的派生类在基类中配置日志记录?

Java 如何基于Log4J中的派生类在基类中配置日志记录?,java,log4j,Java,Log4j,我在库中有一个基类,其中包含大量调试级日志记录语句。该库用于不同的应用程序,基类是子类。我希望能够根据使用基类的特定派生类配置基类的日志记录级别。实现这一目标的有用习惯用法是什么 例如,以下是起点: class Base { static Logger logger = Logger.getLogger(Base.class); protected final void foo() { logger.debug("foo"); } } class Der

我在库中有一个基类,其中包含大量调试级日志记录语句。该库用于不同的应用程序,基类是子类。我希望能够根据使用基类的特定派生类配置基类的日志记录级别。实现这一目标的有用习惯用法是什么

例如,以下是起点:

class Base {
    static Logger logger = Logger.getLogger(Base.class);
    protected final void foo() {
        logger.debug("foo");
    }
}

class DerivedA extends Base {
    public void boo() {
        foo();
    }
}

class DerivedB extends Base {
    public void boo() {
        foo();
    }
}
鉴于上述情况,无法打开
DerivedA
的日志记录,但无法打开
DerivedB
的日志记录

相反,我必须做如下事情:

abstract class Base {

    abstract protected Class getDerivedType();
    protected final void foo() {
        Logger logger = Logger.getLogger(getDerivedType());        
        logger.debug("foo");
    }
}

class DerivedA extends Base {
    public void boo() {
        foo();
    }
    @Override protected Class getDerivedType() {
        return DerivedA.class;
    }
}

class DerivedB extends Base {
    public void boo() {
        foo();
    }
    @Override protected Class getDerivedType() {
        return DerivedB.class;
    }    
}
…鉴于上述情况,我可以根据派生类在我的
log4j.properties
文件中设置不同的日志级别:

log4j.logger.a.DerivedA=debug
log4j.logger.a.DerivedB=info
虽然上述方法确实有效,但我不喜欢这样一个事实,即我的
logger
对象不能再是静态的,必须在每个方法中重新定义。而且,我不得不为派生类定义一个抽象方法来提供它们的具体类型,这感觉很不自然,因为除了能够自定义日志记录之外,没有其他原因

以上是惯用语吗?如果不是,有什么更好的方法可以达到同样的效果


通常,是否有一种基于上下文配置日志的方法?(在本例中,上下文是派生类,但也可以是调用堆栈,即在发生日志记录时调用特定方法的方法)。或者,这种级别的日志配置是否真的不受支持,甚至是一个坏主意?

非静态记录器的一种可能解决方案:

public class Base {
    protected Logger logger = Logger.getLogger(Base.class);

    protected final void foo() {
        logger.debug("foo");
    }
}

class DerivedA extends Base {
    {
        logger = Logger.getLogger(DerivedA.class);
    }

    public void boo() { foo(); }
}

class DerivedB extends Base {
    {
        logger = Logger.getLogger(DerivedB.class);
    }
    public void boo() { foo(); }
}
尽管
记录器
不是静态的,但这种结构比原始结构简单得多


替代解决方案:子类必须实现
getLogger()
抽象方法(它们可以简单地返回一个静态记录器),该方法在基类中用于日志记录。这里的记录器可以是静态的

public abstract class Base {
    protected abstract Logger getLogger();

    protected final void foo() {
        getLogger().debug("foo");
    }
}

class DerivedA extends Base {
    private static final Logger logger = Logger.getLogger(DerivedA.class);

    public void boo() { foo(); }

    protected Logger getLogger() { return logger; }
}

class DerivedB extends Base {
    private static Logger logger =  Logger.getLogger(DerivedB.class);

    public void boo() { foo();}

    protected Logger getLogger() { return logger; }
}
这两种方法都适用于当前属性文件