Spring中classpath和classpath*的问题

本文详细探讨了Spring中classpath和classpath*在加载资源文件时的不同行为。classpath仅返回第一个匹配的资源,优先查找项目目录,然后是jar包。而classpath*支持通配符并能加载所有匹配的资源,包括jar包内的。测试结果显示,classpath在使用通配符时无法获取资源,但classpath*可以。即使将配置文件拆分为多个,classpath也能加载所有内容。此外,classpath的加载速度比classpath*快。

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

这一段是从网上抄录(原网址为 关于Spring加载classpath与classpath*的过程剖析)

1.无论是classpath还是classpath*都可以加载整个classpath下(包括jar包里面)的资源文件。
2.classpath只会返回第一个匹配的资源,查找路径是优先在项目中存在资源文件,再查找jar包。
3.文件名字包含通配符资源(如果spring-.xml,spring.xml), 如果根目录为”“, classpath加载不到任何资源,
而classpath*则可以加载到classpath中可以匹配的目录中的资源,但是不能加载到jar包中的资源

  第1,2点比较好表理解,大家可以自行测试,第三点表述有点绕,举个例,现在有资源文件结构如下:

这里写图片描述

classpath:notice*.txt 加载不到资源
classpath*:notice*.txt 加载到resource根目录下notice.txt
classpath:META-INF/notice*.txt 加载到META-INF下的一个资源(classpath是加载到匹配的第一个资源,就算删除classpath下的notice.txt,他仍然可以加载jar包中的notice.txt)
classpath:META-/notice.txt 加载不到任何资源
classpath*:META-INF/notice*.txt 加载到classpath以及所有jar包中META-INF目录下以notice开头的txt文件
classpath*:META-/notice.txt 只能加载到classpath下 META-INF目录的notice.txt

下面是个人测试
这里只记录引用资源文件resources时的区别,简单写了个连接数据库测试一下
目录结构大体如下:
这里写图片描述

general.properties文件中只是数据库的信息

#DataSource
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/shoes?useUnicode=true&characterEncoding=UTF-8
jdbc.username=root
jdbc.password=123456

spring-hibernate.xml则是spring获取连接池的配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                            http://www.springframework.org/schema/beans/spring-beans.xsd
                            http://www.springframework.org/schema/context
                            http://www.springframework.org/schema/context/spring-context.xsd
                            http://www.springframework.org/schema/tx
                            http://www.springframework.org/schema/tx/spring-tx.xsd">


    <context:property-placeholder location="classpath:general.properties"/>

    <!-- 配置Druid连接池 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <!-- 基本属性 driverClassName、url、user、password -->
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />

    </bean>

    <!-- 配置 Hibernate 的 SessionFactory  -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <!-- 配置 Hibernate 的参数: 方言, 显示SQL等 -->
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">
                    org.hibernate.dialect.MySQL5Dialect
                </prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
            </props>
        </property>
        <!-- 配置映射文件 -->
        <property name="mappingLocations">
            <list>
                <value>classpath:hbm/Factory.hbm.xml</value>
            </list>
        </property>
    </bean>
    <!-- 配置HibernateTemplate -->
    <bean id="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>

</beans>

主要就是通过<context:property-placeholder location="classpath:general.properties"/>获取general.properties中内容,然后放入dataSource的bean中。

实测1:
general.properties位置为/resources/general.properties

配置结果
classpath:general.properties能找到
classpath*:general.properties能找到
classpath*:general*.properties能找到
classpath:general*.properties找不到

实测2:
general.properties位置为/resources/general/general.properties

配置结果
classpath:general/general*.properties能找到
classpath:general*/general*.properties找不到
classpath*:general*/general*.properties能找到

实测3:
general.properties拆成两份

#DataSource
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/shoes?useUnicode=true&characterEncoding=UTF-8
#DataSource
jdbc.username=root
jdbc.password=123456

位置为
/resources/general/general.properties和
/resources/general/general1.properties

配置结果
classpath*:general/general*.properties能正常运行
classpath:general/general*.properties能正常运行
classpath:general/general.properties, general/general1.properties能正常运行
classpath*:general/general.properties, general/general1.properties能正常运行

实测4:
general.properties如上拆成两份重名文件,位置为
/resources/test/general/general.properties和
/resources/test/general1/general.properties

配置结果
classpath*:test/general*/general*.properties能正常运行
classpath:test/general*/general*.properties能正常运行
classpath*:test/general*/general.properties能正常运行
classpath:test/general*/general.properties能正常运行

测试结果:
1、classpath在使用时,第一级路径无法使用通配符,如classpath:general*.properties或者classpath:general*/general*.properties是无法获取到的
2、在我将general.properties拆成两个文件后,classpath同样可以获取两个文件,读取到全部内容,不知道是不是我测的方法有问题,这方面没感觉出来说是只能获取到第一个文件的限制
3、classpath比classpath*快,明确位置比通配符快。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值