Log4j源码阅读之一—Logger的获取

本文从Logger.getLogger("test")方法入手,深入Log4j源码,探讨Logger实例如何通过LogManager的RepositorySelector和LoggerRepository获取。文章揭示了repositorySelector作为私有静态成员变量,其接口实现类与LoggerRepository的关系,以及在没有明确入口指向的情况下,程序如何继续运行的谜团。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    本次Log4j源码研读的入口,是从 logger = Logger.getLogger("test"),这个方法调用开始,我们看看下边是时序图:



下边是对上述时序图的解读:

我们actioner通过调用Logger.getLogger("test")方法的时候,会提交的Logger类的静态方法getLogger,这个静态方法源码如下:

 public static Logger getLogger(String name) {
    return LogManager.getLogger(name);
  }

我们可以知道,这个时候,我们调用到了LogManager的静态方法getLogger(name),源码如下:

    /**
       Retrieve the appropriate {@link Logger} instance.
    */
    public static Logger getLogger(String name) {
        // Delegate the actual manufacturing of the logger to the logger repository.
        return repositorySelector.getLoggerRepository().getLogger(name);
    }

这个时候我们会很疑惑,调用这个方法的时候,怎么跑出了repositorySelector?我们进行查看源码:

    /**
     * The repository selector.
     */
    private static RepositorySelector repositorySelector;

可以知道这个repositorySelector是个私有成员变量引用,同时方法 RepositorySelector还是个接口类,我们看看这个接口类的继承关系:


同时我们通过查看RepositorySelector接口类源码如下:

public interface RepositorySelector {

  /**
   * Returns a {@link LoggerRepository} depending on the context. Implementors 
   * must make sure that under all circumstances a valid (non-null) 
   * LoggerRepository is returned.
  */
  public LoggerRepository getLoggerRepository();
}

可以知道,这个接口类只提供了一个方法,这个方法返回了一个LoggerRepository实例,通过这个实例我们就可以获取到对应的logger实例。

但是通过查看源码我们更加困惑了,这个是接口类,究竟是哪个实现类实现了它,才能要 程序往下跑呢?RepositorySelector的实现类里边必定

指向了一个LoggerRepository实例,而这个LoggerRepository也必定指向了一个Logger实例,他们究竟在哪里指向的呢?我们的入口并没有任何指向呀?

我们带着问题进行下一回:LogManager的静态程序块。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值