首页 > 编程语言 >Mybatis源码分析(十七) - 源码包分析【日志模块】

Mybatis源码分析(十七) - 源码包分析【日志模块】

时间:2022-11-30 14:40:43浏览次数:68  
标签:log void apache 源码 static Mybatis org 日志 public


mybatis源码下载地址:https://github.com/mybatis/mybatis-3

MyBatis源码导入过程:

  1. 下载MyBatis的源码
  2. 检查maven的版本,必须是3.25以上,建议使用maven的最新版本
  3. mybatis的工程是maven工程,在开发工具中导入,工程必须使用jdk1.8以上版本;
  4. 把mybatis源码的pom文件中<optional>true</optional>,全部改为false;
  5. 在工程目录下执行 mvn clean install -Dmaven.test.skip=true,将当前工程安装到本地仓库(pdf插件报错的话,需要将这个插件屏蔽);
  6. 其他工程依赖此工程

mybatis整体架构

Mybatis源码分析(十七) - 源码包分析【日志模块】_ide

日志模块

  1. MyBatis没有提供日志的实现类,需要接入第三方的日志组件,但第三方日志组件都有各自的Log级别,且各不相同,二MyBatis统一提供了trace、debug、warn、error四个级别;
  2. 自动扫描日志实现,并且第三方日志插件加载优先级如下:slf4J → commonsLoging → Log4J2 → Log4J→ JdkLog;
  3. 日志的使用要优雅的嵌入到主体功能中;

日志模块类图

Mybatis源码分析(十七) - 源码包分析【日志模块】_apache_02

这里需要提到一种设计模式

适配器模式

适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁,将一个类的接口转换成客户希望的
另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作;

Target:目标角色,期待得到的接口.
Adaptee:适配者角色,被适配的接口.
Adapter:适配器角色,将源接口转换成目标接口.

Mybatis源码分析(十七) - 源码包分析【日志模块】_ide_03

适用场景:当调用双方都不太容易修改的时候,为了复用现有组件可以使用适配器模式;在系统中接入第三方组
件的时候经常被使用到;

注意:如果系统中存在过多的适配器,会增加系统的复杂性,设计人员应考虑对系统进行重构;

LogFactory

