在Log4J中,最常用的就是这里介绍的OnlyOnceErrorHandler和FallbackErrorHandler。下面,我们再来简单分析下FallbackErrorHandler的代码。
同样的,在分析别人代码之前,我们先来思考下,如果是我们,应该怎么实现这个功能。首先,我们的FallbackErrorHandler需要实现ErrorHandler接口中的方法,先看看几个set方法的实现,对于setAppender和setBackupAppender方法,我们只需要在FallbackErrorHandler里面维护这两个Appender的引用即可;但是对于setLogger方法,我们就需要在FallbackErrorHandler里面使用一个集合来保存所有添加进来的Logger;对于error方法,我们要做的就是遍历所有维护的Logger,然后把这些Logger的所有的Appender都去掉,然后再使用addAppender把维护的backupAppender添加到Logger之上。就完成了Appender的切换,我们来看看是不是这样实现的:
public void setLogger(Logger logger) {
LogLog.debug("FB: Adding logger [" + logger.getName() + "].");
if (loggers == null) {
loggers = new Vector();
}
loggers.addElement(logger);
}
首先是setLogger,确实是把所有添加的Logger全部放到了loggers里面维护。
public void setAppender(Appender primary) {
LogLog.debug("FB: Setting primary appender to [" + primary.getName() + "].");
this.primary = primary;
}
public void setBackupAppender(Appender backup) {
LogLog.debug("FB: Setting backup appender to [" + backup.getName() + "].");
this.backup = backup;
}
再看看两个setAppender方法,确实也是在ErrorHandler里面维护了这两个Appender的实例,最后来看看error方法:
public void error(String message, Exception e, int errorCode, LoggingEvent event) {
if (e instanceof InterruptedIOException) {
Thread.currentThread().interrupt();
}
if (loggers != null) {
for (int i = 0; i < loggers.size(); i++) {
Logger l = (Logger) loggers.elementAt(i);
l.removeAppender(primary);
l.addAppender(backup);
}
}
}
重点就是下面的for循环,可以看到,的确是先遍历所有的维护的logger,但是他并没有全部移除Appender,而是只移除了出错的Appender,然后把备用的Appender添加上去。其实看完这个代码,我们又学习了Logger的一个removeAppender(Appender)方法。
同样的,在分析别人代码之前,我们先来思考下,如果是我们,应该怎么实现这个功能。首先,我们的FallbackErrorHandler需要实现ErrorHandler接口中的方法,先看看几个set方法的实现,对于setAppender和setBackupAppender方法,我们只需要在FallbackErrorHandler里面维护这两个Appender的引用即可;但是对于setLogger方法,我们就需要在FallbackErrorHandler里面使用一个集合来保存所有添加进来的Logger;对于error方法,我们要做的就是遍历所有维护的Logger,然后把这些Logger的所有的Appender都去掉,然后再使用addAppender把维护的backupAppender添加到Logger之上。就完成了Appender的切换,我们来看看是不是这样实现的:
public void setLogger(Logger logger) {
LogLog.debug("FB: Adding logger [" + logger.getName() + "].");
if (loggers == null) {
loggers = new Vector();
}
loggers.addElement(logger);
}
首先是setLogger,确实是把所有添加的Logger全部放到了loggers里面维护。
public void setAppender(Appender primary) {
LogLog.debug("FB: Setting primary appender to [" + primary.getName() + "].");
this.primary = primary;
}
public void setBackupAppender(Appender backup) {
LogLog.debug("FB: Setting backup appender to [" + backup.getName() + "].");
this.backup = backup;
}
再看看两个setAppender方法,确实也是在ErrorHandler里面维护了这两个Appender的实例,最后来看看error方法:
public void error(String message, Exception e, int errorCode, LoggingEvent event) {
if (e instanceof InterruptedIOException) {
Thread.currentThread().interrupt();
}
if (loggers != null) {
for (int i = 0; i < loggers.size(); i++) {
Logger l = (Logger) loggers.elementAt(i);
l.removeAppender(primary);
l.addAppender(backup);
}
}
}
重点就是下面的for循环,可以看到,的确是先遍历所有的维护的logger,但是他并没有全部移除Appender,而是只移除了出错的Appender,然后把备用的Appender添加上去。其实看完这个代码,我们又学习了Logger的一个removeAppender(Appender)方法。