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就好了。

  • 相关阅读:
    详解 CSS 属性
    【技巧】DataGridView,ListView重新绑定时保持上次滚动位置
    c#自动更新+安装程序的制作 (转)
    C#winform程序安装时自动卸载新版本覆盖旧版本
    C# 操作XML文件,用XML文件保存信息
    c# winform 隐藏tabcontrol标签
    datagridview用get,set访问并加锁,可以控制所有使用datagridview的地方都顺序进行访问
    sql 获取当天开始时间 结束时间
    批量导出指定注册表内容
    sql server 保留小数,向上保留指定位数的小数,仅记录,勿看。
  • 原文地址:https://www.cnblogs.com/digdeep/p/4493227.html
Copyright © 2011-2022 走看看