commons-logging 源码之 log4j 集成

注意
需要阅读: commons-logging 源码分析 之后才可以阅读本文

添加maven引用

       <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>

基本使用

新建测试类

public class Main {
    public static void main(String[] args) {
        Log logger = LogFactory.getLog(Main.class);
        logger.info("message");
    }
}

新建 log4j.properties

log4j.rootLogger=DEBUG, stdout

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p  %c:%L - %m%n

分析 LogFactoryImpl 的 newInstance 方法

protected Log newInstance(String name) throws LogConfigurationException {
        Log instance;
        try {
            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;

        } catch (LogConfigurationException lce) {
            throw lce;

        } catch (InvocationTargetException e) {

            Throwable c = e.getTargetException();
            throw new LogConfigurationException(c == null ? e : c);
        } catch (Throwable t) {
            handleThrowable(t); // may re-throw t
            throw new LogConfigurationException(t);
        }
    }

discoverLogImplementation

private Log discoverLogImplementation(String logCategory)
        throws LogConfigurationException {
        if (isDiagnosticsEnabled()) {
            logDiagnostic("Discovering a Log implementation...");
        }

        initConfiguration();

        Log result = null;

        // See if the user specified the Log implementation to use
        //用户没有指定log类
        String specifiedLogClassName = findUserSpecifiedLogClassName();

        if (specifiedLogClassName != null) {
            if (isDiagnosticsEnabled()) {
                logDiagnostic("Attempting to load user-specified log class '" +
                    specifiedLogClassName + "'...");
            }

            result = createLogFromClass(specifiedLogClassName,
                                        logCategory,
                                        true);
            if (result == null) {
                StringBuffer messageBuffer =  new StringBuffer("User-specified log class '");
                messageBuffer.append(specifiedLogClassName);
                messageBuffer.append("' cannot be found or is not useable.");


                informUponSimilarName(messageBuffer, specifiedLogClassName, LOGGING_IMPL_LOG4J_LOGGER);
                informUponSimilarName(messageBuffer, specifiedLogClassName, LOGGING_IMPL_JDK14_LOGGER);
                informUponSimilarName(messageBuffer, specifiedLogClassName, LOGGING_IMPL_LUMBERJACK_LOGGER);
                informUponSimilarName(messageBuffer, specifiedLogClassName, LOGGING_IMPL_SIMPLE_LOGGER);
                throw new LogConfigurationException(messageBuffer.toString());
            }

            return result;
        }



        if (isDiagnosticsEnabled()) {
            logDiagnostic(
                "No user-specified Log implementation; performing discovery" +
                " using the standard supported logging implementations...");
        }
        //    private static final String LOGGING_IMPL_LOG4J_LOGGER = "org.apache.commons.logging.impl.Log4JLogger";
        /*
            private static final String[] classesToDiscover = {
            LOGGING_IMPL_LOG4J_LOGGER,
            "org.apache.commons.logging.impl.Jdk14Logger",
            "org.apache.commons.logging.impl.Jdk13LumberjackLogger",
            "org.apache.commons.logging.impl.SimpleLog"
    };
        */
        // 从classesToDiscover创建Log,直到result!=null 或者遍历结束
        for(int i=0; i<classesToDiscover.length && result == null; ++i) {
            result = createLogFromClass(classesToDiscover[i], logCategory, true);
        }

        if (result == null) {
            throw new LogConfigurationException
                        ("No suitable Log implementation");
        }

        return result;
    }

