Spring + MyBaits 日志初始化两遍的问题
偶然发现一个问题,记录一下以备查询。
问题:系统启动时发现日志初始化了两次
14:28:04.798 [main] DEBUG org.apache.ibatis.logging.LogFactory - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
14:28:04.970 [main] DEBUG org.apache.ibatis.logging.LogFactory - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
相关环境文件
mybatis-config.xml片段:
<settings>
<setting name="logImpl" value="SLF4J" /> <!-- 日志实现包 -->
</settings>
applicitionContext.xml片段:
<!-- 配置SqlSessionFactoryBean -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="driverManagerDataSource" />
<property name="configLocation" value="classpath:mybatis-config.xml" />
</bean>
既然是LogFactory打印的日志,先从LogFactory开始看,
public final class LogFactory {
private static Constructor<? extends Log> logConstructor; static { // 加载时按顺序尝试日志实现,这是第一条日志的输出
tryImplementation(new Runnable() {
public void run() {
useSlf4jLogging();
}
});
tryImplementation(new Runnable() {
public void run() {
useCommonsLogging();
}
});
// 忽略部分代码
tryImplementation(new Runnable() {
public void run() {
useNoLogging();
}
});
} private LogFactory() {
// disable construction
} public static Log getLog(Class<?> aClass) {
return getLog(aClass.getName());
} public static Log getLog(String logger) {
try {
return logConstructor.newInstance(new Object[] { logger });
} catch (Throwable t) {
throw new LogException("Error creating logger for logger " + logger + ". Cause: " + t, t);
}
} public static synchronized void useCustomLogging(Class<? extends Log> clazz) {
setImplementation(clazz);
} public static synchronized void useSlf4jLogging() {
setImplementation(org.apache.ibatis.logging.slf4j.Slf4jImpl.class);
} public static synchronized void useCommonsLogging() {
setImplementation(org.apache.ibatis.logging.commons.JakartaCommonsLoggingImpl.class);
}
public static synchronized void useStdOutLogging() {
setImplementation(org.apache.ibatis.logging.stdout.StdOutImpl.class);
} public static synchronized void useNoLogging() {
setImplementation(org.apache.ibatis.logging.nologging.NoLoggingImpl.class);
} private static void tryImplementation(Runnable runnable) {
if (logConstructor == null) { // 当加载日志实现成功一次后,这里logConstructor已经不为null
try {
runnable.run();
} catch (Throwable t) {
// ignore
}
}
} private static void setImplementation(Class<? extends Log> implClass) {
try {
Constructor<? extends Log> candidate = implClass.getConstructor(new Class[] { String.class });
Log log = candidate.newInstance(new Object[] { LogFactory.class.getName() });
log.debug("Logging initialized using '" + implClass + "' adapter.");
logConstructor = candidate;
} catch (Throwable t) {
throw new LogException("Error setting Log implementation. Cause: " + t, t);
}
}
}
可以看出在spring容器启动时,已经加载了一个“org.apache.ibatis.logging.slf4j.Slf4jImpl”;
那么第二条日志是什么时候输出呢?
容器在构造SqlSessionFactoryBean时,需要mybatis-config.xml,因为有<setting name="logImpl" value="SLF4J" />这一条配置,
所以在解析到这一条时调用了org.apache.ibatis.session.Configuration这个类又执行了一次初始化,
顺序SqlSessionFactoryBean -> SqlSessionFactoryBuilder -> XMLConfigBuilder -> Configuration
最终Configuration中:
public void setLogImpl(Class<?> logImpl) {
if (logImpl != null) {
this.logImpl = (Class<? extends Log>) logImpl;
LogFactory.useCustomLogging(this.logImpl);
}
}
由此也看明白了配置日志实现相当于手动执行org.apache.ibatis.logging.LogFactory.useSlf4jLogging(),mybatis文档中也写到了:
如果要手动调用LogFactory.use***Logging()方法,请在调用所有其他MyBatis方法前调用它。另外,只有在相应日志实现存在 的前提下,调用对应的方法才是有意义的,否则MyBatis一概忽略。如你环境中并不存在Log4J,你却调用了 相应的方法,MyBatis就会忽略这一调用,代之默认的查找顺序查找日志实现。
Spring + MyBaits 日志初始化两遍的问题的更多相关文章
- spring aop 加在Controller层造成类初始化两遍
写一个测试项目,在配置动态数据源的时候采用的AOP切面到Controller层中,根据参数判断是否切合数据源,结果发现,每次Controller层的类都会初始化两次! 后来测试发现,把切面放到Serv ...
- srping mvc 集成CXF 导致类初始化两遍
cxf依赖于spring的ContextLoaderListener,而spring mvc 则依赖于DispatcherServlet. 初始化DispatcherServlet的时候会依赖初始化一 ...
- tomcat启动项目被重新加载,导致资源初始化两遍
之前没有遇到过这个问题,配了三天的项目了,惊人啊!!!各种怪问题全被我赶上了.真有种骂人的冲动. tomcat启动项目时,项目资源被加载两遍. 原因:配置虚拟目录导致,项目被重新加载. <Hos ...
- log4j2 日志打两遍的问题
在使用log4j2的时候,一般都需要不同的日志分类打印不同的日志等级,如下面的配置 <!-- 用于指定log4j自动重新配置的监测间隔时间,单位是秒 --> <configurati ...
- Spring + MyBaits java.lang.reflect.InvocationTargetException 启动日志报错
调试发现 实例化 class org.apache.ibatis.logging.slf4j.Slf4jImpl时发生异常,所以 slf4j jar 问题解决: http://www.cnblogs. ...
- 从启动日志看Spring IOC的初始化和Bean生命周期
一.Tomcat中启动IoC容器的日志 启动Tomcat等容器时,控制台每次都打印出一些日志. 最近刚好在研究Spring源码,所以换个角度,从启动日志来简单的看看Spring的初始化过程! 以下是T ...
- spring项目的 context root 修改之后,导致 WebApplicationContext 初始化两次的解决方法
修改了 spring web 项目的 context root 为 / 之后,在启动项目时,会导致 WebApplicationContext 初始化两次,下面是其初始化日志: 第一次初始化: 四月 ...
- 【问题记录】eclipse启动web项目时,spring会初始化两次
背景:一个tomcat,一个eclipse,一个SSM框架的web项目.在eclipse中新建tomcat服务器,默认配置,然后在服务器配置中将Server Locations改成Use Tomcat ...
- 项目部署到tomcat Root中后导致 WebApplicationContext 初始化两次的解决方法
上一篇文章刚说项目部署到tomcat的ROOT中,今天就发现一个问题.通过eclipse启动tomcat时候,WebApplicationContext 初始化两次: 现象: 通过eclipse控 ...
随机推荐
- google --SwitchyOmega and switchysharp ***
https://github.com/FelisCatus https://chrome.google.com/webstore/search/Proxy%20SwitchySharp%20?hl=z ...
- 如何在不允许联网的环境下使用Maven开发
前言:Maven的运行机理是:Maven核心组件先去本地的.m2目录下的库中去寻找依赖或者插件,如果本地库里没有,如果配置了私服则上私服去下载依赖或者插件,如果私服上没有,则上中央服务等Maven服务 ...
- Linux下的lds链接脚本简介(一)
转载自:http://linux.chinaunix.net/techdoc/beginner/2009/08/12/1129972.shtml 一. 概论 每一个链接过程都由链接脚本(linker ...
- centos mysql错误信息处理
mysql_secure_installation 提示错误:Enter current password for root (enter for none):ERROR 1045 (28000): ...
- Office Adobe Acrobat把PDF转换为Word时候提示不支持的Type2字体怎么办
如下图所示,在使用Adobe Acrobat Pro9将PDF转换为Word的时候出现下面的错误 很简单,不要用Adobe Acrobat Pro9了,用Adobe Acrobat Pro X,还 ...
- oracle统计信息
手工刷ORACLE统计信息 select count(1) from LOG_TRX_DETAIL; select * from user_tab_statistics where table_n ...
- 分享codeigniter框架,在zend studio 环境下的代码提示
一.到github下载相关文件 https://github.com/Stunt/Codeigniter-autocomplete 二.把文件放到application/config中 代码提示就出来 ...
- css 滤镜之Gradient
CreateTime--2017年12月26日11:09:14 Author:Marydon ie滤镜特效之Gradient 作用: 用于设置渐变背景色 使用条件: IE9及以下版本不支持属性ba ...
- android 不同进程间的调用 AIDL 实现通讯服务
android 不同进程间的调用 AIDL 实现通讯服务 近期对aidl android 不同进程间的调用,不同运用间的调用做了一些尝试: 过程例如以下: 1:首先在要被调用的程序里写好 ...
- Mysql Solution - Timeout error occurred trying to stop MySQL Daemon. Stopping MySQL: [FAILED] -
错误例如以下: Timeout error occurred trying to stop MySQL Daemon. Stopping mysqld: ...