/**
* Copyright ${license.git.copyrightYears} the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.ibatis.logging;

import java.lang.reflect.Constructor;

/**
* @author Clinton Begin
* @author Eduardo Macarron
*/
public final class LogFactory {

/**
* Marker to be used by logging implementations that support markers
*/
public static final String MARKER = "MYBATIS";

//被选定的第三方日志组件适配器的构造方法
private static Constructor<? extends Log> logConstructor;

//自动扫描日志实现,并且第三方日志插件加载优先级如下:slf4J → commonsLoging → Log4J2 → Log4J → JdkLog
static {
tryImplementation(LogFactory::useSlf4jLogging);
tryImplementation(LogFactory::useCommonsLogging);
tryImplementation(LogFactory::useLog4J2Logging);
tryImplementation(LogFactory::useLog4JLogging);
tryImplementation(LogFactory::useJdkLogging);
tryImplementation(LogFactory::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(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 useLog4JLogging() {
setImplementation(org.apache.ibatis.logging.log4j.Log4jImpl.class);
}

public static synchronized void useLog4J2Logging() {
setImplementation(org.apache.ibatis.logging.log4j2.Log4j2Impl.class);
}

public static synchronized void useJdkLogging() {
setImplementation(org.apache.ibatis.logging.jdk14.Jdk14LoggingImpl.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) {//当构造方法不为空才执行方法
try {
runnable.run();
} catch (Throwable t) {
// ignore
}
}
}
//通过指定的log类来初始化构造方法
private static void setImplementation(Class<? extends Log> implClass) {
try {
Constructor<? extends Log> candidate = implClass.getConstructor(String.class);
Log log = candidate.newInstance(LogFactory.class.getName());
if (log.isDebugEnabled()) {
log.debug("Logging initialized using '" + implClass + "' adapter.");
}
logConstructor = candidate;
} catch (Throwable t) {
throw new LogException("Error setting Log implementation. Cause: " + t, t);
}
}

}

Log4jImpl类

/**
* Copyright ${license.git.copyrightYears} the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.ibatis.logging.log4j;

import org.apache.ibatis.logging.Log;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;

/**
* @author Eduardo Macarron
*/
public class Log4jImpl implements Log {

private static final String FQCN = Log4jImpl.class.getName();

private final Logger log;

public Log4jImpl(String clazz) {
log = Logger.getLogger(clazz);
}

@Override
public boolean isDebugEnabled() {
return log.isDebugEnabled();
}

@Override
public boolean isTraceEnabled() {
return log.isTraceEnabled();
}

@Override
public void error(String s, Throwable e) {
log.log(FQCN, Level.ERROR, s, e);
}

@Override
public void error(String s) {
log.log(FQCN, Level.ERROR, s, null);
}

@Override
public void debug(String s) {
log.log(FQCN, Level.DEBUG, s, null);
}

@Override
public void trace(String s) {
log.log(FQCN, Level.TRACE, s, null);
}

@Override
public void warn(String s) {
log.log(FQCN, Level.WARN, s, null);
}

}


结合上面的适配模式可以分析,Log4jImpl就是Apdater类,Log接口就是Target


LoggerFactory.getLogger(clazz)这个操作就是获取 org.apache.log4j.Logger 他就是Adaptee类

标签:log,void,apache,源码,static,Mybatis,org,日志,public
From: https://blog.51cto.com/u_14906615/5899414

相关文章

  • Mybatis源码分析(二十一) - 核心流程分析
    mybatis核心流程三大阶段初始化阶段读取XML配置文件和注解中的配置信息,创建配置对象,并完成各个模块的初始化的工作代理阶段封装iBatis的编程模型,使用mapper接口开发的初始化......
  • windows下编译调试 Elasticsearch 8.7.0 源码
    最近想从代码层面学习下ElasticSearch,于是下载代码并导入到idea中,开始一顿操作,gradle各种倒腾,还是没法直接从代码运行进程,最后选择了一种不那么直接的debug方法,远程......
  • tomcat源码分析-http请求在Container中的执行路线
     在CoyoteAdapter的service方法中,主要干了2件事:  1.org.apache.coyote.Request->org.apache.catalina.connector.RequestextendsHttpServletRequest     ......
  • easylogging++的那些事(四)源码分析(二)日志记录宏(四)VERBOSE日志宏
    目录CVLOG宏宏展开源码剖析CVLOG_EVERY_N宏宏展开源码剖析CVLOG_AFTER_N宏宏展开源码剖析CVLOG_N_TIMES宏宏展开源码剖析VLOG宏DCVLOG宏DVLOG宏VLOG_EVERY_N宏VLOG......
  • Java并发编程实战: AQS 源码 史上最详尽图解+逐行注释
    Java并发编程实战:AQS源码史上最详尽图解+逐行注释引言:学习一个java并发编程工具的时候,我们首先要抓住这三点:状态一般是一个state属性,它基本是整个工具的核心,通常整个......
  • apache 日志轮询 linux cronolog
    Linux下运行的Web服务器Apache,默认日志文件是不分割的,一个整文件既不易于管理,也不易于分析统计。安装cronolog后,可以将日志文件按时间分割,易于管理和分析。cronolog安装配置......
  • 直播app系统源码,canvas上放置按钮并实现点击之后全屏显示
    直播app系统源码,canvas上放置按钮并实现点击之后全屏显示html        <divstyle="">        <divclass="canvas-div">     ......
  • C#关于委托的一些事,开发日志
    -----委托是什么------其实委托事件很好理解,就当成是c语言中的函数指针或者是回调函数,或者说换种理解方式,信号和槽?触发器和接收器?总之就是一个地方调用了这个函数,那么在......
  • SQLServer 数据库事务日志已满 log_backup
      解决方案一:收缩日志1、属性-->选项-->恢复模式,设置为简单 2、任务-->收缩-->文件-->文件类型改成(日志)-->收缩操作选择(在释放为使用的空间前重新组织页),并设置收......
  • MybatisPlus 删除记录
    转自:https://blog.csdn.net/h470789634/article/details/124573252学习目标:mybatisplus的删除操作学习内容:delete使用学习产出:1、deleteById@Test   voiddeleteTes......