AppAssember和maven-resources-plugin插件的使用

maven-resources-plugin 处理资源文件

目标:resources, testResources

指定resources插件读取和写入文件的字符编码,比如ASCII,UTF-8或UTF-16。

复制代码
<build>
    <plugins>
        <plugin>
            <artifactId>maven-resources-plugin</artifactId>
            <version>3.0.2</version>
            <configuration>
                <encoding>UTF-8</encoding>
            </configuration>
        </plugin>
    </plugins>
</build>

默认情况下,Maven会从项目的src/main/resources目录下查找资源。如果你的资源不在此目录下,可以用<resources>标签指定,同时也支持多个目录。

复制代码
<build>
    <resources>
        <resource>
            <directory>src/main/resources1</directory>
        </resource>
        <resource>
            <directory>src/main/resources2</directory>
        </resource>
    </resources>
</build>

有的时候,资源文件中存在变量引用,可以使用<filtering>标签指定是否替换资源中的变量。变量的来源为pom文件中的<properties>标签中定义的变量。也可以在<build>中定义过滤器资源,还可以使用<includes>和<excludes>来精细控制。

复制代码
<build>
    <filters>
        <filter>filter-values.properties</filter>
    </filters>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
            <includes>
              <include>**/*.txt</include>
              <include>**/*.rtf</include>
            </includes>
            <excludes>
              <exclude>**/*.bmp</exclude>
              <exclude>**/*.jpg</exclude>
              <exclude>**/*.jpeg</exclude>
              <exclude>**/*.gif</exclude>
            </excludes>
        </resource>
    </resources>
</build>

如果资源中本来存在{}字符,不需要被替换,可以在前加\,并在<configuration>中使用<escapeString>。

另外,目录下存在二进制文件,需要排除,也可以在<configuration>中使用<nonFilteredFileExtensions>根据后缀来过滤。

复制代码
<plugins>
    <plugin>
        <artifactId>maven-resources-plugin</artifactId>
        <version>3.0.2</version>
        <configuration>
            <encoding>UTF-8</encoding>
            <escapeString>\</escapeString>
            <nonFilteredFileExtensions>
                <nonFilteredFileExtension>pdf</nonFilteredFileExtension>
                <nonFilteredFileExtension>swf</nonFilteredFileExtension>
            </nonFilteredFileExtensions>
        </configuration>
  </plugin>

AppAssembler Maven 插件

AppAssembler Maven 插件 中的一段配置,用于把 Spring Boot 应用打成 可解压的目录包(而非 fat-jar)。

复制代码
   <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>appassembler-maven-plugin</artifactId>
        <version>2.1.0</version>
        <executions>
            <execution>
                <id>make-assembly</id>
                <phase>package</phase>
                <goals>
                    <goal>assemble</goal>
                </goals>
            </execution>
        </executions>
        <configuration>
            <configurationDirectory>conf</configurationDirectory>
            <configurationSourceDirectory>src/main/resources</configurationSourceDirectory>
            <copyConfigurationDirectory>true</copyConfigurationDirectory>
            <includeConfigurationDirectoryInClasspath>true</includeConfigurationDirectoryInClasspath>
            <repositoryLayout>flat</repositoryLayout>
            <repositoryName>lib</repositoryName>
            <useWildcardClassPath>true</useWildcardClassPath>
            <!-- 避免二次过滤 -->
            <filterConfigurationDirectory>false</filterConfigurationDirectory>
            <environmentSetupFileName>init.sh</environmentSetupFileName>
            <assembleDirectory>${project.build.directory}/${project.artifactId}-${project.version}</assembleDirectory>
            <platforms>
                <platform>unix</platform>
            </platforms>
            <programs>
                <program>
                    <id>${project.artifactId}</id>
                    <mainClass>com.MyApiApplication</mainClass>
                    <platforms>
                        <platform>unix</platform>
                    </platforms>
                </program>
            </programs>
        </configuration>
    </plugin> 

逐行解释如下:

配置项 含义
<configurationDirectory>conf</configurationDirectory> 在最终目录里创建一个 conf/ 目录,用来存放配置文件。
<configurationSourceDirectory>src/main/resources</configurationDirectory> src/main/resources 下的所有文件原样复制到 conf/
<copyConfigurationDirectory>true</copyConfigurationDirectory> 启用 上述复制。设为 false 就不会复制资源文件。
<includeConfigurationDirectoryInClasspath>true</includeConfigurationDirectoryInClasspath> 启动脚本会把 conf/ 目录加入 JVM 的 classpath,运行时能直接读取里面的配置。
<repositoryLayout>flat</repositoryLayout> 所有依赖 jar 平铺放在 lib/ 目录,而不是按 groupId 分多级目录。
<repositoryName>lib</repositoryName> 依赖 jar 所在的目录名字,最终生成 /lib
<useWildcardClassPath>true</useWildcardClassPath> 启动脚本用通配符 lib/* 加载所有 jar,避免列出每个文件名。
<filterConfigurationDirectory>false</filterConfigurationDirectory> 关闭conf/ 目录的 Maven 资源过滤,防止二进制文件(pfx、pem 等)被编码。(没法区分目录来进行filter)
<environmentSetupFileName>init.sh</environmentSetupFileName> bin/ 目录额外生成 init.sh 脚本,可写环境变量、前置命令等。

这段配置让 AppAssembler 把 src/main/resources 原样拷到 conf/ 并加入 classpath,依赖平铺到 lib/,且不对二进制文件做过滤,最终得到一个可解压、可执行、目录结构的部署包。

启动脚本

复制代码
<programs>
    <program>
        <id>${project.artifactId}</id>
        <mainClass>com.MyApiApplication</mainClass>
        <platforms>
            <platform>unix</platform>
        </platforms>
    </program>
</programs>
  • target/my-api-1.0.0/bin/my-api(Unix 脚本)中:

    #!/bin/sh

    由 AppAssembler 自动生成

    CLASSPATH="conf:lib/*"
    exec java -classpath "CLASSPATH" com.myApplication "@"

最终目录结构

复制代码
target/my-api-1.0.0/
├── bin/
│   ├── my-api        # 启动脚本
│   └── init.sh            # 环境脚本
├── conf/
│   ├── application.yml    # 来自 target/classes/tmp/
│   ├── server.pfx         # 证书原样复制
│   └── logback.xml
└── lib/
    ├── spring-boot-*.jar
    └── your-app-*.jar

项目运行

脚本运行

复制代码
cd /Users/manka/project/my-api/target/my-api-0.0.1-SNAPSHOT
./bin/my-api

java指令运行

复制代码
cd /Users/manka/project/my-api/target/my-api-0.0.1-SNAPSHOT
java -cp "conf:lib/*" -Dspring.config.location=optional:classpath:/,file:conf/ com.MyApiApplication

插件执行顺序

maven-resources-plugin 先于 appassembler-maven-plugin 执行

前者在 process-resources 阶段完成资源复制,后者在 package 阶段把已生成的资源再搬运到最终目录。

插件 默认绑定阶段 作用
maven-resources-plugin process-resources src/main/resourcestarget/classes
appassembler-maven-plugin package target/classes(或你指定的目录)→ target/artifactId-version/conf/

两者结合使用

需求:

1、想要区分目录的文件进行filter, 其他目录不进行filter。

2、项目打包脚本用到了appassembler-maven-plugin。

解决:

<resources> 先过滤/复制,AppAssembler 再二次搬运;两者职责互补,可同时使用,只需确保 AppAssembler 的 filterConfigurationDirectory 设为 false 即可保护二进制文件.

  • <resources> 负责把 源码阶段 的文件(src/main/resources 等)原样或过滤后复制到 target/classes;

  • appassembler-maven-plugin 再把 已生成的 target/classes 或你指定的其它目录,二次拷贝到最终打包目录(conf/、lib/、bin/)。

    src/main/resources/config/ true **/* ${project.build.outputDirectory}/tmp/config ${project.basedir}/src/main/resources/cert * ${project.build.outputDirectory}/tmp/cert org.codehaus.mojo appassembler-maven-plugin 2.1.0 make-assembly package assemble conf ${project.build.outputDirectory}/tmp true true flat lib true false init.sh ${project.build.directory}/${project.artifactId}-${project.version} unix ${project.artifactId} com.MyApplication unix
相关推荐
小宇宙Zz1 天前
Maven依赖冲突
java·服务器·maven
砚底藏山河1 天前
沪深A股:如何获取基金持股数据
java·python·数据分析·maven
一勺菠萝丶1 天前
Maven SNAPSHOT 父 POM 无法解析问题排查
java·maven
我登哥MVP1 天前
SpringCloud Alibaba 核心组件解析:服务链路追踪
java·spring boot·后端·spring·spring cloud·java-ee·maven
南部余额1 天前
Maven Archetype 项目模板
java·maven·项目·archetype
梦想的旅途21 天前
企业微信外部群自动化:一期交付应聚焦双向会话闭环
java·开发语言·机器人·自动化·maven·企业微信
vx-Biye_Design1 天前
springboot安阳地区研学旅游服务小程序-计算机毕业设计源码12785
java·vue.js·windows·spring boot·tomcat·maven·mybatis
Clang's Blog2 天前
Ubuntu(20.04/22.04/24.04)国内环境一键安装 Docker、JDK17 和 Maven
ubuntu·docker·maven
编程的一拳超人2 天前
Maven 国内高速镜像推荐(按速度排序)
java·maven
Orchestrator_me2 天前
Centos7安装maven 3.9.11
java·maven