maven pom 配置 学习笔记(六)之 maven-dependency-plugin (依赖zip包并将其解压到某个目录下)

一、背景

    一般情况下会认为 maven 是给Java工程使用的,但实际并不是,一个程序由多方构成,包括:自己编写的程序代码、依赖的第三方程序(可能是jar、可能就是一个二进制文件、或这个C++库等),基于此,自己编写的程序可以直接通过 maven依赖将自己需要的第三方程序自动加载到本地。

二、场景

1、  程序依赖的第三方程序在一个zip包中,目前需要将该 zip 通过 maven 依赖进来,程序打包生成成果物的时候,需要将zip包解压放到指定的目录中,供自己的程序执行时可调用。

这里仅是举简单的例子:

(1) 依赖的第三方zip包生成

   工程目录结构:

 这里通过pom.xml 及 assembly-zip-deploy.xml 将 consul 二进制文件打包 到一个 zip包中,可以看下这两个文件的配置内容。

pom.xml

<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>com.summer</groupId>
    <artifactId>maven-assembly-demo</artifactId>
    <packaging>pom</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <name>maven-assembly-demo</name>
    <description>demo for maven-assembly-plugin</description>
    
    <build>
       <plugins>
          <plugin>
             <groupId>org.apache.maven.plugins</groupId>
             <artifactId>maven-assembly-plugin</artifactId>
             <version>3.3.0</version>
             <executions>
                <execution>
                   <id>assembly-package</id>
                   <phase>package</phase>
                   <goals>
                      <goal>single</goal>
                   </goals>
                </execution>
             </executions>
             <configuration>
                <descriptors>
                  <descriptor>assembly-zip-deploy.xml</descriptor>
                </descriptors>
                <outputDirectory>output</outputDirectory>
             </configuration>
          </plugin>
       </plugins>
    </build>
    
    <!-- 内部开发版本发布库,这个必须配置,若不配置中央仓库的话,发布不了 -->
    <distributionManagement>
        <repository>
            <id>maven-releases</id>
            <name>maven-releases</name>
            <url>http://127.0.0.1:8081/repository/maven-releases/</url>
        </repository>
        <snapshotRepository>
            <id>maven-snapshots</id>
            <name>maven-snapshots</name>
            <url>http://127.0.0.1:8081/repository/maven-snapshots/</url>
        </snapshotRepository>
    </distributionManagement>
</project>

 assembly-zip-deploy.xml

<?xml version='1.0' encoding='UTF-8'?> 
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.1.0 http://maven.apache.org/xsd/assembly-2.1.0.xsd">
    <id>package</id>
    <formats> 
        <format>zip</format> 
    </formats> 
     <!-- 该值为false表示 output下面不会有个根目录,名为 artifactId_version
                             是直接将 fileSets 中的 文件直接放在output下面,见 maven-assembly-demo-0.0.1-SNAPSHOT-package.zip zip包结构
          值为true时,可见 maven-assembly-demo-0.0.1-SNAPSHOT-package-includebasedirectory.zip
      -->
    <includeBaseDirectory>false</includeBaseDirectory>
   
    <fileSets> 
        <fileSet> 
            <directory>zipDeploy</directory> 
            <outputDirectory>/</outputDirectory>    //将zipDeploy 目录下的文件复制到 maven-assembly-plugin 配置的 output 目录下
        </fileSet> 
    </fileSets> 
</assembly>

 通过以上两个文件打出来的zip目录结构如下:

 注意:

(a) zip包名字构成为:maven-assembly-plugin 配置的 finalName +  assembly-zip-deploy.xml 配置的 id ,若 maven-assembly-plugin 中没有配置 finalName,则默认 finalName 为 artifactId-version,若想生成的 zip 不包含 assembly-zip-deploy.xml 配置的 id,可以在 maven-assembly-plugin 下配置  <appendAssemblyId>false</appendAssemblyId>。

(b) finalName +  assembly-zip-deploy.xml 配置的 id 被包含在 zip 名字中之后,该 id 可以作为 classifier 来使用。

(2) 自己编写的程序工程依赖 (1) 中通过 maven-assembly-plugin 打出来的 zip 包。

工程目录结构:

 该工程也使用了 maven-assembly-plugin 来进行打包,我们的目标是打包出来的成果物,bin 目录下要包含 (1) 中zip包中的 consul 二进制文件。

pom.xml

