本次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还是个接口类,我们看看这个接口类的继承关系:
/**
* 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的静态程序块。