Mybatis原理分析之五:日志

logging包结构

一 概述

本包主要依赖Mybatis的reflection包的ExceptionUtil和io包的Resources,以及第三方的Log4j,Slf4j,CommonsLoging

logging包对其他包只有少量依赖,其他包对logging包有大量依赖

二 核心类和接口

Log接口 提供四种级别的日志

void error(String s);

void debug(String s);

void trace(String s);

void warn(String s);

LogFactory 工厂类 工厂模式 单例模式 根据传入的类或类名构建日志类

在静态代码里加载log实现类

static {
  //这边乍一看以为开了几个并行的线程去决定使用哪个具体框架的logging,其实不然
  //slf4j
  tryImplementation(new Runnable() {
    @Override
    public void run() {
      useSlf4jLogging();
    }
  });
  //common logging
  tryImplementation(new Runnable() {
    @Override
    public void run() {
      useCommonsLogging();
    }
  });
  //log4j2
  tryImplementation(new Runnable() {
    @Override
    public void run() {
      useLog4J2Logging();
    }
  });
  //log4j
  tryImplementation(new Runnable() {
    @Override
    public void run() {
      useLog4JLogging();
    }
  });
  //jdk logging
  tryImplementation(new Runnable() {
    @Override
    public void run() {
      useJdkLogging();
    }
  });
  //没有日志
  tryImplementation(new Runnable() {
    @Override
    public void run() {
      useNoLogging();
    }
  });
}
根据日志的构造器实例化日志

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,一旦设上,表明找到相应的log的jar包了,那后面别的log就不找了。
    logConstructor = candidate;
  } catch (Throwable t) {
    throw new LogException("Error setting Log implementation.  Cause: " + t, t);
  }
}
加载顺序:

slf4j-->
common logging-->
log4j2-->
log4j-->
jdk logging-->
没有日志
获得日志类的接口:

//根据传入的类来构建Log
public static Log getLog(Class<?> aClass) {
  return getLog(aClass.getName());
}

//根据传入的类名来构建Log
public static Log getLog(String logger) {
  try {
    //构造函数,参数必须是一个,为String型,指明logger的名称
    return logConstructor.newInstance(new Object[] { logger });
  } catch (Throwable t) {
    throw new LogException("Error creating logger for logger " + logger + ".  Cause: " + t, t);
  }
}
三 日志的7中实现

把日志抽象成Log接口,该接口有7种实现。
  1.Apache Commons Logging
  2.JDBC Logging
  3.Java Util Logging
  4.Log4j
  5.No Logging
  6.Slf4J
  7.Stdout
 
 7种实现分别位于logging包的7个子包中:commons,jdbc,jdk14,log4j,nologging,slf4j,stdout。
 
 
 1.commons包下的JakartaCommonsLoggingImpl使用Apache Commons Logging包实现了Log接口。
 
 2.jdbc包下的类 并没有直接实现Log接口,而是将Log接口作为自身的一个属性。
 
 BaseJdbcLogger:代理类的父类,代理类增加了logging功能。
 
 ConnectionLogger, PreparedStatementLogger, ResultSetLogger,StatementLogger都继承了BaseJdbcLogger,
 实现了InvocationHandler 接口。
 
 ConnectionLogger:Connection的代理类,增加了日志功能。
 
 PreparedStatementLogger:PreparedStatement的代理类,增加了日志功能。
 
 ResultSetLogger:ResultSet的代理类,增加了日志功能。
 
 StatementLogger:Statement的代理类,增加了日志功能。
 
 
 
 3.jdk14包下的Jdk14LoggingImpl 使用java.util.logging.Logger和java.util.logging.Level 2个类实现了Log接口。
 
 4.log4j包下的Log4jImpl 使用 Log4J包实现了 Log接口。
 
 5.nologging包下的NoLoggingImpl 空实现了 Log接口,即Log接口的实现方法没有意义,或者没有任何代码。
 
 6.slf4j包下的Slf4jImpl,Slf4jLocationAwareLoggerImpl,Slf4jLoggerImpl 都使用Slf4J包 实现了 Log接口。
 
 7.stdout包下的StdOutImpl使用 System.err.println(s)和System.out.println(s) 实现了Log接口。




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值