mybatis-3.4.0---资源获取系列-ClassLoader操作

    其实mybatis框架,或者是说spring框架,都是从读取配置文件开始的,之后是各种操作,这种编程方式的有点就是,我们下载别人的jar包框架之后,修改一下配置文件就可以使用了,

这也是编码从硬编码到配置编码的过程演变,我们平常写代码的时候,也要注意从硬编码改成配置编码,其实有的时候配置编码都是被逼迫的,因为,老大总是要修改,没有办法,不可能每次都在自己机器上改好,然后上传服务器,没有那个闲工夫,如果使用配置文件,修改一下配置文件,保存就行了,就是这么的任性。

    我们先从mybatis的获取资源的过程来说:首先,先不管mybatis怎么处理这个配置文件,但是第一步(虽然是面向对象编程,我一度被面向对象给迷惑了,以为面向对象就不是面向过程了,但是后来证明其实任何程序都是面向过程的,面向对象其实就是一种分析方法和分析思维而已,真是名字吓死人):读取资源无外乎就是获取流,只要我们能拿到流,我们就想操作就怎么操作,但是如何才能获取流,这是个问题,我们使用File的时候,总是出现,FileNotFoundException异常,这个异常就是找不到文件,有的时候文件明明就在那儿,但是还是获取不到,就是这么个郁闷的心情啊。mybatis就是使用ClassLoader获取资源的,为什么使用ClassLoader获取流,因为java有一个jvm:就是java的虚拟机,既然是虚拟机,就是安装在windows或者是linux上一个操作系统,jvm有自己寻找资源的方式,并且ClassLoader就是类加载器,他既然能加载class,class也是使用流的方式加载的,那么,就能加载我们的文件资源,道理都是一样子的。我们讲完了,看看mybatis的源码操作

org.apache.ibatis.io.
ClassLoaderWrapper
这个是mybatis包装的一个获取ClassLoader的包装类,其中只有三个方法值得我们去看,其他的都是重载:

第一个是:获取五种类类加载器(ClassLoader)的方法


/**
 * 获取多个ClassLoader,这一步是必须的,因为,我们就是从这个加载器中获取资源的流的
 *五种类加载器:自己传入的、默认的类加载器、当前线程的类加载器、本类的类加载器、系统类加载器
 * @param classLoader 我们定义的自己的类加载器
 * @return 类加载器的数组
 */
ClassLoader[] getClassLoaders(ClassLoader classLoader) {
    return new ClassLoader[]{
            classLoader,
            defaultClassLoader,
            Thread.currentThread().getContextClassLoader(),
            getClass().getClassLoader(),
            systemClassLoader};
}



第二个方法是:记载资源为InputStream的形式输出
/**
 * 从一个ClassLoader中获取资源的流,这就是我们的目的
 *
 * @param resource    资源的地址
 * @param classLoader 类加载器
 * @return  */
InputStream getResourceAsStream(String resource, ClassLoader[] classLoader) {
    for (ClassLoader cl : classLoader) {
        if (null != cl) {

            // try to find the resource as passed
            InputStream returnValue = cl.getResourceAsStream(resource);

            // now, some class loaders want this leading "/", so we'll add it and try again if we didn't find the resource
            if (null == returnValue) {
                returnValue = cl.getResourceAsStream("/" + resource);
            }

            if (null != returnValue) {
                return returnValue;
            }
        }
    }
    return null;
}

第三个是:获取资源,以URL的形式输出:(URL可以通过openConnection、getInputStream的形式获取流,不知道为什么提供这个方法)
/*
 * Get a resource as a URL using the current class path
 *
 * @param resource    - the resource to locate
 * @param classLoader - the class loaders to examine
 * @return the resource or null
 */
URL getResourceAsURL(String resource, ClassLoader[] classLoader) {

    URL url;

    for (ClassLoader cl : classLoader) {

        if (null != cl) {

            // look for the resource as passed in...
            url = cl.getResource(resource);

            // ...but some class loaders want this leading "/", so we'll add it
            // and try again if we didn't find the resource
            if (null == url) {
                url = cl.getResource("/" + resource);
            }

            // "It's always in the last place I look for it!"
            // ... because only an idiot would keep looking for it after finding it, so stop looking already.
            if (null != url) {
                return url;
            }

        }

    }

    // didn't find it anywhere.
    return null;

}

第四个也要看看:是通过当前的类加载器加载我们的类:
/*
 * Attempt to load a class from a group of classloaders
 *
 * @param name        - the class to load
 * @param classLoader - the group of classloaders to examine
 * @return the class
 * @throws ClassNotFoundException - Remember the wisdom of Judge Smails: Well, the world needs ditch diggers, too.
 */
Class<?> classForName(String name, ClassLoader[] classLoader) throws ClassNotFoundException {

    for (ClassLoader cl : classLoader) {

        if (null != cl) {

            try {

                Class<?> c = Class.forName(name, true, cl);

                if (null != c) {
                    return c;
                }

            } catch (ClassNotFoundException e) {
                // we'll ignore this until all classloaders fail to locate the class
            }

        }

    }

    throw new ClassNotFoundException("Cannot find class: " + name);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值