一、简介
构建 Maven 项目的时候,如果没有进行特殊的配置,Maven 会按照标准的目录结构查找和处理各种类型文件。
● src/main/java 和 src/test/java
这两个目录中的所有 *.java文件会分别在 comile 和 test-comiple 阶段被编译,编译结果分别放到了 target/classes 和targe/test-classes 目录中,但是这两个目录中的其他文件都会被忽略掉。
● src/main/resouces 和 src/test/resources
这两个目录中的文件也会分别被复制到 target/classes 和 target/test-classes 目录中。
● target/classes
打包插件默认会把这个目录中的所有内容打入到 jar 包或者 war 包中。
二、Maven项目的标准目录结构
src
| main
| java 源文件
| resources 资源文件
| filters 资源过滤文件
| config 配置文件
| scripts 脚本文件
| webapp web应用文件
| test
| java 测试源文件
| resources 测试资源文件
| filters 测试资源过滤文件
| it 集成测试
| assembly assembly descriptors
| site Site
target
| generated-sources
| classes
| generated-test-sources
| test-classes
xxx.jar
pom.xml
LICENSE.txt
NOTICE.txt
README.md
三、打包时资源文件的配置
3.1、打包 src/main/java 目录下的 xml
一般情况下,我们用到的资源文件(各种 xml,properites,xsd 文件等)都放在 src/main/resources 下面,利用 maven 打包时,maven 能把这些资源文件打包到相应的 jar 或者 war 里。
有时候,比如 mybatis 的 mapper.xml 文件,我们习惯把它和 Mapper.java 放一起,都在 src/main/java 下面,这样利用 maven 打包时,就需要修改 pom.xml 文件,来把 mapper.xml 文件一起打包进 jar 或者 war 里了,否则,这些文件不会被打包的。(maven 认为src/main/java 只是 java 的源代码路径)
下面通过一个简单的示例来说明:
项目结构如下所示,有两个 UserMaper.xml 文件,所在目录不同
默认情况下,在 pom.xml 目录下执行: mvn clean package 打包命令在 target\classes 目录下不会把 UserMapper.xml 打包到下 mapper 目录下:
而 resources 目录下的文件始终都会打包进 jar 包或 war 包:
这个时候使用 mybatis 就会出一些问题,找不到 UserMapper 所对应的 xml 文件解决方法有如下几种:
(1)配置 POM.XML 的 resource 把 xml 也打包到 mapper 目录下
<build><!-- 资源目录 --><resources><resource><!-- 设定主资源目录 --><directory>src/main/java</directory><!-- maven default生命周期,process-resources阶段执行 maven-resources-plugin插件的resources目标处理主资源目下的资源文件时,只处理如下配置中包含的资源类型--><includes><include>**/*.xml</include></includes><!-- maven default生命周期,process-resources阶段执行maven-resources-plugin插件的resources目标处理主资源目下的资源文件时,不处理如下配置中包含的资源类型(剔除下如下配置中包含的资源类型)--><excludes><exclude>**/*.yaml</exclude></excludes><!-- maven default生命周期,process-resources阶段执行maven-resources-plugin插件的resources目标处理主资源目下的资源文件时,指定处理后的资源文件输出目录,默认是${build.outputDirectory}指定的目录--><!--<targetPath>${build.outputDirectory}</targetPath> --><!-- maven default生命周期,process-resources阶段执行maven-resources-plugin插件的resources目标处理主资源目下的资源文件时,是否对主资源目录开启资源过滤--><filtering>true</filtering></resource></resources></build>
其中 **/*这样的写法,是为了保证各级子目录下的资源文件被打包。resources 是可以看做是容器,这个容器里面可以放很多个像 resource 这样的配置。而 directory 就是配置文件所在的路径,includes 从英文单词角度看,就是包含的意思,此时在执行命令,就会把 xml 也打包到 mapper 目录下了:
Resources 官方文档地址为 http://maven.apache.org/pom.html#Resources
(2)maven-resources-plugin 插件
为了使项目结构更为清晰,Maven 区别对待 Java代码文件和资源文件,maven-compiler-plugin 用来编译 Java 代码,maven-resources-plugin 则用来处理资源文件。
默认的主资源文件目录是 src/main/resources,很多用户会需要添加额外的资源文件目录,这个时候就可以通过配置 maven-resources-plugin 来实现。
<!--
可以用此 plugin,把源代码中的 xml 文件,打包到相应位置,
这里主要是为了打包 Mybatis 的 mapper.xml 文件
-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<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>
此外,资源文件过滤也是 Maven 的一大特性,你可以在资源文件中使用 ${propertyName}形式的 Maven 属性,然后配置maven-resources-plugin 开启对资源文件的过滤,之后就可以针对不同环境通过命令行或者 Profile 传入属性的值,以实现更为灵活的构建。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<encoding>UTF-8</encoding>
<!-- 过滤后缀为pem、pfx的证书文件 -->
<nonFilteredFileExtensions>
<nonFilteredFileExtension>pem</nonFilteredFileExtension>
<nonFilteredFileExtension>pfx</nonFilteredFileExtension>
<nonFilteredFileExtension>p12</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
</plugin>
(3)build-helper-maven-plugin 插件
<!--
可以利用此plugin,把源代码中的xml文件,
打包到相应位置,这里主要是为了打包Mybatis的mapper.xml文件
-->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>add-resource</id>
<phase>generate-resources</phase>
<goals>
<goal>add-resource</goal>
</goals>
<configuration>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
3.2、src/main/resources 目录下的 xml 等资源文件不被打包
默认 resources 目录下的文件都会被打包,如果想 resources 目录下的 xml 文件不被打包,可通过如下配置:
<!--过滤resource下的文件-->
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>*.properties</include> <!--打包properties文件-->
</includes>
<excludes>
<exclude>*.xml</exclude> <!--过滤xml与yaml文件-->
<exclude>*.yaml</exclude>
</excludes>
</resource>
</resources>
编译之后如下:
当然也可以通过插件来实现
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-resources</id>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<!-- 并把文件复制到target/conf目录下-->
<outputDirectory>${project.build.directory}/conf</outputDirectory>
<resources>
<resource>
<directory>src/main/resources</directory>
<!-- 指定不需要处理的资源 <excludes> <exclude>WEB-INF/*.*</exclude> </excludes> -->
<excludes> <exclude>**/*.xml</exclude> </excludes>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
实现的效果如下:
编译好之后,会在 target 目录下生成 conf 目录并且把 resources 目录下的所有文件都自动拷贝到 target/conf/ 目录下。
