初識log4j1.x
研究源碼首先要對項(xiàng)目要有整體的認(rèn)識,這一章節(jié)主要讓大家對log4j1.x有一個(gè)整體的認(rèn)識,并以此為切入點(diǎn),認(rèn)識log4j1.x的整個(gè)框架
1 整體認(rèn)識
先整體上對log4j1有一個(gè)整體的認(rèn)識,然后再在后面對log4j的研究中逐漸加深對其的理解。先不必糾結(jié)在整體的類圖和流程圖中。
(這里類圖和流程從簡,能夠表達(dá)內(nèi)容即可)
1.1 打印日志流程圖

流程說明:
?-第一步: 初始化Logger容器LoggerRepository,默認(rèn)為Hierachy,?根節(jié)點(diǎn)是RootLogger
-第二步: 獲取Logger實(shí)例,調(diào)用LogManager.getLogger()獲得Logger實(shí)例,存在直接返回,不存在創(chuàng)建返回
-第三步: 判斷是否打印日志(請求打印日志的Level要高于或者等于Logger的級別,請求打印日志語句才能生效),Logger實(shí)例的所有Appender按照Layout的格式輸出日志
1.2 類圖

類圖說明:
LoggerFactory : Logger的工廠,用來獲得Logger實(shí)例
LoggerRepository: Logger的容器
RepositorySelector: 獲取Logger容器
LogManager: Logger的管理中心,獲取Logger容器、Logger實(shí)例、RootLogger
Logger: 日志記錄器
Appender: 日志輸出目的地
Layout: 日志輸出格式
2 ?搭建環(huán)境
創(chuàng)建maven項(xiàng)目,加入依賴:
<!-- Log4j1 日志框架包 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
3 ?代碼示例(以此為切入點(diǎn)了解架構(gòu))
public class BasicConfiguratorDemo {
private static final Logger LOGGER =Logger.getLogger(BasicConfiguratorDemo.class);
public static void main(String[] args){
BasicConfigurator.configure();
LOGGER.info("Hello World");
}
}
輸出結(jié)果:
1 [main] INFO com.log.log4j.configure.BasicConfiguratorDemo - Hello World
4 代碼運(yùn)行流程

4.1 獲取Logger流程(Logger.getLogger(BasicConfiguratorDemo.class))

4.2 BasicConfigurator.configure()配置流程
獲得RootLogger,添加ConsoleAppender,由于繼承關(guān)系,其他Logger的父Logger都是RootLogger.所以其他Logger的Appender都是這里定義的ConsoleAppender
public static void configure() {
Logger root = Logger.getRootLogger();
root.addAppender(new ConsoleAppender(
new PatternLayout(PatternLayout.TTCC_CONVERSION_PATTERN)));
}
4.3 打印Hello World(LOGGER.info("Hello World"))流程
源碼:
public void info(Object message) {
if(repository.isDisabled(Level.INFO_INT))
return;
if(Level.INFO.isGreaterOrEqual(this.getEffectiveLevel()))
forcedLog(FQCN, Level.INFO, message, null);
}
//Level具有繼承特性,如果Logger本身沒有設(shè)置Level,會繼承父Logger的Level,Logger至少有一個(gè)Parent(RootLogger),具體參考log4j文檔
public Level getEffectiveLevel() {
for(Category c = this; c != null; c=c.parent) {
if(c.level != null)
return c.level;
}
return null; // If reached will cause an NullPointerException.
}
流程:
