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/)。

    <resource> <directory>src/main/resources/config/</directory> <filtering>true</filtering> <includes> <include>**/*</include> </includes> <targetPath>${project.build.outputDirectory}/tmp/config</targetPath> </resource> <resource> <directory>${project.basedir}/src/main/resources/cert</directory> <includes> <include>*</include> </includes> <targetPath>${project.build.outputDirectory}/tmp/cert</targetPath> </resource> <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>${project.build.outputDirectory}/tmp</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.MyApplication</mainClass> <platforms> <platform>unix</platform> </platforms> </program> </programs> </configuration> </plugin>
相关推荐
5pace18 小时前
【JavaWeb|第一篇】Maven篇
java·maven
半梦半醒*19 小时前
Jenkins流水线项目发布
运维·ci/cd·tomcat·jenkins·maven·运维开发
一只游鱼20 小时前
maven简介与安装
java·maven
考虑考虑1 天前
解决idea导入项目出现不了maven
java·后端·maven
敲代码的嘎仔1 天前
JavaWeb零基础学习Day4——Maven
java·开发语言·学习·算法·maven·javaweb·学习方法
陈小桔1 天前
idea中重新加载所有maven项目失败,但maven compile成功
java·maven
自由会客室2 天前
Ubuntu 24.04 上安装 Sonatype Nexus Repository(Maven 私服)
架构·maven
哞哞不熬夜2 天前
JavaEE--SpringIoC
java·开发语言·spring boot·spring·java-ee·maven
TT哇2 天前
【Maven】Maven设置国内源
java·maven
编啊编程啊程2 天前
【011】宠物共享平台
spring boot·log4j·maven·dubbo·宠物