<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>com.summer</groupId>
    <artifactId>maven-dependency-plugin-demo</artifactId>
    <packaging>pom</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <name>maven-dependency-plugin-demo</name>
    <description>demo for maven-dependency-plugin</description>

    <dependencies>
        <dependency>
            <groupId>com.summer</groupId>
            <artifactId>maven-assembly-demo</artifactId>
            <version>0.0.1-SNAPSHOT</version>
            <classifier>package</classifier>
            <type>zip</type>   //依赖 zip 包
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>2.8</version>
                <executions>
                    <execution>
                        <id>unpack</id>
                        <phase>package</phase>
                        <goals>
                            <goal>unpack</goal>
                        </goals>
                        <configuration>   //打包阶段将依赖的zip解压到指定的 bin 目录下
                            <artifactItems>
                                <artifactItem>
                                    <groupId>com.summer</groupId>
                                    <artifactId>maven-assembly-demo</artifactId>
                                    <version>0.0.1-SNAPSHOT</version>
                                    <classifier>package</classifier>
                                    <type>zip</type>
                                    <outputDirectory>${project.basedir}/bin</outputDirectory>
                                </artifactItem>
                            </artifactItems>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>3.3.0</version>
                <executions>
                    <execution>
                        <id>assembly-package</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <descriptors>
                        <descriptor>assembly-unpack-zip-deploy.xml</descriptor>
                    </descriptors>
                    <outputDirectory>output</outputDirectory>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <!-- 内部开发版本发布库,这个必须配置,若不配置中央仓库的话,发布不了 -->
    <distributionManagement>
        <repository>
            <id>maven-releases</id>
            <name>maven-releases</name>
            <url>http://127.0.0.1:8081/repository/maven-releases/</url>
        </repository>
        <snapshotRepository>
            <id>maven-snapshots</id>
            <name>maven-snapshots</name>
            <url>http://127.0.0.1:8081/repository/maven-snapshots/</url>
        </snapshotRepository>
    </distributionManagement>
</project>

assembly-unpack-zip-deploy.xml

<?xml version='1.0' encoding='UTF-8'?> 
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.1.0 http://maven.apache.org/xsd/assembly-2.1.0.xsd">
    <id>package</id>
    <formats> 
        <format>zip</format> 
    </formats> 
     <includeBaseDirectory>false</includeBaseDirectory>
   
    <fileSets> 
        <fileSet> 
            <directory>${project.basedir}</directory> 
            <outputDirectory>/</outputDirectory> 
            <includes>
               <include>bin/**</include>
               <include>config/**</include>
            </includes>
        </fileSet> 
    </fileSets> 
</assembly>

 以上打出来的zip包结构为:

 三、知识点说明

官网叙述地址:http://maven.apache.org/ref/3.6.3/maven-model/maven.html#class_dependency

1、精确匹配依赖某个构件(可以是从一个pom生成的多个成果物,如:log4j-to-slf4j-2.11.2.jar、log4j-to-slf4j-2.11.2-javadoc.jar、log4j-to-slf4j-2.11.2-sources.jar)

<dependency> 表示依赖一个构件,通过 <dependency> 的多个子属性精确匹配到某个构件,一个构件组成结构为:artifactid-version-classifier.type,如:上述例子 一下的(1) 生成的成果物为:maven-assembly-demo-0.0.1-SNAPSHOT-package.zip ,此时 artifactid为 assembly-demo,version 为 0.0.1-SNAPSHOT,classifier 为 package,type 为 zip,一般从同一个pom若出多个成果物的话,就是使用 classifier 进行区分的。

一般情况下,我们依赖都是这么些:

<dependency>
    <groupId>com.summer</groupId>
    <artifactId>maven-assembly-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

默认:classifier为null,type 为 jar,上述表示依赖 maven-assembly-demo-0.0.1-SNAPSHOT.jar 包。官网提供了支持的type类型的范围,但是经过上面的例子感觉 type 不在该范围也是可以的,比如:zip

 官网对这几个属性的解释为:

 2、直接依赖的 jar包可以选择性的传递给依赖当前程序的程序

如: A 直接依赖 B(A pom 使用 dependency 标签直接依赖 B),现在 C 直接依赖 A,若A已经决定 B是否要被C间接依赖 ,可以使用 optional

A.pom

<dependency>
    <groupId>xxx</groupId>
    <artifactId>B</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <optional>true</optional>   //表示 依赖A的程序必须自己声明依赖B,否则B的包不会被程序间接依赖到
</dependency>

  C.pom

<dependency>
    <groupId>xxx</groupId>
    <artifactId>A</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

此时C的依赖列表里面不会有 B

<dependency>
    <groupId>xxx</groupId>
    <artifactId>A</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
    <groupId>xxx</groupId>
    <artifactId>B</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

此时C的依赖列表里面既有A也有B。

PS:

对于这种用法还需谨慎,一般A程序依赖B说明A的功能是需要B程序的,C使用A的功能很有可能也要B。这种用法一般在 Spring 里面看到过,它会使用 @ConditionOnClass(xxx.class)来决定注解该注解的类是否需要执行。

原文地址:https://www.cnblogs.com/sandyflower/p/14076328.html