zoukankan      html  css  js  c++  java
  • 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就好了。

  • 相关阅读:
    switch case加范围判断
    对requestAnimationFrame的一点理解
    用dos命令导出一个文件夹里面所有文件的名字(装逼利器)
    zookeeper基本知识入门(一)
    hadoop学习(七)----mapReduce原理以及操作过程
    centos虚拟机配置静态ip
    linux 配置ssh无密码登录不起作用的解决方案
    linux下安装开发环境
    hadoop学习(五)----HDFS的java操作
    hadoop学习(四)----windows环境下安装hadoop
  • 原文地址:https://www.cnblogs.com/digdeep/p/4493227.html
Copyright © 2011-2022 走看看