使用Maven为一个工程生成多个jar包

目录

前言

实现

多模块实现

maven-assembly-plugin插件实现

关于properties标签题外话(maven的内置变量)


前言

有时候我们需要在一个java工程内执行打包命令能生成多个jar包,每个jar包的具体内容都与具体实现类相绑定,这样的好处就是方便。比如我们项目中对外提供了插件扩展,第三方使用者只需要实现我们的插件接口,然后打成jar包上传到我们的项目中便可动态解析,而使用者的需求便是能在一个工程内同时编辑多个业务插件,最终打包时也能生成多个不同的jar包以作不同的用途,因此作为产品方需要给出一个demo供他们直接上手。

实现

多模块实现

这个应该很好理解,可以使用多模块的方式实现,每个模块就相当于一个插件,最终打包时直接mvn package便能在不同模块的target目录下输出各自的jar包,实现简单,但是层次上存在一个父子关系,而实际上并不存在,因此不太好。

maven-assembly-plugin插件实现

使用该插件配合描述文件实现,整体项目结构如下图:

pom文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>qingcha.test</groupId>
    <artifactId>multiPluginDemo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!-- 引入插件目标接口以及相关依赖 -->
        <dependency>
            <artifactId>hornet-web-api</artifactId>
            <groupId>uyun.hornet</groupId>
            <version>2.0.0-SNAPSHOT</version>
            <!-- 表示已提供依赖范围,由于是作为插件jar包运行在主项目中,而主项目中存在该依赖,因此实际运行的时候并不需要maven重复引入一遍,
             因此该依赖范围表示只在测试和编译classpath时有效,在运行时无效,换句话说就是该依赖不会被打进包中-->
            <scope>provided</scope>
        </dependency>

    </dependencies>

    <!-- 在properties标签中定义的值可以通过使用${key}在pom的任何位置访问,其中key为属性值 -->
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <maven.compiler.encoding>UTF-8</maven.compiler.encoding>
        <project.assembly.directory>src/main/resources/assembly</project.assembly.directory>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>2.6</version>

                 <configuration>
                    <!--该方式会将所有依赖打包到jar,生成的jar包带有jar-with-dependencies后缀 -->
                    <descriptorRefs>
                        <!-- 将依赖一起打包到 JAR -->
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>

                    <!-- 该标签可以配置主main类,即 使该jar包成为可执行jar包,可在META-INF下的MF文件中找到Main-class一行 -->
                    <archive>
                        <manifest>
                            <mainClass></mainClass>
                        </manifest>
                    </archive>
                </configuration>

                <!-- 配置执行器,若还想增加编写新的插件,在此处新增执行器即可 -->
                <executions>
                    <execution>
                        <!-- 执行器id -->
                        <id>plugin1</id>
                        <!-- 绑定到maven的package生命周期 -->
                        <phase>package</phase>
                        <goals>
                            <!-- 代表只运行一次 -->
                            <goal>single</goal>
                        </goals>
                        <configuration>
                            <descriptors>
                                <!-- 描述文件的地址 -->
                                <descriptor>${project.assembly.directory}/assembly-plugin1.xml</descriptor>
                            </descriptors>
                            <!-- 自定义包名,如果不配置则是 artifactId + version + assemblyId,配置后则为 finalName + assemblyId,当然也可以增加属性去除自动拼接assemblyId值 -->
                            <finalName>multiPluginDemo</finalName>
                        </configuration>
                    </execution>

                    <execution>
                        <id>plugin2</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                        <configuration>
                            <descriptors>
                                <descriptor>${project.assembly.directory}/assembly-plugin2.xml</descriptor>
                            </descriptors>
                            <finalName>multiPluginDemo</finalName>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

其中打包脚本之一的assembly-plugin1.xml文件如下:

<assembly
        xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">

    <!-- 文件id,与前面保持一致即可 -->
    <id>plugin1</id>
    <!-- 是否生成和压缩包同名的项目和目录 -->
    <includeBaseDirectory>false</includeBaseDirectory>
    <formats>
        <!-- 指定格式 -->
        <format>jar</format>
    </formats>

    <fileSets>
        <fileSet>
            <!-- 文件所在项目中的位置 -->
            <directory>${project.build.outputDirectory}/qingcha/test/common</directory>
            <!-- 打包后的展示路径,必须与包路径保持一致 -->
            <outputDirectory>qingcha/test/common</outputDirectory>
        </fileSet>
        <fileSet>
            <directory>${project.build.outputDirectory}/qingcha/test/plugin1</directory>
            <outputDirectory>qingcha/test/plugin1</outputDirectory>
        </fileSet>
        <fileSet>
            <directory>src/main/resources/plugin1</directory>
            <!-- 由于依赖spi机制,因此这里的输出路径需要满足条件,否则插件便不生效了 -->
            <outputDirectory>META-INF/services</outputDirectory>
        </fileSet>
    </fileSets>
</assembly>

最终直接使用mvn package打包即可,可在target/ 目录下看到最终的jar包,多个plugin会有多个jar包:

如果还要增加一个plugin的话,可依次增加对应的实现类、提供者配置文件、脚本描述文件、执行器

关于properties标签题外话(maven的内置变量)

在上面的脚本描述文件中有使用到 ${project.build.outputDirectory} ,然后查看pom文件发现我们并没有定义该key值,因此也能猜到这是maven的内置变量,常用的内置变量如下:

  • ${project.basedir}:这引用了module/project的根文件夹(当前pom.xml文件所在的位置),还可以简化的写法:${basedir}
  • ${project.build.directory}:这表示默认的target文件夹。
  • ${project.build.outputDirectory}:默认情况下表示target/classes文件夹。
  • ${project.build.testOutputDirectory}:这表示默认的target/test-classes文件夹。
  • ${project.build.sourceDirectory}:这表示默认情况下src/main/java文件夹。
  • ${project.build.testSourceDirectory}:这表示默认情况下src/test/java文件夹。
  • ${project.build.finalName}:默认情况下定义为${project.artifactId}-${project.version}。
  • ${project.version}:这可以在必须编写文字版本的位置使用,否则,特别是如果您在多模块构建模块间依赖关系。
  • ${settings.localRepository}:它引用了本地存储库的位置。这是默认的${home}/.m2/repository。
 

猜你喜欢

转载自blog.csdn.net/m0_38001814/article/details/104505990