Spring源码jcl模块学习

今天再看spring-jcl模块里的源码,这个模块是spring源码里最基础的模块没有依赖其他模块,它是为了兼容不同版本的日志系统。一看居然还有这种写法,看得我一愣一愣的,三层try嵌套,利用异常去做业务控制。采用适配器模式,和工厂模式

在虚拟机启动的时候确定项目用的是哪一种日志实现兼容

// LogAdapter 
static {
   ClassLoader cl = LogAdapter.class.getClassLoader();
   try {
      // Try Log4j 2.x API
      Class.forName("org.apache.logging.log4j.spi.ExtendedLogger", false, cl);
      logApi = LogApi.LOG4J;
   }
   catch (ClassNotFoundException ex1) {
      try {
         // Try SLF4J 1.7 SPI
         Class.forName("org.slf4j.spi.LocationAwareLogger", false, cl);
         logApi = LogApi.SLF4J_LAL;
      }
      catch (ClassNotFoundException ex2) {
         try {
            // Try SLF4J 1.7 API
            Class.forName("org.slf4j.Logger", false, cl);
            logApi = LogApi.SLF4J;
         }
         catch (ClassNotFoundException ex3) {
             // 使用默认的  java.util.logging
            // Keep java.util.logging as default
         }
      }
   }
}

根据确定的日志系统,创建日志对象

// LogAdapter
/** 选中的API创建真实的log对象
 * Create an actual {@link Log} instance for the selected API.
 * @param name the logger name
 */
public static Log createLog(String name) {
   switch (logApi) {
      case LOG4J:
         return Log4jAdapter.createLog(name);
      case SLF4J_LAL:
         return Slf4jAdapter.createLocationAwareLog(name);
      case SLF4J:
         return Slf4jAdapter.createLog(name);
      default:
         // Defensively use lazy-initializing adapter class here as well since the
         // java.logging module is not present by default on JDK 9. We are requiring
         // its presence if neither Log4j nor SLF4J is available; however, in the
         // case of Log4j or SLF4J, we are trying to prevent early initialization
         // of the JavaUtilLog adapter - e.g. by a JVM in debug mode - when eagerly
         // trying to parse the bytecode for all the cases of this switch clause.
         return JavaUtilAdapter.createLog(name);
   }
}

采用工厂模式去新建log对象

public abstract class LogFactory {
​
   /**
    * Convenience method to return a named logger.
    
    * @param clazz containing Class from which a log name will be derived
    */
   public static Log getLog(Class clazz) {
      return getLog(clazz.getName());
   }
​
   /**
    * Convenience method to return a named logger.
    * @param name logical name of the Log instance to be returned
    */
   public static Log getLog(String name) {
      return LogAdapter.createLog(name);
   }
​
   /**
    * This method only exists for compatibility with unusual Commons Logging API
    * usage like e.g. {@code LogFactory.getFactory().getInstance(Class/String)}.
    * @see #getInstance(Class)
    * @see #getInstance(String)
    * @deprecated in favor of {@link #getLog(Class)}/{@link #getLog(String)}
    */
   @Deprecated
   public static LogFactory getFactory() {
      return new LogFactory() {};
   }
​
   /**
    * Convenience method to return a named logger.
    * 

This variant just dispatches straight to {@link #getLog(Class)}. * @param clazz containing Class from which a log name will be derived * @deprecated in favor of {@link #getLog(Class)} */ @Deprecated public Log getInstance(Class clazz) { return getLog(clazz); } ​ /** * Convenience method to return a named logger. *

This variant just dispatches straight to {@link #getLog(String)}. * @param name logical name of the Log instance to be returned * @deprecated in favor of {@link #getLog(String)} */ @Deprecated public Log getInstance(String name) { return getLog(name); } ​ }

你可能感兴趣的:(java)