• spring中的 classpath* 存在可移植性问题


    classpath* 的可移植性问题,许多人都应该遇到过了。下面就是一个例子(使用的是spring4.1.5和mybatis3.2.8):

        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
          <property name="dataSource" ref="dataSource" />
          <property name="configLocation" value="classpath*:config/mybatis-config-master.xml" />
          <property name="mapperLocations" value="classpath*:config/mappers/master/**/*.xml" />
        </bean>

    上面的配置,在启动时报错:

    Caused by: java.io.FileNotFoundException: Could not open ServletContext resource [/classpath*:config/mybatis-config-master.xml]
        at org.springframework.web.context.support.ServletContextResource.getInputStream(ServletContextResource.java:141)
        at org.mybatis.spring.SqlSessionFactoryBean.buildSqlSessionFactory(SqlSessionFactoryBean.java:358)
        at org.mybatis.spring.SqlSessionFactoryBean.afterPropertiesSet(SqlSessionFactoryBean.java:340)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1625)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1562)
        ... 49 more

    spring在构造sqlSessionFactory这个bean时报错,原因是找不到配置文件:

    Could not open ServletContext resource [/classpath*:config/mybatis-config-master.xml]

    spring查找的路径是:/classpath*:config/mybatis-config-master.xml

    而这个路径根本不是我们想要的,根本就是找错了地方。

    但是我们配置文件给出的路径是:classpath*:config/mybatis-config-master.xml

    我们将配置文件中下面的配置稍作修改,去掉classpath后面的 *

    <property name="configLocation" value="classpath*:config/mybatis-config-master.xml" />

    改为:

    <property name="configLocation" value="classpath:config/mybatis-config-master.xml" />

    之后,启动正常,没有报错。

    原因

    The wildcard classpath relies on the getResources() method of the underlying classloader. As most application servers nowadays supply their own classloader implementation, the behavior might differ especially when dealing with jar files. A simple test to check if classpath* works is to use the classloader to load a file from within a jar on the classpath: getClass().getClassLoader().getResources("<someFileInsideTheJar>"). Try this test with files that have the same name but are placed inside two different locations. In case an inappropriate result is returned, check the application server documentation for settings that might affect the classloader behavior.

    不同的类加载器 classLoader 在处理 classpath* 时存在可移植性问题。如果在使用 classpath* 时报错,那么就应该去掉 * 直接使用classpath: ,如果还是报错,那么可以去掉classpath直接使用路径,在stackoverflow上有一个例子:http://stackoverflow.com/questions/6035464/could-not-open-servletcontext-resource

    classpath* 和 classpath的区别

    classpath* prefix specifies that all classpath resources that match the given name must be obtained (internally, this essentially happens via a ClassLoader.getResources(...) call), and then merged to form the final application context definition.

    1)classpath* 它会搜索所有的 classpath,找到所有符合条件的文件,包括jar文件中的配置文件。而classpath不会到jar文件中去寻找。

    2)classpath* 存在可移植性问题,遇到问题时,应该使用classpath.

    3)其实一般情况下我们根本没有必要去使用classpath*,直接使用classpath就好了。

  • 相关阅读:
    [iOS]C语言技术视频-15-指针变量高级用法练习一(函数指针完成动态排序)
    [iOS]C语言技术视频-14-指针变量高级用法(函数指针)
    [iOS]C语言技术视频-13-指针变量练习三(结构体指针变量)
    [iOS]C语言技术视频-12-指针变量练习二(数组打印)
    ReentrantLock加锁解锁过程
    spring初始化bean之后的3种回调方式
    spring循环引用-笔记
    二叉树的三种遍历方式
    快速排序
    java模拟实现单向链表
  • 原文地址:https://www.cnblogs.com/digdeep/p/4493227.html
Copyright © 2020-2023  润新知