往JAR包里添加资源
将资源放到标准目录结构即可:${basedir}/src/main/resources
比如:
${basedir}/src/main/java和${basedir}/src/main/resources都对应JAR包里的基路径,上例JAR包中的内容是这样的(可以用解压缩工具打开浏览JAR包里的内容):
其他文件都是Maven生成JAR包的时候自己添加进去的。
我们可以创建自己的manifest,或者修改Maven默认的manifest。
pom.xml和pom.properties是用来描述此工件(artifact)的,我们如果有需要也可以使用这些元数据。比如获取工件的版本。不过操作POM文件需要使用Maven工具,但我们可以利用属性文件,Java有API可以读取属性文件,比如:
#Generated by Maven#Tue Oct 04 15:43:21 GMT-05:00 2005version=1.0-SNAPSHOTgroupId=com.mycompany.appartifactId=my-app
如果要为单元测试添加资源,也是类似,资源目录放在test目录下即可:${basedir}/src/test/resources
现在我们的目录结构是这样的:
过滤资源文件
过滤(filter)可以理解为在打成JAR包的时候,需要动态生成一些值提供给资源文件。
也可以这样说,资源文件需要用到某些数据,而这些数据是在构建过程中生成的。
本质上是Maven在将资源文件拷贝到JAR包中的时候,对资源文件进行一次扫描,然后用数据填充到适当的位置。
第一步,如果需要这种过滤,需要在pom.xml为资源目录设置filtering属性为true,比如:
src/main/resourcestrue
事实上,这几个元素都是Maven默认有的,只不过filtering的默认值是false
第二步,资源文件引用这些数据值的语法:${}
比如,我们的资源文件application.properties需要引用项目的名字和版本,可以这样:
# application.propertiesapplication.name=${project.name}application.version=${project.version}
那project.name和project.version这两个属性是来自哪呢?引用的属性可以来自:
- pom.xml :属性的名字就是元素名字用点号拼接起来,比如:project.name就是元素中的元素的值。不过project有个别名pom。需要注意的是POM中某些元素是有默认值的。
- Maven的用户配置文件settings.xml :与POM文件类似,只不过根元素变为,所以属性名都用settings开头,比如:${settings.localRepository}指代用户本地仓库的路径。
- 在其他外部属性文件中定义的属性
- 系统属性
所以,上面两个属性就是来自POM文件。
第三步,想看下效果,执行:
mvn process-resources
process-resources是Maven构建生命周期的一个阶段,此阶段是进行资源文件的复制和过滤的。
执行之后,target/classes目录下的application.properties中的内容是(大家的配置不同结果会不同):
application.name=demoapplication.version=0.0.1-SNAPSHOT
注意:如果你使用了Spring Boot,比如在POM文件中这样写:
org.springframework.bootspring-boot-starter-parent1.5.11.RELEASE
那么Spring Boot会把Spring默认的分隔符${}替换为@,这个可以点开spring-boot-starter-parent的POM文件看到:
1.6@UTF-8UTF-8${java.version}${java.version}
所以解决方法:
a、我们需要这样引用属性值:application.name=@project.name@
b、在我们的POM文件中添加:
${}
覆盖Spring Boot的配置
c、不要继承spring-boot-starter-parent
前面使用的是POM文件中的属性值,如果要使用其他外部属性文件中的属性值,比如,在目录src/main/xxxx下定义个外部属性文件asdf.properties,其内容是:
aaaa.bbbb.value=hello!
然后我们要在POM文件中引用这个文件:
src/main/xxxx/asdf.propertiessrc/main/resourcestrue
然后在我们的资源文件application.properties中添加一个引用外部属性文件属性值的属性:
application.name=${project.name}application.version=${project.version}# 下面这个属性引用的是外部属性文件中的属性值message=${aaaa.bbbb.value}
资源文件被过滤后内容变为:
application.name=demoapplication.version=0.0.1-SNAPSHOTmessage=hello!
当然,我们也可以把我们需要的属性定义在POM文件中,比如:
hello
现在,我们就可以不需要外部属性文件src/main/xxxx/asdf.properties了,所以,相关的配置和元素也就不需要了。
资源文件过滤还可以使用系统属性,比如Java内置的属性java.version、user.home等等,还有使用标准Java -D方式定义在命令行中的属性。
假设我们把资源文件application.properties的内容改为:
java.version=${java.version}command.line.prop=${command.line.prop}
然后执行命令:
mvn process-resources "-Dcommand.line.prop=hello again"