C3P0的XML配置文件是由哪个类加载的

C3P0的XML配置文件是由哪个类加载的

 前几天在看JDBC连接时候,用到了C3P0连接池进行连接,想起XML的名字必须叫c3p0-config.xml就很好奇,然后又觉得

既然是xml文件,肯定是有加载xml文件的类。于是我的强迫症就发作了,所以我就一直debug源码,一直找,一直找
功夫不负有心人,让哥哥我终于找到了,下面直接上代码:

我写的测试类
首先是由ComboPooledDataSource类进入,接着是进入构造方法
在这里插入图片描述
然后构造方法又跳转到super(autoregister),也就是AbstractPoolBackedDataSource类下如下
在这里插入图片描述
然后继续加载super(autoregister),到继承类PoolBackedDataSourceBase的构造方法,如下
在这里插入图片描述
然后到这一步就关键了,按照我基本的java知识,这个时候是先执行PoolBackedDataSourceBase类static代码块,然后对类上的成员变量赋值的。该类的成员变量如下:
在这里插入图片描述
然后加载C3P0Config类,在该类下有static代码块,然后继续加载该代码块:

 static {
        logger = MLog.getLogger(C3P0Config.class);
        String cname = MultiPropertiesConfig.readVmConfig().getProperty("com.mchange.v2.c3p0.cfg.finder");
        Object cfgFinder = null;

        try {
            if (cname != null) {
                cfgFinder = (C3P0ConfigFinder)Class.forName(cname).newInstance();
            }
        } catch (Exception var6) {
            if (logger.isLoggable(MLevel.WARNING)) {
                logger.log(MLevel.WARNING, "Could not load specified C3P0ConfigFinder class'" + cname + "'.", var6);
            }
        }

        C3P0Config protoMain;
        try {
            if (cfgFinder == null) {
                Class.forName("org.w3c.dom.Node");
                Class.forName("com.mchange.v2.c3p0.cfg.C3P0ConfigXmlUtils");
                cfgFinder = new DefaultC3P0ConfigFinder();
            }

            protoMain = ((C3P0ConfigFinder)cfgFinder).findConfig();
        } catch (Exception var5) {
            if (logger.isLoggable(MLevel.WARNING)) {
                logger.log(MLevel.WARNING, "XML configuration disabled! Verify that standard XML libs are available.", var5);
            }

            HashMap flatDefaults = C3P0ConfigUtils.extractHardcodedC3P0Defaults();
            flatDefaults.putAll(C3P0ConfigUtils.extractC3P0PropertiesResources());
            protoMain = C3P0ConfigUtils.configFromFlatDefaults(flatDefaults);
        }

        MAIN = protoMain;
        warnOnUnknownProperties(MAIN);
        SUOAS_ARGS = new Class[]{String.class};
        SKIP_BIND_PROPS = Arrays.asList("loginTimeout", "properties");
    }
从该代码块我们可以看到,  Class.forName("com.mchange.v2.c3p0.cfg.C3P0ConfigXmlUtils");

OK,现在终于水落石出了,是由C3P0ConfigXmlUtils这个类加载的,从这个类我们知道
配置文件名是写死的:XML_CONFIG_RSRC_PATH = “/c3p0-config.xml”;而且如果你不是这个名字,还会报错: logger.warning(“POSSIBLY MISSPELLED c3p0-conf.xml RESOURCE FOUND. Please ensure the file name is c3p0-config.xml, all lower case, with the digit 0 (NOT the letter O) in c3p0. It should be placed in the top level of c3p0’s effective classpath.”);
然后xml文件是用下面这种方法解析的
在这里插入图片描述
这个类的源码如下:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.mchange.v2.c3p0.cfg;

import com.mchange.v1.xml.DomParseUtils;
import com.mchange.v2.log.MLevel;
import com.mchange.v2.log.MLog;
import com.mchange.v2.log.MLogger;
import java.io.InputStream;
import java.util.HashMap;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

public final class C3P0ConfigXmlUtils {
    public static final String XML_CONFIG_RSRC_PATH = "/c3p0-config.xml";
    static final MLogger logger;
    public static final String LINESEP;
    private static final String[] MISSPELL_PFXS;
    private static final char[] MISSPELL_LINES;
    private static final String[] MISSPELL_CONFIG;
    private static final String[] MISSPELL_XML;

    private static final void warnCommonXmlConfigResourceMisspellings() {
        if (logger.isLoggable(MLevel.WARNING)) {
            int a = 0;

            for(int lena = MISSPELL_PFXS.length; a < lena; ++a) {
                StringBuffer sb = new StringBuffer(16);
                sb.append(MISSPELL_PFXS[a]);
                int b = 0;

                for(int lenb = MISSPELL_LINES.length; b < lenb; ++b) {
                    sb.append(MISSPELL_LINES[b]);
                    int c = 0;

                    for(int lenc = MISSPELL_CONFIG.length; c < lenc; ++c) {
                        sb.append(MISSPELL_CONFIG[c]);
                        sb.append('.');
                        int d = 0;

                        for(int lend = MISSPELL_XML.length; d < lend; ++d) {
                            sb.append(MISSPELL_XML[d]);
                            String test = sb.toString();
                            if (!test.equals("/c3p0-config.xml")) {
                                Object hopefullyNull = C3P0ConfigXmlUtils.class.getResource(test);
                                if (hopefullyNull != null) {
                                    logger.warning("POSSIBLY MISSPELLED c3p0-conf.xml RESOURCE FOUND. Please ensure the file name is c3p0-config.xml, all lower case, with the digit 0 (NOT the letter O) in c3p0. It should be placed  in the top level of c3p0's effective classpath.");
                                    return;
                                }
                            }
                        }
                    }
                }
            }
        }

    }

