MyBatis Source article - logging module 1

Java developers customary in the log framework Log4j, Log4j2, Apache Common Log, java.util.logging, slf4j etc., these interfaces provide external logging framework varies. This chapter describes in detail how MyBatis integration and reuse of these third-party frameworks, by way of the adapter.

 

Log Adapter

MyBatis log module located org.apache.ibatis.logging package, the module interface defines the function log Log module, and then respectively different framework defines different log log adapter, these adapters are inherited logs Log interfaces, plant LogFactory responsible for creating the corresponding log frame adapter.

image.png

Let's look at the log jdk14 adapter mode class diagram:

image.png

When LogFactory class loader performs its fast static code, loaded and instantiated adapter frame corresponding to the log in order then to third recording adapter logging framework currently used by logConstructor field.

tryImplementation () method uses a try cache to capture information about loading the logging framework exception generated in the process, and in the cache did not do anything, so there will not be thrown exception information, the normal execution. If you do not introduce any logging framework, it will use useJdkLogging, which comes with the JDK logging facility.

public  end  class LogFactory {

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

  // constructor method of recording a third-party logging framework currently in use adapters 
  Private  static <? Constructor the extends the Log> logConstructor;

  // try to load a log of each frame, the calling sequence is:
   // useSlf4jLogging -> useCommonsLogging -> useLog4J2Logging -> 
   // useLog4JLogging -> useJdkLogging -> useNoLogging 
  static {
    tryImplementation(new Runnable() {
      @Override
      public void run() {
        useSlf4jLogging();
      }
    });
    tryImplementation(new Runnable() {
      @Override
      public void run() {
        useCommonsLogging();
      }
    });
    tryImplementation(new Runnable() {
      @Override
      public void run() {
        useLog4J2Logging();
      }
    });
    tryImplementation(new Runnable() {
      @Override
      public void run() {
        useLog4JLogging();
      }
    });
    tryImplementation(new Runnable() {
      @Override
      public void run() {
        useJdkLogging ();
      }
    });
    tryImplementation(new Runnable() {
      @Override
      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(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);
  }

  // try to load logging framework 
  Private  static  void tryImplementation (the Runnable Runnable) {
     IF (logConstructor == null ) {
       the try {
        runnable.run();
      } The catch (the Throwable T) {
         // load exception is ignored
         // the ignore 
      }
    }
  }

  Private  static  void setImplementation (<? Class the extends the Log> implClass) {
     the try {
       // Get the specified adapter constructor 
      the Constructor <? the extends Candidate implClass.getConstructor = (String. the Log> class );
       // instantiate the adapter 
      Log log = candidate .newInstance (LogFactory. class .getName ());
       // output log 
      IF (log.isDebugEnabled ()) {
        log.debug("Logging initialized using '" + implClass + "' adapter.");
      }
      // Initialization logConstructor field 
      logConstructor = Candidate;
    } catch (Throwable t) {
      throw new LogException("Error setting Log implementation.  Cause: " + t, t);
    }
  }

}

Logging framework introduced SLF4J

SLF4J just logging framework unified interface definition (Reference: http://www.slf4j.org/manual.html ), also we need to introduce achieve, pom.xml file add the following:

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.28</version>
</dependency>

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-simple</artifactId>
    <version>1.7.28</version>
    <scope>test</scope>
</dependency>

When LogFactory class loading, static code block will be initialized logConstructor SLF4J adapter constructor.

Log level configuration file by simplelogger.properties Debug property, attribute file name is fixed, reference org.slf4j.impl.SimpleLoggerConfiguration categories:

image.png

Perform a simple query operation, outputs the following log information:

[main] DEBUG org.apache.ibatis.logging.LogFactory - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
[main] DEBUG org.apache.ibatis.datasource.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
[main] DEBUG org.apache.ibatis.datasource.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
[main] DEBUG org.apache.ibatis.datasource.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
[main] DEBUG org.apache.ibatis.datasource.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
[main] DEBUG org.apache.ibatis.transaction.jdbc.JdbcTransaction - Opening JDBC Connection
[main] DEBUG org.apache.ibatis.datasource.pooled.PooledDataSource - Created connection 1426329391.
[main] DEBUG com.yjw.mybatis.dao.StudentMapper.selectByPrimaryKey - ==>  Preparing: select id, name, sex, selfcard_no, note from t_student where id = ? 
[main] DEBUG com.yjw.mybatis.dao.StudentMapper.selectByPrimaryKey - ==> Parameters: 1(Long)
[main] DEBUG com.yjw.mybatis.dao.StudentMapper.selectByPrimaryKey - <==      Total: 1

Slf4jImpl org.apache.ibatis.logging.Log class implements the interface, and the interface encapsulates SLF4J log, all logs of the interface function Log interface by calling the SLF4J.

Constructor implemented Slf4jImpl distinction SLF4J version using a different interface versions depending on logging, the following source code:

public class Slf4jImpl implements Log {

  private Log log;

  public Slf4jImpl(String clazz) {
    Log log = LoggerFactory.getLogger (Clazz);

    if (logger instanceof LocationAwareLogger) {
      try {
        // check for slf4j >= 1.6 method signature
        logger.getClass().getMethod("log", Marker.class, String.class, int.class, String.class, Object[].class, Throwable.class);
        log = new Slf4jLocationAwareLoggerImpl((LocationAwareLogger) logger);
        return;
      } catch (SecurityException e) {
        // fail-back to Slf4jLoggerImpl
      } catch (NoSuchMethodException e) {
        // fail-back to Slf4jLoggerImpl
      }
    }

    // Logger is not LocationAwareLogger or slf4j version < 1.6
    log = new Slf4jLoggerImpl(logger);
  }

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

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

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

  @Override
  public void error(String s) {
    log.error(s);
  }

  @Override
  public void debug(String s) {
    log.debug(s);
  }

  @Override
  public void trace(String s) {
    log.trace(s);
  }

  @Override
  public void warn(String s) {
    log.warn(s);
  }

}

 

MyBatis source article

Guess you like

Origin www.cnblogs.com/yinjw/p/11757433.html
Recommended