关于maven的资源过滤,官方文档有个例子:
<project>
...
<build>
...
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<excludes>
<exclude>**/*.xml</exclude>
</excludes>
</resource>
...
</resources>
...
</build>
...
</project>
刚开始我很困惑:
include=true与exclude=false难道不是等价的吗?这样配置不是重复了吗?
后来通过这篇文章
这篇文章找到正确的理解方式:
1.在src/main/resources目录下,xml文件都是资源文件,且需要被过滤
2.在src/main/resources目录下,除了xml文件以外的其他文件,也是资源文件,但它们不需要被过滤
但这样,好像还是有点绕。
看看
源码吧。
ResourcesMojo类的execute方法为入口:
public void execute()
throws MojoExecutionException
{
//...
mavenResourcesFiltering.filterResources( mavenResourcesExecution );
//...
}
找到org.apache.maven.shared.filtering.DefaultMavenResourcesFiltering.filterResources:
public void filterResources( MavenResourcesExecution mavenResourcesExecution )
throws MavenFilteringException {
for ( Resource resource : mavenResourcesExecution.getResources() )
{
String targetPath = resource.getTargetPath();
File resourceDirectory = new File( resource.getDirectory() );
Scanner scanner = buildContext.newScanner( resourceDirectory, ignoreDelta );
//扫描
setupScanner( resource, scanner, mavenResourcesExecution.isAddDefaultExcludes() );
scanner.scan();
//获取符合条件的文件
List<String> includedFiles = Arrays.asList( scanner.getIncludedFiles() );
for ( String name : includedFiles )
{
File source = new File( resourceDirectory, name );
File destinationFile = getDestinationFile( outputDirectory, targetPath, name, mavenResourcesExecution );
boolean filteredExt =
filteredFileExtension( source.getName(), mavenResourcesExecution.getNonFilteredFileExtensions() );
//替换和拷贝
mavenFileFilter.copyFile( source, destinationFile, resource.isFiltering() && filteredExt,
mavenResourcesExecution.getFilterWrappers(),
mavenResourcesExecution.getEncoding(),
mavenResourcesExecution.isOverwrite() );
}
}
}
步骤很清晰:
1.扫描指定目录,找出哪些文件是符合条件的
2.遍历符合条件的文件,如果需要过滤则进行过滤否则保持原样,最后拷贝到目标文件夹。
有几个关键的参数:
resource.isFiltering():是否过滤
mavenResourcesExecution.isOverwrite():是否覆盖
看看如何定义为“符合条件的文件”:
org.codehaus.plexus.util.DirectoryScanner.scan() {
if ( isIncluded( "", tokenizedEmpty ) )
{
if ( !isExcluded( "", tokenizedEmpty ) )
{
if ( isSelected( "", basedir ) )
{
dirsIncluded.addElement( "" );
}
else
{
dirsDeselected.addElement( "" );
}
}
else
{
dirsExcluded.addElement( "" );
}
}
else
{
dirsNotIncluded.addElement( "" );
}
}
看到这里就明白了:
满足<include></include>的条件,且不满足<exclude></exclude>的条件,就是“符合条件的文件”,也就是资源文件。
由代码也可看出,如果某个文件同时满足include和exclude,则结果为exclude。也就是exclude的优先级高。
再看看DirectoryScanner的注释:
* The segments of the name and the pattern are then matched against each
* other. When '**' is used for a path segment in the pattern, it matches
* zero or more path segments of the name.
* <p/>
* There is a special case regarding the use of <code>File.separator</code>s
* at the beginning of the pattern and the string to match:<br>
* When a pattern starts with a <code>File.separator</code>, the string
* to match must also start with a <code>File.separator</code>.
* When a pattern does not start with a <code>File.separator</code>, the
* string to match may not start with a <code>File.separator</code>.
* When one of these rules is not obeyed, the string will not
* match.
* <p/>
* When a name path segment is matched against a pattern path segment, the
* following special characters can be used:<br>
* '*' matches zero or more characters<br>
* '?' matches one character.
* <p/>
* Examples:
* <p/>
* "**\*.class" matches all .class files/dirs in a directory tree.
* <p/>
* "test\a??.java" matches all files/dirs which start with an 'a', then two
* more characters and then ".java", in a directory called test.
* <p/>
* "**" matches everything in a directory tree.
* <p/>
* "**\test\**\XYZ*" matches all files/dirs which start with "XYZ" and where
* there is a parent directory called test (e.g. "abc\test\def\ghi\XYZ123").
* <p/>
从注释中可知:
1.当<resouces>没有指定include时,默认为包括目录下所有文件; 如果没有指定exclude时,默认为不排除任一文件。
2.**表示匹配任意个目录
例如**/*.xml匹配以下:
a.xml
b/b.xml
c/d/f.xml
最后举个生产上的例子:
需求:
1.所有配置项都在properties/config.properties文件里,打包时需要根据不同的profile替换成真正的数值(例如数据库地址,生产跟测试是不同的)
2.其他spring文件里引用config.properties的变量(通过org.springframework.beans.factory.config.PropertyPlaceholderConfigurer),不需要替换成真正的值。这样的好处就是万一生产上要改配置,就只改config.properties,不需要到各个spring配置文件里修改
3.eboxx-client.xml也要过滤,因为它不是基于spring的,不能引用config.properties的变量
配置:
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>properties/config.properties</include>
<include>eboxx-client.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
</resource>
模拟一下maven进行资源过滤的过程:
1.读取第一个resource标签,找到符合条件的文件:config.properties文件和eboxx-client.xml
2.根据filtering=true得知,这两个文件需要过滤
3.过滤完成后,拷贝文件到默认目录(${project.build.outputDirectory},也就是target/classes目录)
4.读取第二个标签,由于没有指定include和exclude,所有文件都符合条件
5.根据filtering=false得知,这些文件不需要过滤
6.开始拷贝文件。拷贝过程中发现config.properties和eboxx-client.xml已经在默认目录存在了,由于overwrite默认为false,也就是不覆盖
7.结束
关于overwrite的默认值可以在ResourcesMojo.java中找到:
/**
* Overwrite existing files even if the destination files are newer.
*
* @since 2.3
*/
@Parameter( property = "maven.resources.overwrite", defaultValue = "false" )
private boolean overwrite;
事实上,为满足上面的需求,有个简单的办法:
1.pom.xml
<properties>
<p.jdbc.username>RTFM</p.jdbc.username>
</properties>
2.config.properties
jdbc_user=${p.jdbc.username}
3.beans.xml
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<property name="username" value="${jdbc_user}" />
</bean>
在配置资源过滤时,默认过滤所有文件。
由于beans.xml与pom.xml的变量名不一样,因为即使beans.xml被过滤了,里面的变量也不会被替换。
这样,或许人生会更简单一些^_^
分享到:
相关推荐
maven资源包maven资源包maven资源包maven资源包maven资源包maven资源包maven资源包maven资源包maven资源包maven资源包
举例说明: <directory>src/main/java **/*.properties **/*.xml <filtering>false </resource>
工程运行环境有研发,测试和生产,不同的运行环境配置不同,maven 打包时指定文件目录,使用指定的文件夹下的配置文件。
maven构建webAPP工程时加入此文件可以快速构建,减少等待
maven资源 apache-maven-3.3.9-bin.zip
所有资源都在一起,,打包下载,所有资源都在一起,,打包下载,所有资源都在一起,,打包下载,所有资源都在一起,,打包下载,所有资源都在一起,,打包下载,所有资源都在一起,,打包下载,所有资源都在一起,,...
maven资源库,海量下载,java开发必备,有需要的可以下载。
一些maven常用包
maven安装maven安装maven安装maven安装maven安装maven安装maven安装maven安装maven安装maven安装maven安装maven安装maven安装maven安装maven安装maven安装maven安装maven安装maven安装maven安装maven安装maven安装...
测试maven用到的资源
maven目前在web上面的使用方式很普遍,而打包的方式也存在很多方式,下面这篇文章主要给大家介绍了关于maven资源过滤打包后文件变大的处理方法,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
最全的maven资源包连接阿里资源库包括各大框架包邮件包oss上传包等等
maven是什么 maven这个词可以翻译为“知识的积累”,也可以翻译为“专家”或“内 行”。作为apache组织中的一个颇为成功的开源项目,maven主要服务于基于 java平台的项目构建、依赖管理和项目信息管理。 maven...
针对Log4j 2 远程代码执行漏洞,需要用到的升级资源包,适用于maven资源库,包括log4j,log4j-core,log4j-api,log4j-1.2-api,log4j-jpa等全套2.15.0 maven资源库jar包。如果是maven本地仓库使用,需要将zip包解压...
包含常用的maven jar包有需要请下载..
配置maven本地仓库以及路径,还有一个资源是修改Eclipse中的setting.xml最好一起参考,都是我上传的资源
Maven3.9.4版本压缩包,仅供学习参考,更新版本请前往Maven官方下载;Maven3.9.4版本压缩包,仅供学习参考,更新版本请前往Maven官方下载;Maven3.9.4版本压缩包,仅供学习参考,更新版本请前往Maven官方下载;Maven...
news jar包maven资源
maven:Maven是基于项目对象模型(POM),可以通过一小段描述信息来管理项目的构建、报告和文档的软件项目管理工具。主要用于大型项目的jar包管理,和多个互相依赖的项目的管理。
Maven本地资源库 Maven中央存储库 如何从Maven远程存储库下载? Maven添加远程仓库 Maven依赖机制 定制库到Maven本地资源库 使用Maven创建Java项目 使用Maven创建Web应用程序项目 Maven POM Maven 构建生命周期 ...