maven

maven-surefire-plugin

就是在maven的生命周期的测试阶段,通过插件来执行JUnit或者TestNG的测试用例

msglink
maven maven-jar-plugin maven-assembly-plugin的区别link
maven maven-antrun-plugin 的作用link
link
link
link
link
link
link
link
link
link
link

nuxus 上传

link





## 打包排除resources里的东西

```sql
 <resources>
            <resource>
                <directory>${project.basedir}/src/main/resources</directory>
                <filtering>true</filtering>
                <excludes>
                    <exclude>**</exclude>
                </excludes>
            </resource>
        </resources>

总结

click for setting

  • 1setting中的server中的id必须和pom中distributionManagement的id匹配,才能deploy成功
  • 2 mirror本质是对你配置的repository的拦截器;具体看下面的mirror图
  • 3当自己使用的时候,建议用阿里的mirror,公司使用,还是陪着repository好一点;

server是上传你的jar包用的(deplment)、mirror、 repositories是下载jar包用的;

distributionManagement

在 Maven 项目中,distributionManagement 标签用于配置项目发布的相关信息,其中包括两个重要的子标签:snapshotRepository 和 repository。它们分别用于定义快照版本和正式版本的发布位置。

snapshotRepository
snapshotRepository 子标签用于配置项目快照版本(SNAPSHOT)的发布位置。快照版本是指那些在开发过程中不断变化的版本,通常用于尚未正式发布的开发版本。Maven 允许这些快照版本频繁发布和更新。

如果配置了snapshotRepository又配置了repository,那么进行发布操作,maven会两个仓库都发布吗

在 Maven 中,当你配置了 snapshotRepository 和 repository,并进行发布操作时,Maven 根据版本号的类型(SNAPSHOT 或非 SNAPSHOT)决定发布到哪个仓库。

通常在开发过程中会频繁发布 SNAPSHOT 版本到 snapshotRepository,而在准备发布正式版本时会先通过 mvn release:prepare 和 mvn release:perform 完成版本发布,这将确保版本号从 SNAPSHOT 转为正式版本,并发布到 repository。

行为总结

jie dian config

  • pom
<distributionManagement>
            <snapshotRepository>
                <id>jiedian-snapshot</id>
                <name>jiedian-snapshot</name>
                <url>https://maven.int.jiediankeji.com/content/repositories/snapshots/</url>
            </snapshotRepository>
    </distributionManagement>
  • setting
<servers>
        <server>
            <id>jiedian-snapshot</id>
            <username>deployment</username>
            <password>4cde205bf83f333a7765bd38368e4bbd</password>
        </server>
    </servers>
  • profile
<profile>
            <id>default</id>
            <activation>
                <activeByDefault>true</activeByDefault>
                <jdk>11</jdk>
            </activation>
            <repositories>
                <repository>
                    <id>jiedian-releases</id>
                    <name>jiedian-releases</name>
                    <url>https://maven.int.jiediankeji.com/content/repositories/releases/</url>
                    <releases>
                        <enabled>true</enabled>
                    </releases>
                    <snapshots>
                        <enabled>false</enabled>
                    </snapshots>
                    <layout>default</layout>
                </repository>
                <repository>
                    <id>jiedian-snapshot</id>
                    <name>jiedian-snapshot</name>
                    <url>https://maven.int.jiediankeji.com/content/repositories/snapshots/</url>
                    <releases>
                        <enabled>false</enabled>
                    </releases>
                    <snapshots>
                        <enabled>true</enabled>
                    </snapshots>
                    <layout>default</layout>
                </repository>
            </repositories>
        </profile>
  </profiles>

setting

重要参考
link

setting of profile

profile元素由activation、repositories、pluginRepositories和properties四个元素组成。当一个profile在settings.xml中是处于活动状态并且在pom.xml中定义了一个相同id的profile时,settings.xml中的profile会覆盖pom.xml中的profile

<profiles>
        <!--根据环境参数来调整的构件的配置-->
        <profile>
            <id>jdk-11</id>
            <!--当所有的约束条件都满足的时候就会激活这个profile。-->
            <activation>
                <!--当其值为true的时候表示如果没有其他的profile处于激活状态的时候,该profile将自动被激活。-->
                <activeByDefault>false</activeByDefault>
                <!--当匹配的jdk被检测到,profile被激活。例如,1.4激活JDK1.4,1.4.0_2,而!1.4激活所有版本不是以1.4开头的JDK。
 这里的版本还可以用一个范围来表示,如
<jdk>[1.4,1.7)</jdk>表示1.4、1.5和1.6满足;
<jdk>[1.4,1.7]</jdk>表示1.4、1.5、1.6和1.7满足;-->
                <jdk>1.5</jdk>
                <!--表示当操作系统满足条件的时候激活。-->
                <os>
                    <!--激活profile的操作系统的名字 -->
                    <name>Windows XP</name>
                    <!--激活profile的操作系统所属家族(如 'windows')  -->
                    <family>Windows</family>
                    <!--激活profile的操作系统体系结构  -->
                    <arch>x86</arch>
                    <!--激活profile的操作系统版本-->
                    <version>5.1.2600</version>
                </os>
                <!--property是键值对的形式,表示当Maven检测到了这样一个键值对的时候就激活该profile。如果值字段是空的,那么存在属性名称字段就会激活profile,否则按区分大小写方式匹配属性值字段-->
                <property>
                    <!--这个时候如果要激活该profile的话,可以在调用Maven指令的时候加上参数mavenVersion并指定其值为>2.0.3,如:mvn compile –DmavenVersion=>2.0.3-->
                    <name>mavenVersion</name>
                    <!--激活profile的属性的值 -->
                    <value>2.0.3</value>
                </property>
                <!--表示当文件存在或不存在的时候激活,exists表示存在,missing表示不存在。如下面的例子表示当文件hello/world不存在的时候激活该profile。-->
                <file>
                    <!--如果指定的文件存在,则激活profile。 -->
                    <exists>${basedir}/file2.properties</exists>
                    <!--如果指定的文件不存在,则激活profile。-->
                    <missing>${basedir}/file1.properties</missing>
                </file>
            </activation>
            <!--用于定义远程仓库的,当该profile是激活状态的时候,这里面定义的远程仓库将作为当前pom的远程仓库。 -->
            <repositories>
                <repository>
                    <id>jdk14</id>
                    <name>Repository for JDK 1.4 builds</name>
                    <url>http://www.myhost.com/maven/jdk14</url>
                    <layout>default</layout>
                    <snapshotPolicy>always</snapshotPolicy>
                </repository>
            </repositories>
        </profile>
        <profile>
            <id>env-dev</id>
            <activation>
                <property>
                    <name>target-env</name>
                    <value>dev</value>
                </property>
            </activation>
            <properties>
                <tomcatPath>/path/to/tomcat/instance</tomcatPath>
            </properties>
        </profile>
        <profile>
            <id>nexusProfile</id>
            <!--远程仓库列表,它是Maven用来填充构建系统本地仓库所使用的一组远程项目。 -->
            <repositories>
                <!--包含需要连接到远程仓库的信息 -->
                <repository>
                    <!--远程仓库唯一标识-->
                    <id>nexusProfile</id>
                    <!--远程仓库名称 -->
                    <name>nexus repository</name>
                    <!--用于定位和排序构件的仓库布局类型-可以是default(默认)或者legacy(遗留)。Maven 2为其仓库提供了一个默认的布局;然而,Maven 1.x有一种不同的布局。我们可以使用该元素指定布局是default(默认)还是legacy(遗留)。 -->
                    <layout>default</layout>
                    <!--远程仓库URL,按protocol://hostname/path形式
		  -->
                    <url>http://196.160.1.211:8081/nexus/content/groups/public/</url>
                    <!--如何处理远程仓库里发布版本的下载-->
                    <releases>
                        <!--true或者false表示该仓库是否为下载某种类型构件(发布版,快照版)开启。  -->
                        <enabled>true</enabled>
                        <!--该元素指定更新发生的频率。Maven会比较本地POM和远程POM的时间戳。这里的选项是:always(一直),daily(默认,每日),interval:X(这里X是以分钟为单位的时间间隔),或者never(从不)。 -->
                        <updatePolicy>always</updatePolicy>
                        <!--当Maven验证构件校验文件失败时该怎么做-ignore(忽略),fail(失败),或者warn(警告)。-->
                        <checksumPolicy>warn</checksumPolicy>
                    </releases>
                    <!--如何处理远程仓库里快照版本的下载。有了releases和snapshots这两组配置,POM就可以在每个单独的仓库中,为每种类型的构件采取不同的策略。例如,可能有人会决定只为开发目的开启对快照版本下载的支持。参见repositories/repository/releases元素-->
                    <snapshots>
                        <enabled>true</enabled>
                    </snapshots>
                </repository>
            </repositories>
        </profile>
        <profile>
            <id>centralProfile</id>
            <repositories>
                <repository>
                    <id>central</id>
                    <name>Central Repository</name>
                    <!-- 虚拟的URL形式,指向镜像的URL,因为所有的镜像都是用的是nexus,这里的central实际上指向的是http://repos.d.xxx.com/nexus/content/groups/public -->
                    <url>https://repo.maven.apache.org/maven2</url>
                    <layout>default</layout>
                    <snapshots>
                        <enabled>true</enabled>
                    </snapshots>
                </repository>
            </repositories>
        </profile>
    </profiles>

setting of mirror

用于定义一系列的远程仓库的镜像。我们可以在pom中定义一个下载工件的时候所使用的远程仓库。但是有时候这个远程仓库会比较忙,所以这个时候人们就想着给它创建镜像以缓解远程仓库的压力,也就是说会把对远程仓库的请求转换到对其镜像地址的请求。每个远程仓库都会有一个id,这样我们就可以创建自己的mirror来关联到该仓库,那么以后需要从远程仓库下载工件的时候Maven就可以从我们定义好的mirror站点来下载,这可以很好的缓解我们远程仓库的压力。在我们定义的mirror中每个远程仓库都只能有一个mirror与它关联,也就是说你不能同时配置多个mirror的mirrorOf指向同一个repositoryId

    <mirrors>
        <mirror>
            <!--该镜像的唯一标识符。id用来区分不同的mirror元素。 -->
            <id>mirrorId</id>
            <!-- 用来表示该mirror是关联的哪一个仓库,其值为其关联仓库的id。当要同时关联多个仓库时,这多个仓库之间可以用逗号隔开;当要关联所有的仓库时,可以使用“*”表示;当要关联除某一个仓库以外的其他所有仓库时,可以表示为“*,!repositoryId”;当要关联不是localhost或用file请求的仓库时,可以表示为“external:*”。-->
            <mirrorOf>repositoryId</mirrorOf>
            <!--镜像名称 -->
            <name>Human Readable Name for this Mirror.</name>
            <!--该镜像的URL。构建系统会优先考虑使用该URL,而非使用默认的服务器URL。 -->
            <url>http://196.160.1.211:8081/nexus/content/groups/public/</url>
        </mirror>
    </mirrors>

mirror相当于一个拦截器,它会拦截maven对remote repository的相关请求,把请求里的remote repository地址,重定向到mirror里配置的地址。

在这里插入图片描述

setting of sever

<!--表示当需要连接到一个私有服务器的时候需要的认证信息 。-->
    <servers>
        <!--服务器元素包含配置服务器时需要的信息
  发布的服务器,发布的位置在POM中配置,以ID为关联,有很多公用的信息需要配置在POM文件里,最佳实践是定义一个公司级别的root pom - 
	-->
        <server>
            <!--这是server的id(注意不是用户登陆的id),该id与distributionManagement中repository元素的id相匹配。-->
            <id>frame-releases</id>
            <!--鉴权用户名。鉴权用户名和鉴权密码表示服务器认证所需要的登录名和密码。 -->
            <username>admin</username>
            <password>admin123</password>
        </server>
        <server>
            <id>siteServer</id>
            <!--鉴权时使用的私钥位置。和前两个元素类似,私钥位置和私钥密码指定了一个私钥的路径(默认是${user.home}/.ssh/id_dsa)以及如果需要的话,一个密语。将来passphrase和password元素可能会被提取到外部,但目前它们必须在settings.xml文件以纯文本的形式声明。 -->
            <privateKey>/path/to/private/key</privateKey>
            <!--鉴权时使用的私钥密码。-->
            <passphrase>optional; leave empty if not used.</passphrase>
            <!--文件被创建时的权限。如果在部署的时候会创建一个仓库文件或者目录,这时候就可以使用权限(permission)。这两个元素合法的值是一个三位数字,其对应了unix文件系统的权限,如664,或者775-->
            <filePermissions>664</filePermissions>
            <!--目录被创建时的权限。 -->
            <directoryPermissions>775</directoryPermissions>
        </server>
    </servers>

your sever id & repository id

在这里插入图片描述

packaging

在这里插入图片描述

上传你的jar

如果是官方的jar,你要走ui面板
你自己的jar,在setting文件中配置好,再在你的pom中配置

<distributionManagement>
        <snapshotRepository>
            <!-- 这里的ID一定要在maven setting文件中存在于server下的ID -->
            <id>sona</id>
            <url>https://oss.sonatype.org/content/repositories/snapshots/</url>
        </snapshotRepository>
        <repository>
            <id>sona</id>
            <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
        </repository>
    </distributionManagement>

scope

在这里插入图片描述

【one】<dependencyManagement>

由于我们的模块很多,所以我们又抽象了一层,抽出一个itoo-base-parent来管理子项目的公共的依赖。为了项目的正确运行,必须让所有的子项目使用依赖项的统一版本,必须确保应用的各个项目的依赖项和版本一致,才能保证测试的和发布的是相同的结果。 在我们项目顶层的POM文件中,我们会看到dependencyManagement元素。通过它元素来管理jar包的版本,让子项目中引用一个依赖而不用显示的列出版本号。Maven会沿着父子层次向上走,直到找到一个拥有dependencyManagement元素的项目,然后它就会使用在这个dependencyManagement元素中指定的版本号。

  1. POM 的<dependencyManagement>元素包含可以被其他项目使用的<dependency>声明。
    这样的POM 的子项目将会自动继承这些声明。其他项目可以通过使用<scope>元素的import 值来导入它们

在这里插入图片描述

  1. 引用了<dependencyManagement>元素的项目可以使用它所声明的依赖,而不需要指定
    它们的<version>坐标。如果<dependencyManagement>中的<version>在稍后有所改变,
    则它将被所有引用它的POM 拾起。

【two】<pluginManagement>

如同<dependencyManagement>,<pluginManagement>声明了其他POM 可以使用的
信息,如下。

<build>
<pluginManagement>
<plugins>

<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
</plugin>
</plugins>
</pluginManagement>
</build >

子模块使用

<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
</plugin>
</plugins>
</build >

【three】构建 build

  1. validate——检查项目是否正确,所有必需的信息是否已经就绪。
  2. process-sources——处理源代码,如过滤任何值。
  3. compile——编译项目的源代码。
  4. process-test-resources——复制并处理资源到测试目标目录中。
  5. test-compile——将测试源代码编译到测试目标目录中。
  6. test——使用合适的单元测试框架测试编译的源代码。
  7. package——将编译的代码打包为它的可分发格式,如JAR。
  8. integration-test——处理并将软件包部署到一个可以运行集成测试的环境中。
  9. verify——运行任何的检查以验证软件包是否有效,并且符合质量标准。
  10. install——将软件包安装到本地存储库中,在那里其他本地构建项目可以将它引用
    为依赖。
  11. deploy——将最终的构件上传到远程存储库,以与其他开发人员和项目共享。
    执行这些阶段中的一个阶段将会调用所有前面的阶段
  12. 命令
    mvn clean install

【four】<profiles> 配置文件

配置文件(在<profiles>中定义)是一组自定义的POM 元素,可以通过自动或者手动启
用(激活)来改变POM 的行为
配置多环境的细节
click
mvn clean package -P dev

【five】SNAPSHOT

远程存储库通常会为正在开发的构件,以及那些稳定发布或者生产发布的构件,定义不同的
区域。这些区域被分别称为快照存储库和发布存储库。
一个<version>值由-SNAPSHOT 结尾的构件将被认为是还没有发布的。这种构件可以重复
地使用相同的<version>值被上传到存储库。每次它都会被分配一个唯一的时间戳。当项目检
索构件时,下载的是最新实例。
一个<version>值不具有-SNAPSHOT 后缀的构件将会被认为是一个发布版本。通常,存储
库策略只允某一特定的发布版本上传一次。

当构建一个具有SNAPSHOT 依赖的项目时,Maven 将检查本地存储库中是否有对应的副本。
如果没有,它将尝试从指定的远程存储库中检索,在这种情况下,它将接收到具有最新时间戳的
构件。如果本地的确有这个构件,并且当前构建也是这一天中的第一个,那么Maven 将默认尝
试更新该本地副本。这个行为可以通过使用Maven 配置文件(settings.xml)中的配置或者命令行
标志来进行配置。

【six】<dependencies>

内部包含若干<dependency>
groupId, artifactId,version 三个基本属性
type :默认jar类型
scope: 当前包依赖类型
optional: false时, 继承这个项目所有的子项目。 true时, 该项目的子项目需要显式引入
exclusion :排除某项

exclusion 要注意,一般用来解决冲突

Resources

参考:点击

这个元素描述了项目相关的所有资源 路径列表,例如和项目相关的 属性文件,这些资源被包含在最终的打包文件里。

directory

描述存放资源的目录,该路径相对POM路径

<includes/>

包含的文件列表

<excludes/>

排除的模式列表

<targetPath/>

描述了资源的目标路径。该路径相对target/classes目录(例如${project.build.outputDirectory})。举个例子,如果你想资源在特定的包里(org.apache.maven.messages),你就必须该元素设置为org/apache/maven/messages。然而,如果你只是想把资源放到源码目录结构里,就不需要该配置。

<filtering/>

是否使用参数值代替参数名。参数值取自properties元素或者文件里配置的属性,文件在filters元素里列出。

<build>
        <resources>
            <!--设置filter,font文件不需要filter,因为经过maven的filter,
            会破坏font文件的二进制文件格式,到时前台解析出错-->
            <resource>
                <directory>${project.basedir}/src/main/resources</directory>
                <filtering>true</filtering>
                <excludes>
                    <exclude>static/**</exclude>
                </excludes>
            </resource>
            <resource>
                <directory>${project.basedir}/src/main/resources</directory>
                <filtering>false</filtering>
                <includes>
                    <include>static/**</include>
                </includes>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <configuration>
                    <encoding>UTF-8</encoding>
                    <nonFilteredFileExtensions>
                        <nonFilteredFileExtension>xlsx</nonFilteredFileExtension>
                        <nonFilteredFileExtension>xls</nonFilteredFileExtension>
                    </nonFilteredFileExtensions>
                </configuration>
            </plugin>
        </plugins>
    </build>

dir

http://php-note.com/article/1724.html

b a s e d i r 项目的根目录 ( 包含 p o m . x m l 文件的目录 ) , {basedir}项目的根目录(包含pom.xml文件的目录), basedir项目的根目录(包含pom.xml文件的目录){version}项目版本
${project.basedir}和basedir等价

jar和war和pom的区别

pom:打出来可以作为其他项目的maven依赖,在工程A中添加工程B的pom,A就可以使用B中的类。用在父级工程或聚合工程中。用来做jar包的版本控制,也就是项目中所有要使用到的jar包的版本都集中由父工程管理。这样你在写其他工程pom文件中maven依赖时就不需要写版本号了 。当然所有的项目都要先继承它才行。这个只是作整个项目的版本控制,子工程还是需要自己在pom文件中引入依赖关系<dependency>
pom的作用

1 做聚合工程
2 用在父级工程,作为jar包的版本控制者,儿子项目需要继承pom项目。一般是做整个项目的版本控制

在这里插入图片描述

如果您觉得我的付出对您有帮助,还请关注+点赞哦,谢谢思密达

classifier

classifier 是 Maven 中一个非常重要但常被忽略的标签。让我详细解释它的意义和用法:

1. 基本概念

什么是 classifier?

classifier 是 Maven 坐标的第五个元素,用于区分同一个项目、同一版本下构建出的不同内容的构件。

完整 Maven 坐标:groupId:artifactId:version[:packaging][:classifier]

默认情况:

<!-- 没有 classifier -->
<dependency>
    <groupId>com.example</groupId>
    <artifactId>my-project</artifactId>
    <version>1.0.0</version>
    <!-- 默认:没有 classifier -->
</dependency>
<!-- 对应文件:my-project-1.0.0.jar -->

2. 常见使用场景

场景1:不同 JDK 版本

<!-- 为不同JDK版本提供不同的jar -->
<dependency>
    <groupId>com.example</groupId>
    <artifactId>my-project</artifactId>
    <version>1.0.0</version>
    <classifier>jdk8</classifier>
</dependency>
<!-- 文件:my-project-1.0.0-jdk8.jar -->

<dependency>
    <groupId>com.example</groupId>
    <artifactId>my-project</artifactId>
    <version>1.0.0</version>
    <classifier>jdk11</classifier>
</dependency>
<!-- 文件:my-project-1.0.0-jdk11.jar -->

场景2:源码和文档

<!-- 源码包 -->
<dependency>
    <groupId>com.example</groupId>
    <artifactId>my-project</artifactId>
    <version>1.0.0</version>
    <classifier>sources</classifier>
</dependency>
<!-- 文件:my-project-1.0.0-sources.jar -->

<!-- Javadoc包 -->
<dependency>
    <groupId>com.example</groupId>
    <artifactId>my-project</artifactId>
    <version>1.0.0</version>
    <classifier>javadoc</classifier>
</dependency>
<!-- 文件:my-project-1.0.0-javadoc.jar -->

场景3:不同平台/环境

<!-- Linux平台 -->
<dependency>
    <groupId>com.example</groupId>
    <artifactId>native-lib</artifactId>
    <version>1.0.0</version>
    <classifier>linux-x86_64</classifier>
</dependency>

<!-- Windows平台 -->
<dependency>
    <groupId>com.example</groupId>
    <artifactId>native-lib</artifactId>
    <version>1.0.0</version>
    <classifier>windows-x86_64</classifier>
</dependency>

<!-- macOS平台 -->
<dependency>
    <groupId>com.example</groupId>
    <artifactId>native-lib</artifactId>
    <version>1.0.0</version>
    <classifier>darwin-x86_64</classifier>
</dependency>

3. 实际项目示例

Netty 中的 classifier

<!-- Netty 对不同操作系统提供不同native传输实现 -->
<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-transport-native-epoll</artifactId>
    <version>4.1.100.Final</version>
    <classifier>linux-x86_64</classifier>
</dependency>

<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-transport-native-kqueue</artifactId>
    <version>4.1.100.Final</version>
    <classifier>osx-x86_64</classifier>
</dependency>

Spring Boot 的可执行jar

<!-- 可执行jar -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>2.7.0</version>
</dependency>
<!-- 生成的可执行jar:app-1.0.0.jar -->

<!-- 普通jar(用于依赖) -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>2.7.0</version>
    <classifier>plain</classifier>
</dependency>
<!-- 文件:app-1.0.0-plain.jar -->

4. 如何构建带 classifier 的构件

Maven 插件配置示例

<build>
    <plugins>
        <!-- 构建主jar -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>default-jar</id>
                    <phase>package</phase>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                    <configuration>
                        <!-- 主jar没有classifier -->
                    </configuration>
                </execution>
                
                <!-- 构建带classifier的jar -->
                <execution>
                    <id>build-with-classifier</id>
                    <phase>package</phase>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                    <configuration>
                        <classifier>lite</classifier>
                        <!-- 排除一些文件 -->
                        <excludes>
                            <exclude>**/test/**</exclude>
                            <exclude>**/heavy-module/**</exclude>
                        </excludes>
                    </configuration>
                </execution>
                
                <!-- 构建源码jar -->
                <execution>
                    <id>sources-jar</id>
                    <phase>package</phase>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                    <configuration>
                        <classifier>sources</classifier>
                        <includes>
                            <include>**/*.java</include>
                            <include>**/*.properties</include>
                        </includes>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        
        <!-- 构建不同平台的native包 -->
        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <executions>
                <execution>
                    <id>linux-assembly</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                    <configuration>
                        <classifier>linux-x86_64</classifier>
                        <descriptors>
                            <descriptor>src/assembly/linux.xml</descriptor>
                        </descriptors>
                    </configuration>
                </execution>
                <execution>
                    <id>windows-assembly</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                    <configuration>
                        <classifier>windows-x86_64</classifier>
                        <descriptors>
                            <descriptor>src/assembly/windows.xml</descriptor>
                        </descriptors>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

5. 依赖管理中的 classifier

使用 properties 动态选择

<properties>
    <!-- 根据平台动态设置classifier -->
    <os.detected.classifier>${os.detected.classifier}</os.detected.classifier>
</properties>

<dependencies>
    <dependency>
        <groupId>com.example</groupId>
        <artifactId>native-lib</artifactId>
        <version>1.0.0</version>
        <classifier>${os.detected.classifier}</classifier>
    </dependency>
</dependencies>

<build>
    <plugins>
        <!-- os-maven-plugin 用于检测操作系统 -->
        <plugin>
            <groupId>kr.motd.maven</groupId>
            <artifactId>os-maven-plugin</artifactId>
            <version>1.7.1</version>
            <executions>
                <execution>
                    <phase>initialize</phase>
                    <goals>
                        <goal>detect</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

6. classifier 与 type 的区别

维度classifiertype (packaging)
目的区分同一类型的多个构件指定构件的包装类型
示例jdk8, sources, javadocjar, war, pom, zip
文件扩展名不影响扩展名决定扩展名
数量可以有多个每个artifact一个
依赖解析可选必需
<!-- type指定包装格式 -->
<dependency>
    <groupId>com.example</groupId>
    <artifactId>web-app</artifactId>
    <version>1.0.0</version>
    <type>war</type>  <!-- 文件:web-app-1.0.0.war -->
</dependency>

<!-- type + classifier -->
<dependency>
    <groupId>com.example</groupId>
    <artifactId>web-app</artifactId>
    <version>1.0.0</version>
    <type>war</type>
    <classifier>sources</classifier>  <!-- 文件:web-app-1.0.0-sources.war -->
</dependency>

7. 实战案例:发布多版本构件

项目配置

<!-- pom.xml -->
<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>my-library</artifactId>
    <version>2.0.0</version>
    
    <build>
        <plugins>
            <!-- 主jar -->
            <plugin>
                <artifactId>maven-jar-plugin</artifactId>
                <executions>
                    <execution>
                        <id>default-jar</id>
                        <goals><goal>jar</goal></goals>
                    </execution>
                    <!-- 精简版 -->
                    <execution>
                        <id>lite-jar</id>
                        <goals><goal>jar</goal></goals>
                        <configuration>
                            <classifier>lite</classifier>
                            <excludes>
                                <exclude>**/optional/**</exclude>
                            </excludes>
                        </configuration>
                    </execution>
                    <!-- 完整版 -->
                    <execution>
                        <id>full-jar</id>
                        <goals><goal>jar</goal></goals>
                        <configuration>
                            <classifier>full</classifier>
                            <includes>
                                <include>**/*</include>
                            </includes>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            
            <!-- 部署所有构件 -->
            <plugin>
                <artifactId>maven-deploy-plugin</artifactId>
                <configuration>
                    <skip>false</skip>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

部署到仓库

# 执行部署,会生成:
# my-library-2.0.0.jar          (主构件)
# my-library-2.0.0-lite.jar     (精简版)
# my-library-2.0.0-full.jar     (完整版)
mvn clean deploy

8. 注意事项和最佳实践

注意事项:

  1. classifier 不是版本号:它不能替代版本管理
  2. 主构件唯一性:每个版本必须有且只有一个没有 classifier 的主构件
  3. 依赖解析:Maven 会优先选择没有 classifier 的构件,除非显式指定

最佳实践:

  1. 语义化 classifier:使用有意义的名称,如 jdk8androidsources
  2. 平台检测:使用 os-maven-plugin 自动选择平台特定的构件
  3. 文档化:在 README 中说明各个 classifier 的区别
  4. 避免过度使用:只在真正需要时使用 classifier

9. 常见问题解答

Q:classifier 会影响依赖传递吗?

A:。如果依赖 A 依赖于带 classifier 的 B,那么依赖传递时也会包含该 classifier。

Q:如何查看一个构件的所有 classifier?

A:在 Maven 仓库中查看:

http://repo.maven.apache.org/maven2/com/example/my-project/1.0.0/
# 列出:
# my-project-1.0.0.jar
# my-project-1.0.0-sources.jar
# my-project-1.0.0-javadoc.jar
# my-project-1.0.0-tests.jar

Q:classifier 能否包含点号(.)?

A:可以,但不推荐。最好使用连字符(-)。

Q:安装到本地仓库时的文件名?

A:使用 classifier 的构件安装时,文件名会包含 classifier:

# 安装命令
mvn install:install-file \
  -Dfile=my-app-1.0.0-linux.jar \
  -DgroupId=com.example \
  -DartifactId=my-app \
  -Dversion=1.0.0 \
  -Dclassifier=linux \
  -Dpackaging=jar

# 本地仓库路径:
~/.m2/repository/com/example/my-app/1.0.0/
  my-app-1.0.0-linux.jar
  my-app-1.0.0-linux.pom

总结

classifier 是一个非常强大的功能,主要用于:

  1. 发布同一项目的多个变体
  2. 处理跨平台兼容性
  3. 提供源码和文档
  4. 创建不同配置的构件

合理使用 classifier 可以减少项目数量,更优雅地管理多版本、多平台的支持。

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值