Class.getResourceAsStream 和 ClassLoder.getResourceAsStream 的区别

本文介绍了解决MyBatis配置文件加载失败的问题,通过对比Class.getResourceAsStream与ClassLoader.getResourceAsStream的区别,最终实现了跨Jar包正确加载配置文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述

最近学习MyBaits时用到了 InputStream Resources.getResourceAsStream(String resource)来读取MyBatis配置文件,为了方便使用,封装了一个SqlSessionFactoryUtil,代码如下

并且将这个类放在了一个单独的jar包中,其他工程会引用这个jar包,当然其他工程的MyBatis配置文件名称均为Mybatis-Configuration.xml

问题就是,测试时报错,无法找到Mybatis-Configuration.xml文件,但工程中这个文件确实存在,如图

 

package canger.study.Utils;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

/**
 * Created by Administrator on 2018\2\12 0012.
 */
public class SqlSessionFactoryUtil {
    private static String resource = "Mybatis-Configuration.xml";
    private static SqlSessionFactory sqlSessionFactory = null;
    public static void setResourcePath(String path){
        resource = path;
    }
    private static void initSqlSessionFactory() throws IOException {
        if (sqlSessionFactory!=null){
            return;
        }

        synchronized (SqlSessionFactoryUtil.class){
            if(sqlSessionFactory==null){
                InputStream resourceAsStream = Resources.getResourceAsStream(resource);
                sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
            }
        }
    }

    public static SqlSession openSqlSession() throws IOException {
        initSqlSessionFactory();
        return sqlSessionFactory.openSession();
    }
}

 

问题排查

 InputStream Resources.getResourceAsStream(String resource)底层采用ClassLoder.getResourceAsStream(String resource)方法,ClassLoder.getResourceAsStream(String resource)调用时返回了null,百度后知道ClassLoder.getResourceAsStream(String resource)只会检查当前jar包的路径,不用检查其他jar包,所以无法找到文件,具体可参考 https://stackoverflow.com/questions/16570523/getresourceasstream-returns-null ,

同时Class..getResourceAsStream(String resource)会检查其他jar包,所以能够找到配置文件

修改后的代码如下

package canger.study.Utils;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.InputStream;

/**
 * Created by Administrator on 2018\2\12 0012.
 */
public class SqlSessionFactoryUtil {
    private static String resource = "/Mybatis-Configuration.xml";
    private static SqlSessionFactory sqlSessionFactory = null;
    public static void setResourcePath(String path){
        resource = path;
    }
    private static void initSqlSessionFactory(){
        if (sqlSessionFactory!=null){
            return;
        }

        synchronized (SqlSessionFactoryUtil.class){
            if(sqlSessionFactory==null){
                InputStream resourceAsStream = SqlSessionFactoryUtil.class.getClassLoader().getResourceAsStream(resource);
                sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
            }
        }
    }

    public static SqlSession openSqlSession(){
        initSqlSessionFactory();
        return sqlSessionFactory.openSession();
    }
}

总结

Class.getResourceAsStream(String name) 和 ClassLoader.getResourceAsStream(String name)区别如下

  1. ClassLoader.getResourceAsStream(String name)  无论name最前面是否为'/' 都会从classpath的根路径下查找

  2. Class.getResourceAsStream(String name)如果 name不以'/'开头则在当前类所在包的路径查找 ,如果name是以 '/' 开头的,那么就会从classpath的根路径下开始查找

  3. ClassLoader.getResourceAsStream(String name)不会查看其他jar包,Class.getResourceAsStream(String name)会查看其他jar包

转载于:https://www.cnblogs.com/canger/p/8445677.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值