叙述
(1)默认 Spring Boot 项目结构,资源文件放置在 src/main/resources 中,测试的资源文件在 src/test/resources 中。
src/main/resources 与 src/test/resources 的区别:
- src/main/java 里面的 java 文件只能直接加载 src/main/resources 下的资源,不能直接加载 src/test/resources 下的资源;
- src/test/java 里面的 java 文件既能加载 src/test/resources 下的资源,又能加载 src/main/resources 下的资源,当两个 resources 下都有要加载的同名资源时候,优先选择 src/test/resources 下的资源。
src/main/resources和src/test/resources下的资源读取方式
- 一般maven会将spring工程编译到target文件夹下,/target/classes就是其根目录。而src/main/resources下的文件被复制到了这个classes文件夹下。
- maven会将src/test/java文件夹下的代码编译到target/test-classes文件夹下。同样的,如果src/test/resources下有资源文件的话,就复制到target/test-classes文件夹下。
- 测试代码运行时,优先使用test-classes文件夹下的资源文件,如果不存在,再使用classes文件夹下的资源文件。
(2)将项目打包后,解压 jar 可以发现原先 src/main/resources 目录下的资源文件已经被打包进来了:
(3)但有时我们的资源文件并不一定是放在 src/main/resources 目录下,比如我的项目通常会将资源文件放在 src/test/resources 目录下:
原因:根据实践经验表明,测试完后的配置项是最完整的,且经常会忘记替换正式版参数,因而选择将配置文件全部放置在 src/test/resources 目录下。
(4)又比如 mybatis 的 mapper.xml 文件,我们习惯把它和 Mapper.java 放一起
(5)但上面这两种情况的资源文件,在使用 maven 打包时是不会被打包进 jar 的。这时候我们便要指定需要打包的资源文件,这个有如下两种方法可以实现。
解决方案
使用 <resources> 标签
(1)<resources> 标签位于 <build> 标签内,用于指定项目资源文件的位置。比如下面配置我们指定了 src/test/resources 也是资源文件目录:
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> <!-- 重新指明资源文件位置 --> <resources> <resource> <directory>src/test/resources</directory> </resource> <resource> <directory>src/main/resources</directory> </resource> </resources> </build>
(2)而对于写在包下的 Mapper.xml 文件,我们则可以通过如下配置指明资源文件位置:
提示:其中 **/* 这样的写法,是为了保证各级子目录下的资源文件被打包。
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> <!-- 重新指明资源文件位置 --> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> <resource> <directory>src/main/resources</directory> </resource> </resources> </build>
(3)我们还可以通过 excludes 标签剔除不需要的资源:
<build> ....... <resources> <resource> <directory>src/main/resources</directory> <excludes> <exclude>**/*.properties</exclude> <exclude>**/*.xml</exclude> </excludes> <filtering>false</filtering> </resource> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> </resources> ...... </build>
使用 maven-resources-plugin 插件
(1)除了使用 标签外,我们也可以使用 maven-resources-plugin 插件实现同样的目的。比如下面配置把 src/test/resources 目录下的资源文件打包到 classes 目录下:
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <executions> <execution> <id>my-resources</id> <phase>process-resources</phase> <goals> <goal>copy-resources</goal> </goals> <configuration> <outputDirectory>${basedir}/target/classes</outputDirectory> <resources> <resource> <directory>${basedir}/src/test/resources</directory> <includes> <include>*.properties</include> <include>*.xml</include> </includes> </resource> </resources> </configuration> </execution> </executions> </plugin> </plugins> </build>
(2)而对于写在包下的 Mapper.xml 文件,我们也可以通过 maven-resources-plugin 插件将其打包到相应位置:
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <executions> <execution> <id>copy-xmls</id> <phase>process-sources</phase> <goals> <goal>copy-resources</goal> </goals> <configuration> <outputDirectory>${basedir}/target/classes</outputDirectory> <resources> <resource> <directory>${basedir}/src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> </resources> </configuration> </execution> </executions> </plugin> </plugins> </build>
(3)使用 maven-resources-plugin 插件时,我们同样可以通过 excludes 标签剔除不需要的资源:
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <executions> <execution> <id>my-resources</id> <phase>process-resources</phase> <goals> <goal>copy-resources</goal> </goals> <configuration> <outputDirectory>${basedir}/target/classes</outputDirectory> <resources> <resource> <directory>${basedir}/src/test/resources</directory> <includes> <include>**/*.*</include> </includes> <excludes> <exclude>log4j2-spring.xml</exclude> </excludes> </resource> </resources> </configuration> </execution> </executions> </plugin> </plugins> </build>