使用spring mvc已有2年之久,却还是停留在使用阶段,感觉这么下去不是办法,所以还是想往深处一探究竟。
为啥我没有在web.xml里配置log4j,也能打印日志。
在倒腾AOP切面的时候,突然发现了一个问题,在框架中使用了log4j,项目启动时也会有相应的日志打印,而且是我自己配置的log4j.properties里的内容。这不是很正常吗?不是,很不正常,因为我在web.xml里的log4j的监听器和log4jConfigLocation配置路径已经被我注释掉了,它却还能打印,表示一脸蒙比。。。
到网上寻求解释,搜到的大部分是spring mvc里如何配置日志。于是想试试排查一下:
1.将log4j.properties文件中的日志语句加个前缀,再看看打印的日志——确定该日志的确实来自log4j.properties
2.将log4j.properties文件名修改一下,比如改为log4jabc.properties,此时启动项目,日志不打印——只能读到特定的文件名
由此猜想,是不是系统中会设置默认的值。
再次查找,看到有这样一个问答:http://www.iteye.com/problems/15009,哈哈,感觉和我想问的很符合,看看答案,额,大多都是:贴代码我帮你找找,你肯定配置了。第一个答案:“java虚拟机加载log4j的类(LogManager.class)后,执行静态代码块,这个类中的静态代码块,会load log4j的配置文件,依次加载log4j.xml,log4j.properties”,倒是感觉有点道理,于是去log4j的jar包里找找源码,在根目录下找到了LogManager.class这个文件,打开看看:
<span style="font-size:18px;"><span > </span>if(configurationOptionStr == null) {
url = Loader.getResource("log4j.xml");
if(url == null) {
url = Loader.getResource("log4j.properties");
}
} else {
try {
url = new URL(configurationOptionStr);
} catch (MalformedURLException var5) {
url = Loader.getResource(configurationOptionStr);
}
}</span>
果然是有默认值,再次实验,将log4j.properties 改名为log4jabc.properties后,通过配置加载:
<span style="font-size:18px;"><span > </span><context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:log4jabc.properties</param-value>
</context-param>
<!-- Spring的log4j监听器 -->
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener></span>
可以正常打印日志,所以当导入了log4j包,又没配置时,会去找默认配置。
强调一点,“同时使用commons-logging和Log4j”,与“单独使用Log4j”相比,并不会带来更大的学习、配置和维护成本,反而更加简化了我们的工作。我想这也是为什么“所有用到Log4j的项目一般也同时会用到commons-loggin”的原因之一吧。
Commons-logging能帮我们做什么?
l 提供一个统一的日志接口,简单了操作,同时避免项目与某个日志实现系统紧密a耦合
l 很贴心的帮我们自动选择适当的日志实现系统(这一点非常好!)
l 它甚至不需要配置
这里看一下它怎么“‘很贴心的’帮我们‘自动选择’‘适当的’日志实现系统”:
1) 首先在classpath下寻找自己的配置文件commons-logging.properties,如果找到,则使用其中定义的Log实现类;
2) 如果找不到commons-logging.properties文件,则在查找是否已定义系统环境变量org.apache.commons.logging.Log,找到则使用其定义的Log实现类;
3) 否则,查看classpath中是否有Log4j的包,如果发现,则自动使用Log4j作为日志实现类;
4) 否则,使用JDK自身的日志实现类(JDK1.4以后才有日志实现类);
5) 否则,使用commons-logging自己提供的一个简单的日志实现类SimpleLog;
有意思,这东西能和多种日志框架配合使用。