问题描述

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

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

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

  1. package canger.study.Utils;
  2.  
  3. import org.apache.ibatis.io.Resources;
  4. import org.apache.ibatis.session.SqlSession;
  5. import org.apache.ibatis.session.SqlSessionFactory;
  6. import org.apache.ibatis.session.SqlSessionFactoryBuilder;
  7.  
  8. import java.io.IOException;
  9. import java.io.InputStream;
  10.  
  11. /**
  12. * Created by Administrator on 2018\2\12 0012.
  13. */
  14. public class SqlSessionFactoryUtil {
  15. private static String resource = "Mybatis-Configuration.xml";
  16. private static SqlSessionFactory sqlSessionFactory = null;
  17. public static void setResourcePath(String path){
  18. resource = path;
  19. }
  20. private static void initSqlSessionFactory() throws IOException {
  21. if (sqlSessionFactory!=null){
  22. return;
  23. }
  24.  
  25. synchronized (SqlSessionFactoryUtil.class){
  26. if(sqlSessionFactory==null){
  27. InputStream resourceAsStream = Resources.getResourceAsStream(resource);
  28. sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
  29. }
  30. }
  31. }
  32.  
  33. public static SqlSession openSqlSession() throws IOException {
  34. initSqlSessionFactory();
  35. return sqlSessionFactory.openSession();
  36. }
  37. }

问题排查

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包,所以能够找到配置文件

修改后的代码如下

  1. package canger.study.Utils;
  2.  
  3. import org.apache.ibatis.session.SqlSession;
  4. import org.apache.ibatis.session.SqlSessionFactory;
  5. import org.apache.ibatis.session.SqlSessionFactoryBuilder;
  6.  
  7. import java.io.InputStream;
  8.  
  9. /**
  10. * Created by Administrator on 2018\2\12 0012.
  11. */
  12. public class SqlSessionFactoryUtil {
  13. private static String resource = "/Mybatis-Configuration.xml";
  14. private static SqlSessionFactory sqlSessionFactory = null;
  15. public static void setResourcePath(String path){
  16. resource = path;
  17. }
  18. private static void initSqlSessionFactory(){
  19. if (sqlSessionFactory!=null){
  20. return;
  21. }
  22.  
  23. synchronized (SqlSessionFactoryUtil.class){
  24. if(sqlSessionFactory==null){
  25. InputStream resourceAsStream = SqlSessionFactoryUtil.class.getClassLoader().getResourceAsStream(resource);
  26. sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
  27. }
  28. }
  29. }
  30.  
  31. public static SqlSession openSqlSession(){
  32. initSqlSessionFactory();
  33. return sqlSessionFactory.openSession();
  34. }
  35. }

总结

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包

Class.getResourceAsStream 和 ClassLoder.getResourceAsStream 的区别的更多相关文章

  1. 1、ClassLoader.getResourceAsStream() 与Class.getResourceAsStream()的区别

    1.ClassLoader.getResourceAsStream() 与Class.getResourceAsStream()的区别 例如你写了一个MyTest类在包com.test.mycode ...

  2. Class.getResourceAsStream和ClassLoader.getResourceAsStream方法

    项目中,有时候要读取当前classpath下的一些配置文件,下面介绍下Class.getResourceAsStream和ClassLoader.getResourceAsStream两种方法以及两者 ...

  3. JAVA 笔记 ClassLoader.getResourceAsStream() 与 Class.getResourceAsStream()的区别

       Class.getResourceAsStream() 会指定要加载的资源路径与当前类所在包的路径一致. 例如你写了一个MyTest类在包com.test.mycode 下,那么MyTest.c ...

  4. Class.getResourceAsStream()与ClassLoader.getResourceAsStream()的区别

    Class.getResourceAsStream() 会指定要加载的资源路径与当前类所在包的路径一致. 例如你写了一个MyTest类在包com.test.mycode 下,那么MyTest.clas ...

  5. ClassLoader.getResourceAsStream() 与 Class.getResourceAsStream()的区别

        Class.getResourceAsStream() 会指定要加载的资源路径与当前类所在包的路径一致. 例如你写了一个MyTest类在包com.test.mycode 下,那么MyTest. ...

  6. Class.getResourceAsStream() VS. ClassLoader.getResourceAsStream()

    For Class.getResourceAsStream(String name), if the name parameter doesn't start with a "/" ...

  7. class getResourceAsStream 和 classloader getResourceAsStream获取资源的不同

    工程目录结构: prj(工程根目录) cn json classloader GetResourceByClassAndClassLoader.Java beans.xml /** * */ pack ...

  8. 对Class.getResourceAsStream和ClassLoader.getResourceAsStream方法所使用的资源路径的解释

    这是个非常基础的问题了,这里提供一些演示样例,帮助高速理解和记忆这个问题. 在该方法的文档:http://docs.oracle.com/javase/7/docs/api/java/lang/Cla ...

  9. Class.getResourceAsStream()与ClassLoader.getResourceAsStream()获取资源时的路径说明

    Class.getResourceAsStream(): com.xusweeter.iot.ws.vodafone.config.VodafoneServiceConfig.class.getRes ...

