上文描述了如何在Apusic AS的Web应用中调用Log4J,有些朋友会觉得Log4J使用前还需要初始化比较麻烦,还有些朋友会说“怎么你这个Log4J使用起来那么复杂,我们的项目都没有那么过程呀?”,那是因为许多Web应用中是用Java commons-logging(JCL)+Log4J的,如果采用JCL+Log4J就不需要初始化了。
那么为什么有了Log4J又有JCL呢?是因为SUN的JDK 1.4中自带有日志框架,Log4J是Apache提供的日志框架,为了扩展应用的兼容性,保证应用可以无缝切换到不同的日志框架,因此JCL提供的是日志系统的接口,通过给工厂接口提供不同的实现类,从而保证与不同日志框架的兼容。同时,为了保证系统的有效性,还提供了一个非常简单的日志框架实现,以便没有外接其他日志框架时可以使用自带的。
那么为什么JCL+Log4J就不需要初始化了呢?这要从JCL的执行流程说起。当应用执行类似以下代码时:
import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory;
public class LoggingDemo { private static Log log = LogFactory.getLog(LoggingDemo.class); // ... } LogFactory.getLog()函数会启动一个搜索过程,找出底层日志记录功能的实现,具体的发现过程在下面列出:
⑴ Commons的Logging首先在CLASSPATH中寻找一个commons-logging.properties文件。这个属性文件至少定义org.apache.commons.logging.Log属性,它的值应该是实现Log接口的完整限定名称。
⑵ 如果上面的步骤失败,Commons的Logging接着检查系统属性org.apache.commons.logging.Log,以便找到实现Log接口的完整限定名称。属性可以通过服务器启动时参数配置,或者在代码中使用System.setProperty()函数操作,具体可以参考附件。
⑶ 如果找不到org.apache.commons.logging.Log系统属性,Logging接着在CLASSPATH中寻找log4j的类。如果找到了,Logging就假定应用要使用的是log4j。log4j本身的属性需要按照框架配置文件定义的方式进行,一般是通过log4j.properties文件正确配置。
⑷ 如果上述查找均不能找到适当的Logging API,但应用程序正运行在JRE 1.4或更高版本上,则默认使用JRE 1.4的日志记录功能。
⑸ 最后,如果上述操作都失败,则应用将使用内建的SimpleLog。SimpleLog把所有日志信息直接输出到System.err。
了解了以上的过程就会明白为什么JCL+Log4J不再需要初始化,使用JCL+Log4J只需要在WEB-INF/lib下放置commons-logging.jar和log4j.jar包,在WEB-INF/classes下放置log4j.properties和commons-logging.properties(可选)文件,就可以在程序中随意的使用了。