如何将易变资源移出jar包----和新同学聊聊maven插件的使用
某些Maven项目在打包时,有时需要将src路径下的某些文件原封不动地拷贝到target路径下。
这样做的最明显的好处是,在部署后,可以随时修改配置文件、网页文件等有可能随时修改的文件。常见的几种场景有:
- 配置文件*.properties或*.yml
- 微服务内嵌的*.html和*.js文件
- 必须定期更换的文件,典型的有:
- 苹果APP的apns文件
- 从阿里云申请的数字证书文件(免费版的只有3个月寿命)
- 微信公众号的网站验证文件
1、资源在src中的位置
以SpringBoot程序为例,一般来说,静态资源和配置信息都存放在src/main/resource文件夹中。我的实例程序中,资源分成了apns、config、static等3个子目录,还有一个logback-spring.xml文件位于resource目录下。如下:
2、maven-resources-plugin和maven-jar-plugin插件
为了实现把上述文件夹移出jar包,需要在POM.xml文件中配置以下plugin:
<project> ....项目依赖等配置.... <build> <finalName>websocket</finalName> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <!-- 复制指定环境配置文件到指定目录 --> <plugin> <artifactId>maven-resources-plugin</artifactId> <executions> <execution> <id>copy-out</id> <phase>package</phase> <goals> <goal>copy-resources</goal> </goals> <configuration> <resources> <resource> <directory>/src/main/resources</directory> <includes> <include>config/*</include> <include>apns/*</include> <include>static/*</include> </includes> <excludes> <exclude>/.*</exclude> </excludes> </resource> <resource> <directory>/</directory> <includes> <include>doc/部署说明.md</include> </includes> </resource> </resources> <outputDirectory>${project.build.directory}</outputDirectory> </configuration> </execution> </executions> </plugin> <plugin> <artifactId>maven-jar-plugin</artifactId> <configuration> <!--不打入jar包的文件类型或者路径--> <excludes> <exclude>config/**</exclude> <exclude>static/**</exclude> <exclude>*.properties</exclude> <exclude>*.pfx</exclude> </excludes> </configuration> </plugin> </plugins> </build> </project>
2.1 maven-resources-plugin是为了输出,这里边主要的部分是<execution>元素,其中有几处需要说明:
- <directory>src/main/resources</directory> 指定要处理的文件夹,
- 输出目录必须指定${project.build.directory},也就是生成的jar包所在目录(一般是target),也可以附件子目录如写成${project.build.directory}/xxx,xxx是子目录名称,这样文件都拷贝到jar包所在的xxx下,便于拷贝。
- 输入目录都是以<directory>src/main/resources</directory>目录为根的,包含include和exclude两个部分。注意两点,一是插件只针对文件进行筛选,而其所属文件夹路径是会自动创建的。二是排除操作会在包含之后应用,所以如果一个文件匹配了
include
模式,然后又匹配了exclude
模式,它最终会被排除。文件路径中的*是占位符,匹配文件路径的任意字符,所以用到不同位置有不同效果:
-
- * 匹配所有文件
- ** 匹配根目录
- *.properties 匹配扩展名为properties的文件
- .* 匹配路径是.起头的文件,如.tmp/1/2/3/x.bmp
- *.* 匹配所有路径带点的文件
- */* 匹配所有带/的文件,但不匹配根文件夹下的
- **/* 匹配所有带/的文件,包括根文件夹下的
- 可以带上子目录名,如config/*.properties、**/3.4/*等等,只要文件的路径中有子目录名,文件就会匹配。
- /*/*.xml 匹配一级目录下的所有xml文件
- 可以有多个<execution>,注意id区分即可
2.2 maven-jar-plugin 负责控制打包。 既然我们已经将上述文件拷贝出jar,可以将它们从jar中剔除。 当然有时保留一份文件在jar里面也很好,毕竟放到外边的可能会被小白改的面目全非,重回起点也是个不错的选择。
2.3 在此提一下SpringBoot查找配置文件的位置优先顺序:
- 命令行用--spring.config.location 指定的配置文件路径。
SPRING_CONFIG_LOCATION
环境变量指定的路径。- 当前路径的 /config 子路径内:file:./config/
- 当前路径:file:./
- classpath 路径下的 /config 包内:classpath:/config/
- classpaht 根路径:classpath:/
考考你,现在能说出 **/config/*、*/config/*、**config/*、/config/*、config/* 这几个include值的区别吗? 可以执行maven package反复测试下找一下规律。
2.4 最后,需要在程序中做好特定的设置,以便生成的jar包在启动后,能够找到这些“跑出jar包”的文件。一般是在生效的配置文件如bootstrap.properties里这么设定:
然后在bootstrap-dev.properties文件里写: