• mybatis源码——日志ErrorContext类


    一、特性表示

      mybatis的日志输出具有如下特性:

      (1)日志量随程序执行量增加(例如:xml文件中sql报错,那么一定会有初始化、xml加载等信息出现);

      (2)日志输出的顺序,是按顺序且隔离的;

    二、附上源代码

    package org.apache.ibatis.executor;
    
    /**
     * @author Clinton Begin
     */
    public class ErrorContext {
    
      private static final String LINE_SEPARATOR = System.getProperty("line.separator","
    ");
      private static final ThreadLocal<ErrorContext> LOCAL = new ThreadLocal<ErrorContext>();
    
      //暂存线程上下文
      private ErrorContext stored;
    
      private String sql;
      ... //各个阶段的值存储
    
      private Throwable cause;
    
      private ErrorContext() {
      }
    
      public static ErrorContext instance() {
        //单例模式,从当前线程获取线程存储变量(一个)
        ErrorContext context = LOCAL.get();
        if (context == null) {
          context = new ErrorContext();
          LOCAL.set(context);
        }
        return context;
      }
    
      public ErrorContext store() {
        stored = this;
        LOCAL.set(new ErrorContext());
        return LOCAL.get();
      }
    
      public ErrorContext recall() {
        if (stored != null) {
          LOCAL.set(stored);
          stored = null;
        }
        return LOCAL.get();
      }
    
      public ErrorContext sql(String sql) {
        //这种写法是流式编程
        this.sql = sql;
        return this;
      }
    
      public ErrorContext cause(Throwable cause) {
        this.cause = cause;
        return this;
      }
    
      public ErrorContext reset() {
        ...各个阶段记录初始化
        sql = null;
        
        LOCAL.remove();
        return this;
      }
    
      @Override
      public String toString() {
        StringBuilder description = new StringBuilder();
    
        ...各阶段日志输出
    
        // sql
        if (sql != null) {
          description.append(LINE_SEPARATOR);
          description.append("### SQL: ");
          description.append(sql.replace('
    ', ' ').replace('
    ', ' ').replace('	', ' ').trim());
        }
    
        // cause
        if (cause != null) {
          description.append(LINE_SEPARATOR);
          description.append("### Cause: ");
          description.append(cause.toString());
        }
    
        return description.toString();
      }
    
    }
    

      

    此处有几个值得借鉴的地方:

    (1)使用ThreadLocal<ErrorContext>类变量可以做到在当前线程执行的任何阶段保证只有一个类对象实例。即使说,只要是出于一个线程,不论走多少层方法栈都没关系,只要使用对应方法将对应阶段的信息记录下来,最终在所有操作完结的使用toString()一下就能将整个过程的信息输出出来。(否则就要将信息存储的类一个接一个方法地以形参方式传入)

    (2)每个记录方法都以类对象this返回,可以使用流式编程。简洁明了,可以直接将方法名.出来

  • 相关阅读:
    appium自动化测试(4)部分方法&unitest初步使用
    appium自动化测试(2)-工具(monitor、uiautomatorviewer)
    Appium自动化测试(1)-安装&环境
    echarts 地图 免费离线js,json包分享
    css动画Demo---水波动画和边框动画
    canvas绘制折线图(仿echarts)
    可编辑div中包含子元素时获取光标位置不准确的问题
    脚印
    从原理到代码之线性模型
    【ocelot】ocelot使用swagger
  • 原文地址:https://www.cnblogs.com/chendeming/p/9461681.html
Copyright © 2020-2023  润新知