/* * Copyright 2009-2013 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 */ //给支持marker功能的logger使用(目前有slf4j, log4j2) public static final String MARKER = "MYBATIS"; //具体究竟用哪个日志框架,那个框架所对应logger的构造函数 private static Constructor<? extends Log> logConstructor; 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(); } }); } //单例模式,不得自己new实例 private LogFactory() { // disable construction } //根据传入的类来构建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); } } //提供一个扩展功能,如果以上log都不满意,可以使用自定义的log 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 { //这里调用的不是start,而是run!根本就没用多线程嘛! runnable.run(); } catch (Throwable t) { // ignore } } } 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); } } }