日志门面技术

1.JCL

public abstract class LogFactory {

	public static Log getLog(Class clazz) throws LogConfigurationException {
		// 默认实现类为LogFactoryImpl
        return getFactory().getInstance(clazz);
    }
}

利用LogFactoryImpl实例化具体的日志框架。其中,如果存在log4j依赖则选择Log4JLogger,Jdk14Logger是指JDK本身集成的JUL,否则使用JCL本身自带的日志实现之SimpleLog。

public class LogFactoryImpl extends LogFactory {

	protected Constructor logConstructor = null;
	
	private static final String[] classesToDiscover = {
            "org.apache.commons.logging.impl.Log4JLogger",
            "org.apache.commons.logging.impl.Jdk14Logger",
            "org.apache.commons.logging.impl.Jdk13LumberjackLogger",
            "org.apache.commons.logging.impl.SimpleLog"
    }
    
	protected Log newInstance(String name) throws LogConfigurationException {
	    Log instance;
	     if (logConstructor == null) {
             instance = discoverLogImplementation(name);
         }else {
            Object params[] = { name };
            instance = (Log) logConstructor.newInstance(params);
         }
		if (logMethod != null) {
            Object params[] = { this };
            logMethod.invoke(instance, params);
        }
        return instance;
	}
	
	private Log discoverLogImplementation(String logCategory)throws LogConfigurationException {
        ...
        for(int i=0; i<classesToDiscover.length && result == null; ++i) {
            result = createLogFromClass(classesToDiscover[i], logCategory, true);
        }
        return result;
    }
	
	private Log createLogFromClass(String logAdapterClassName,String logCategory,boolean affectState){
        Object[] params = { logCategory };
        Log logAdapter = null;
        Constructor constructor = null;
        Class logAdapterClass = null;
        ClassLoader currentCL = getBaseClassLoader();

        for(;;) {
            ...
            Class  c = Class.forName(logAdapterClassName, true, currentCL);
            constructor = c.getConstructor(logConstructorSignature);
            Object o = constructor.newInstance(params);
            if (o instanceof Log) {
                logAdapterClass = c;
                logAdapter = (Log) o;
                break;
            }
            handleFlawedHierarchy(currentCL, c);
            if (currentCL == null) {
                break;
            }
            currentCL = getParentClassLoader(currentCL);
        }
		...
        return logAdapter;
    }
}

2.Slf4j

StaticLoggerBinder是存在于各种日志适配桥接相关的依赖中,并且在不同依赖中该类的全限定名都为:org.slf4j.impl.StaticLoggerBinder。

例如,slf4j-jdk14是Slf4j对JUL适配的相关依赖,在其包中的类StaticLoggerBinder引入jul相关的日志核心类JDK14LoggerFactory。

public class JDK14LoggerFactory implements ILoggerFactory {
    ConcurrentMap<String, Logger> loggerMap;
    public JDK14LoggerFactory() {
        java.util.logging.Logger.getLogger("");//获取JDK自带的日志框架实现
    }
}

slf4j-log4j12是Slf4j对log4j适配的相关依赖,在其包中的类StaticLoggerBinder引入log4j相关的日志核心类Log4jLoggerFactory。

public class Log4jLoggerFactory implements ILoggerFactory {
	
    ConcurrentMap<String, Logger> loggerMap;

    public Log4jLoggerFactory() {
        loggerMap = new ConcurrentHashMap<String, Logger>();
        // force log4j to initialize
        org.apache.log4j.LogManager.getRootLogger();//获取log4j自带的日志框架实现
    }
}
public final class LoggerFactory {

	private static String STATIC_LOGGER_BINDER_PATH = "org/slf4j/impl/StaticLoggerBinder.class";
	
	public static Logger getLogger(String name) {
	    ILoggerFactory iLoggerFactory = getILoggerFactory();
	    return iLoggerFactory.getLogger(name);
	}
	
	public static ILoggerFactory getILoggerFactory() {
        if (INITIALIZATION_STATE == 0) {
            synchronized (LoggerFactory.class) {
                if (INITIALIZATION_STATE == 0) {
                    INITIALIZATION_STATE = 1;
                    performInitialization();
                }
            }
        }
        switch (INITIALIZATION_STATE) {
        case SUCCESSFUL_INITIALIZATION:
            return StaticLoggerBinder.getSingleton().getLoggerFactory();
        case NOP_FALLBACK_INITIALIZATION:
            return NOP_FALLBACK_FACTORY;
        case FAILED_INITIALIZATION:
            throw new IllegalStateException(UNSUCCESSFUL_INIT_MSG);
        case ONGOING_INITIALIZATION:
            return SUBST_FACTORY;
        }
        throw new IllegalStateException("Unreachable code");
    }
	
	private final static void performInitialization() {
        bind();
    }
	
	private final static void bind() {
        Set<URL> staticLoggerBinderPathSet = null;
        if (!isAndroid()) {
            staticLoggerBinderPathSet = findPossibleStaticLoggerBinderPathSet();
            reportMultipleBindingAmbiguity(staticLoggerBinderPathSet);
        }
        // the next line does the binding
        StaticLoggerBinder.getSingleton();
        INITIALIZATION_STATE = SUCCESSFUL_INITIALIZATION;
        reportActualBinding(staticLoggerBinderPathSet);
        fixSubstituteLoggers();
        replayEvents();
        // release all resources in SUBST_FACTORY
        SUBST_FACTORY.clear();
    }
	
	static Set<URL> findPossibleStaticLoggerBinderPathSet() {
        Set<URL> staticLoggerBinderPathSet = new LinkedHashSet<URL>();
        ClassLoader loggerFactoryClassLoader = LoggerFactory.class.getClassLoader();
        Enumeration<URL> paths;
        //利用StaticLoggerBinder引入具体的日志框架
        if (loggerFactoryClassLoader == null) {
            paths = ClassLoader.getSystemResources(STATIC_LOGGER_BINDER_PATH);
        } else {
            paths = loggerFactoryClassLoader.getResources(STATIC_LOGGER_BINDER_PATH);
        }
        while (paths.hasMoreElements()) {
            URL path = paths.nextElement();
            staticLoggerBinderPathSet.add(path);
        }
        return staticLoggerBinderPathSet;
    }
}

你可能感兴趣的:(java)