    public static C3P0Config extractXmlConfigFromDefaultResource() throws Exception {
        InputStream is = null;

        C3P0Config var1;
        try {
            is = C3P0ConfigUtils.class.getResourceAsStream("/c3p0-config.xml");
            if (is == null) {
                warnCommonXmlConfigResourceMisspellings();
                var1 = null;
                return var1;
            }

            var1 = extractXmlConfigFromInputStream(is);
        } finally {
            try {
                if (is != null) {
                    is.close();
                }
            } catch (Exception var9) {
                if (logger.isLoggable(MLevel.FINE)) {
                    logger.log(MLevel.FINE, "Exception on resource InputStream close.", var9);
                }
            }

        }

        return var1;
    }

    public static C3P0Config extractXmlConfigFromInputStream(InputStream is) throws Exception {
        DocumentBuilderFactory fact = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = fact.newDocumentBuilder();
        Document doc = db.parse(is);
        return extractConfigFromXmlDoc(doc);
    }

    public static C3P0Config extractConfigFromXmlDoc(Document doc) throws Exception {
        Element docElem = doc.getDocumentElement();
        if (!docElem.getTagName().equals("c3p0-config")) {
            throw new Exception("Root element of c3p0 config xml should be 'c3p0-config', not '" + docElem.getTagName() + "'.");
        } else {
            HashMap configNamesToNamedScopes = new HashMap();
            Element defaultConfigElem = DomParseUtils.uniqueChild(docElem, "default-config");
            NamedScope defaults;
            if (defaultConfigElem != null) {
                defaults = extractNamedScopeFromLevel(defaultConfigElem);
            } else {
                defaults = new NamedScope();
            }

            NodeList nl = DomParseUtils.immediateChildElementsByTagName(docElem, "named-config");
            int i = 0;

            for(int len = nl.getLength(); i < len; ++i) {
                Element namedConfigElem = (Element)nl.item(i);
                String configName = namedConfigElem.getAttribute("name");
                if (configName != null && configName.length() > 0) {
                    NamedScope namedConfig = extractNamedScopeFromLevel(namedConfigElem);
                    configNamesToNamedScopes.put(configName, namedConfig);
                } else {
                    logger.warning("Configuration XML contained named-config element without name attribute: " + namedConfigElem);
                }
            }

            return new C3P0Config(defaults, configNamesToNamedScopes);
        }
    }

    private static NamedScope extractNamedScopeFromLevel(Element elem) {
        HashMap props = extractPropertiesFromLevel(elem);
        HashMap userNamesToOverrides = new HashMap();
        NodeList nl = DomParseUtils.immediateChildElementsByTagName(elem, "user-overrides");
        int i = 0;

        for(int len = nl.getLength(); i < len; ++i) {
            Element perUserConfigElem = (Element)nl.item(i);
            String userName = perUserConfigElem.getAttribute("user");
            if (userName != null && userName.length() > 0) {
                HashMap userProps = extractPropertiesFromLevel(perUserConfigElem);
                userNamesToOverrides.put(userName, userProps);
            } else {
                logger.warning("Configuration XML contained user-overrides element without user attribute: " + LINESEP + perUserConfigElem);
            }
        }

        return new NamedScope(props, userNamesToOverrides);
    }

    private static HashMap extractPropertiesFromLevel(Element elem) {
        HashMap out = new HashMap();

        try {
            NodeList nl = DomParseUtils.immediateChildElementsByTagName(elem, "property");
            int len = nl.getLength();

            for(int i = 0; i < len; ++i) {
                Element propertyElem = (Element)nl.item(i);
                String propName = propertyElem.getAttribute("name");
                if (propName != null && propName.length() > 0) {
                    String propVal = DomParseUtils.allTextFromElement(propertyElem, true);
                    out.put(propName, propVal);
                } else {
                    logger.warning("Configuration XML contained property element without name attribute: " + LINESEP + propertyElem);
                }
            }
        } catch (Exception var8) {
            logger.log(MLevel.WARNING, "An exception occurred while reading config XML. Some configuration information has probably been ignored.", var8);
        }

        return out;
    }

    private C3P0ConfigXmlUtils() {
    }

    static {
        logger = MLog.getLogger(C3P0ConfigXmlUtils.class);
        MISSPELL_PFXS = new String[]{"/c3p0", "/c3pO", "/c3po", "/C3P0", "/C3PO"};
        MISSPELL_LINES = new char[]{'-', '_'};
        MISSPELL_CONFIG = new String[]{"config", "CONFIG"};
        MISSPELL_XML = new String[]{"xml", "XML"};

        String ls;
        try {
            ls = System.getProperty("line.separator", "\r\n");
        } catch (Exception var2) {
            ls = "\r\n";
        }

        LINESEP = ls;
    }
}

引申关于Class.froName:源码如下:
  @CallerSensitive
    public static Class<?> forName(String className)
                throws ClassNotFoundException {
        Class<?> caller = Reflection.getCallerClass();
        return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
    }

官方文档解释如下:

Returns the Class object associated with the class or interface with the given string name, using the given class loader. Given the fully qualified name for a class or interface (in the same format returned by getName) this method attempts to locate, load, and link the class or interface. The specified class loader is used to load the class or interface. If the parameter loader is null, the class is loaded through the bootstrap class loader. The class is initialized only if the initialize parameter is true and if it has not been initialized earlier.

大概意思就是:
这个类只会被加载一次

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值