随机推荐

  1. 一个将当前目录下HEX文件的第一行数据删除的程序

    为什么要写这样一个函数 在使用SoftConsole开发M3程序时,生成的hex文件,必须要把第一行数据删除,才能在Libero中使用,所以写了这个小工具,这是2.0版本了,第一版是直接删除第一行数据 ...

  2. Zabbix实战-简易教程--订阅类

    一.需求提出 最近数据中心有一个新的需求,有一批后台任务需要在每天固定时间点运行(凌晨8:00),现在希望能够把这个任务执行的结果定时上报给他. 说明:执行的任务为一个sql查询,查询出来的是每个任务 ...

  3. c# table 怎么在前台循环展示 ViewBag

    后台 public ActionResult DoctorEvaluation()//前台页面 { HE_Department HE_dt = new HE_Department(); DataTab ...

  4. 动态加载与插件系统的初步实现(一):反射与MEF解决方案

    涉及内容: 反射与MEF解决方案 AppDomain卸载与代理 WinForm.WcfRestService示 PRRT1: 反射实现 插件系统的基本目的是实现宿主与组件的隔离,核心是作为接驳约定的接 ...

  5. 微信小程序—day01

    前言 听说谷歌准备回中国了,玩了一下谷歌刚入驻微信的小程序:“猜画小歌”,又一次见识到了ai的强大魅力.看来python之路,前途还是一片光明的. 因为18年初时的“跳一跳”,带火了微信小程序,一直想 ...

  6. C++构造函数和析构函数什么情况下会用

    析构函数: 1. 对象生命周期结束,被销毁时: 2. delete 指向对象的指针时: 3. delete 指向基类对象的指针时,其析构函数是虚函数: 4. 在嵌套关系中,对象A是对象B的成员,当对象 ...

  7. 《spark机器学习 第二版》 蔡立宇 分享 pdf下载

    链接:https://pan.baidu.com/s/15Y14eAnfj8zf5mXdixbVeQ 提取码:rkdt

  8. kali虚拟机安装后操作[配置ssh,安装vmtools,更新源]

    更新源 # 打开控制台, 输入以下命令打开编辑器修改配置文件 $ leafpad /etc/apt/sources.list #kali官方源 deb http://http.kali.org/kal ...

  9. 啥是MD5?

    啥是MD5加密呢?为啥要使用MD5这种非对称的加密方式呢? 本文将通过漫画的形式来通俗易懂的讲述什么是MD5加密算法(Message Digest Algorithm MD5(中文名为消息摘要算法第五 ...

  10. python多线程创建与使用(转)

    原文:http://codingpy.com/article/python-201-a-tutorial-on-threads/ 创建多线程 创建多线程主要有2种方式. 使用threading.Thr ...