createLogFromClass

 private Log createLogFromClass(String logAdapterClassName,
                                   String logCategory,
                                   boolean affectState)
        throws LogConfigurationException {

        if (isDiagnosticsEnabled()) {
            logDiagnostic("Attempting to instantiate '" + logAdapterClassName + "'");
        }

        Object[] params = { logCategory };
        Log logAdapter = null;
        Constructor constructor = null;

        Class logAdapterClass = null;
        ClassLoader currentCL = getBaseClassLoader();

        for(;;) {
            // Loop through the classloader hierarchy trying to find
            // a viable classloader.
            logDiagnostic("Trying to load '" + logAdapterClassName + "' from classloader " + objectId(currentCL));
            try {
                if (isDiagnosticsEnabled()) {

                    URL url;

                    String resourceName = logAdapterClassName.replace('.', '/') + ".class";
                    //resourceName = "org/apache/commons/logging/impl/Log4JLogger.class"
                    if (currentCL != null) {
                        url = currentCL.getResource(resourceName );
                    } else {
                        url = ClassLoader.getSystemResource(resourceName + ".class");
                    }

                    if (url == null) {
                        logDiagnostic("Class '" + logAdapterClassName + "' [" + resourceName + "] cannot be found.");
                    } else {
                        logDiagnostic("Class '" + logAdapterClassName + "' was found at '" + url + "'");
                    }
                }

                Class c;
                try {
                //尝试载入:org.apache.commons.logging.impl.Log4JLogger ,不存在时就退出
                    c = Class.forName(logAdapterClassName, true, currentCL);
                } catch (ClassNotFoundException originalClassNotFoundException) {

                    String msg = originalClassNotFoundException.getMessage();
                    logDiagnostic("The log adapter '" + logAdapterClassName + "' is not available via classloader " +
                                  objectId(currentCL) + ": " + msg.trim());
                    try {

                        c = Class.forName(logAdapterClassName);
                    } catch (ClassNotFoundException secondaryClassNotFoundException) {
                        // no point continuing: this adapter isn't available
                        msg = secondaryClassNotFoundException.getMessage();
                        logDiagnostic("The log adapter '" + logAdapterClassName +
                                      "' is not available via the LogFactoryImpl class classloader: " + msg.trim());
                        break;
                    }
                }
// 获取构造器  Constructor(String)
                constructor = c.getConstructor(logConstructorSignature);
                // 创建实例,org.apache.commons.logging.impl.Log4JLogger
                //params=com.aya.Main
                Object o = constructor.newInstance(params);


                if (o instanceof Log) {
                //日志代理类:org.apache.commons.logging.impl.Log4JLogger
                    logAdapterClass = c;
                    //获的日志代理,退出循环
                    logAdapter = (Log) o;
                    break;
                }


                handleFlawedHierarchy(currentCL, c);
            } catch (NoClassDefFoundError e) {

                String msg = e.getMessage();
                logDiagnostic("The log adapter '" + logAdapterClassName +
                              "' is missing dependencies when loaded via classloader " + objectId(currentCL) +
                              ": " + msg.trim());
                break;
            } catch (ExceptionInInitializerError e) {

                String msg = e.getMessage();
                logDiagnostic("The log adapter '" + logAdapterClassName +
                              "' is unable to initialize itself when loaded via classloader " + objectId(currentCL) +
                              ": " + msg.trim());
                break;
            } catch (LogConfigurationException e) {

                throw e;
            } catch (Throwable t) {
                handleThrowable(t); // may re-throw t

                handleFlawedDiscovery(logAdapterClassName, currentCL, t);
            }

            if (currentCL == null) {
                break;
            }

            // try the parent classloader
            // currentCL = currentCL.getParent();
            currentCL = getParentClassLoader(currentCL);
        }
// 在commons-logging 源码分析已经分析过....
        if (logAdapterClass != null && affectState) {
            // We've succeeded, so set instance fields
            this.logClassName   = logAdapterClassName;
            this.logConstructor = constructor;

            // Identify the <code>setLogFactory</code> method (if there is one)
            try {
                this.logMethod = logAdapterClass.getMethod("setLogFactory", logMethodSignature);
                logDiagnostic("Found method setLogFactory(LogFactory) in '" + logAdapterClassName + "'");
            } catch (Throwable t) {
                handleThrowable(t); // may re-throw t
                this.logMethod = null;
                logDiagnostic("[INFO] '" + logAdapterClassName + "' from classloader " + objectId(currentCL) +
                              " does not declare optional method " + "setLogFactory(LogFactory)");
            }

            logDiagnostic("Log adapter '" + logAdapterClassName + "' from classloader " +
                          objectId(logAdapterClass.getClassLoader()) + " has been selected for use.");
        }

        return logAdapter;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值