转自:https://fanlychiex.github.io/

1. Maven生命周期

Maven的生命周期是对项目所有的构建过程进行抽象和统一。它包含了项目的清理、初始化、编译、测试、打包、部署和站点生成等构建步骤。Maven的生命周期本质是定义项目构建的各个步骤,它本身是抽象的,并不作任何的具体工作,而是将构建过程中的各个步骤任务交个相对应的插件来完成。这使得Maven的生命周期具有良好的扩展性,开发者可以自己编写插件实现代码绑定到构建的某个步骤。当然,在绝大部分场景下,开发者不必这样来做,因为Maven初始为项目构建的各个步骤绑定了默认的插件。

生命周期

Maven有三个相互独立的生命周期。它们分别是Clean Lifecycle Default Lifecycle Site Lifecycle

生命周期 描述
Clean 用于清理项目
Default 用于构建项目
Site 用于生成项目站点

每个独立的生命周期都包含一些阶段(phase),这些阶段是一个有序的组合,后面的阶段依赖于前面的阶段,并且顺序执行各个阶段。

Clean生命周期

阶段 描述
pre-clean 在实际项目清理之前执行所需的过程
clean 删除上一个版本生成的所有文件
post-clean 执行完成项目清理所需的过程

Default生命周期

阶段 描述
validate 验证项目所有必要的信息都是可用的
initialize 初始化构建状态,例如设置属性或创建目录
generate-sources 生成包含在编译中的源代码
process-sources 处理源代码,过滤和替换一些变量的值
generate-resources 生成包含在包中的资源
process-resources 处理资源包,将其复制到目标目录
compile 编译项目的源代码
process-classes 从编译中对生成的文件进行后处理,例如对Java类进行字节码增强
generate-test-sources 生成包含在编译中的测试源代码
process-test-sources 处理源代码,过滤和替换一些变量的值
generate-test-resources 生成包含在测试包中的资源
process-test-resources 处理资源包,将其复制到测试目标目录
test-compile 编译项目的测试源代码
process-test-classes 从编译中对生成的测试文件进行后处理,例如对Java类进行字节码增强
test 执行单元测试,测试代码不会被打包部署
prepare-package 打包之前执行所需的任何操作
package 打包项目
pre-integration-test 集成测试前执行的操作,如设置环境等
integration-test 执行集成测试,如果需要,可将软件包部署到可以运行集成测试的环境
post-integration-test 集成测试后执行的操作,如清理环境
verify 检查软件包是否符合标准
install 将项目输出构件安装到本地仓库
deploy 将项目输出构件部署到远程仓库

Site生命周期

阶段 描述
pre-site 在实际项目站点生成之前执行所需的过程
site 生成项目的站点文档
post-site 执行完成站点生成所需的进程,并准备站点部署
site-deploy 将生成的站点文档部署到指定的Web服务器

命令行命令与生命周期

$ mvn clean package

该命令会调用执行Clean生命周期的clean和clean之前的所有阶段,以及会调用Default生命周期的package和package之前的所有阶段。


2. Maven Super POM

所有maven模块(项目)的POM(Project Object Model,项目对象模型)都隐式的继承了Super POM。Super POM中定义了一组标准的配置变量。maven模块(项目)的POM会自动继承这些配置变量,你可以在maven模块(项目)的POM文件中直接使用它们,或者通过重新声明以覆盖它们。

倘若Maven安装的目录用{MAVEN_HOME}来表示,那么,Maven Super POM文件所在的路径为:{MAVEN_HOME}/lib/maven-model-builder-3.5.4.jar/org/apache/maven/model/pom-4.0.0.xml

<?xml version="1.0" encoding="UTF-8"?>

<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
-->

<!-- START SNIPPET: superpom -->
<project>
  <modelVersion>4.0.0</modelVersion>

  <repositories>
    <repository>
      <id>central</id>
      <name>Central Repository</name>
      <url>https://repo.maven.apache.org/maven2</url>
      <layout>default</layout>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
    </repository>
  </repositories>

  <pluginRepositories>
    <pluginRepository>
      <id>central</id>
      <name>Central Repository</name>
      <url>https://repo.maven.apache.org/maven2</url>
      <layout>default</layout>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
      <releases>
        <updatePolicy>never</updatePolicy>
      </releases>
    </pluginRepository>
  </pluginRepositories>

  <build>
    <directory>${project.basedir}/target</directory>
    <outputDirectory>${project.build.directory}/classes</outputDirectory>
    <finalName>${project.artifactId}-${project.version}</finalName>
    <testOutputDirectory>${project.build.directory}/test-classes</testOutputDirectory>
    <sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
    <scriptSourceDirectory>${project.basedir}/src/main/scripts</scriptSourceDirectory>
    <testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory>
    <resources>
      <resource>
        <directory>${project.basedir}/src/main/resources</directory>
      </resource>
    </resources>
    <testResources>
      <testResource>
        <directory>${project.basedir}/src/test/resources</directory>
      </testResource>
    </testResources>
    <pluginManagement>
      <!-- NOTE: These plugins will be removed from future versions of the super POM -->
      <!-- They are kept for the moment as they are very unlikely to conflict with lifecycle mappings (MNG-4453) -->
      <plugins>
        <plugin>
          <artifactId>maven-antrun-plugin</artifactId>
          <version>1.3</version>
        </plugin>
        <plugin>
          <artifactId>maven-assembly-plugin</artifactId>
          <version>2.2-beta-5</version>
        </plugin>
        <plugin>
          <artifactId>maven-dependency-plugin</artifactId>
          <version>2.8</version>
        </plugin>
        <plugin>
          <artifactId>maven-release-plugin</artifactId>
          <version>2.5.3</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>

  <reporting>
    <outputDirectory>${project.build.directory}/site</outputDirectory>
  </reporting>

  <profiles>
    <!-- NOTE: The release profile will be removed from future versions of the super POM -->
    <profile>
      <id>release-profile</id>

      <activation>
        <property>
          <name>performRelease</name>
          <value>true</value>
        </property>
      </activation>

      <build>
        <plugins>
          <plugin>
            <inherited>true</inherited>
            <artifactId>maven-source-plugin</artifactId>
            <executions>
              <execution>
                <id>attach-sources</id>
                <goals>
                  <goal>jar-no-fork</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
          <plugin>
            <inherited>true</inherited>
            <artifactId>maven-javadoc-plugin</artifactId>
            <executions>
              <execution>
                <id>attach-javadocs</id>
                <goals>
                  <goal>jar</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
          <plugin>
            <inherited>true</inherited>
            <artifactId>maven-deploy-plugin</artifactId>
            <configuration>
              <updateReleaseInfo>true</updateReleaseInfo>
            </configuration>
          </plugin>
        </plugins>
      </build>
    </profile>
  </profiles>

</project>
<!-- END SNIPPET: superpom -->

Super POM 的作用

  1. 定义了一个ID为central的远程仓库(url即为这个仓库的地址),如果没有其它特殊的声明,maven模块(项目)所需要的构件(jar包等)都会到这个远程中央仓库中去下载;

  2. 定义了一个插件仓库,这个插件仓库和上面定义的远程仓库用的是同一个仓库,maven模块(项目)所需要的插件包都会到这个远程中央仓库中去下载;

  3. 定义了一组标准的配置变量,在maven模块(项目)的POM中可以通过${project.build.XX}来使用它们,如 ${project.build.directory};

    <directory>${project.basedir}/target</directory>
    <outputDirectory>${project.build.directory}/classes</outputDirectory>
    <finalName>${project.artifactId}-${project.version}</finalName>
    <testOutputDirectory>${project.build.directory}/test-classes</testOutputDirectory>
    <sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
    <scriptSourceDirectory>${project.basedir}/src/main/scripts</scriptSourceDirectory>
    <testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory>
    

3. Maven发布构件到私服

Nexus3搭建的Maven私服为例子,用管理员账户登录系统,并在管理控制台的配置面板中创建一个用于发布项目构件(在maven中,所有的依赖、插件、项目构建的输出,都可以称作是构件)的账户。

创建角色

在Nexus3管理控制台中,创建一个具有nx-component-uploadnx-repository-view-*-*-*两个权限的角色:

Maven结合Nexus私服用法

创建用户

在Nexus3管理控制台中,创建一个用作构件部署的账户,并将刚刚创建的角色分配给该用户:

Maven结合Nexus私服用法

settings.xml配置

找到maven的用户或全局settings.xml配置文件,添加如下代码:

<servers>
    <server>
        <id>nexus-maven-snapshot</id>
        <username>deployment</username>
        <password>deployment123</password>
    </server>
    <server>
        <id>nexus-maven-releases</id>
        <username>deployment</username>
        <password>deployment123</password>
    </server>
</servers>

<server>用于配置连接到远程服务器的账户和密码信息。主要用于发布项目构件上传到maven私服的时进行权限认证。

pom.xml配置

在项目的pom.xml配置文件中,如果是快照(项目pom.xml文件中version的值含有*-SNAPSHOT)则添加如下代码:

<distributionManagement>
    <snapshotRepository>
        <id>nexus-maven-snapshots</id>
        <url>http://10.10.10.121:8081/repository/maven-snapshots/</url>
    </snapshotRepository>
</distributionManagement>

如果不是快照(项目pom.xml文件中version的值不含SNAPSHOT)则添加如下代码:

<distributionManagement>
    <repository>
        <id>nexus-maven-releases</id>
        <url>http://10.10.10.121:8081/repository/maven-releases/</url>
    </repository>
</distributionManagement>

<distributionManagement>用于指定当前项目发布到maven私服时上传到哪个仓库中存储。如果是快照文件则使用<snapshotRepository>元素,否则使用<repository>元素。
<id>这里的值必须要与settings.xml配置文件中<server>中的<id>的值匹配,否则在发布构件到maven私服的时候,就会因连接到远程服务器的身份验证失败导致发布构件失败(maven构建的时候报401错误)。
<url>用于指定当前项目发布到maven私服时上传存储到的那个仓库的地址。

部署构件

在命令行中执行命令:

$ mvn clean deploy

如果部署的构件是一个快照版本,由于存储快照版本的仓库是允许构件重新部署的,因此快照版本的构件在每次发布时都会自动带上一个时间戳标记,以作为区分和历史备份。如图所示:

Maven结合Nexus私服用法


4. Maven仓库

Maven仓库分为两种,一种是本地仓库,一种是远程仓库。
本地仓库是maven用来在本地机器上存储从远程仓库下载回来的构件的位置。
远程仓库包含了绝大多数流行的开源的java构件,项目依赖的构件一般都可以在这里下载。不同的远程仓库可能包含不同的java构件。

本地仓库和远程仓库的关系

远程仓库又分为:中央仓库(https://repo.maven.apache.org/maven2)、私服(如Nexus OSS)、其他第三方公共库(如阿里的http://maven.aliyun.com/nexus/content/groups/public)。

Maven结合Nexus私服用法

大部分构件最初都是Maven从远程仓库下载回来存储到本地仓库的(也有一小部分是通过安装命令直接安装到本地仓库的),一旦Maven从远程仓库下载一个构件回来存储到本地仓库,只要你不手工删除该构件,它将永远不需要再下载一次。因为Maven每次查找依赖的构件时都会首先在本地仓库中去查找,然后才是去远程仓库中查找。一旦Maven在本地仓库查找到了依赖所需的构件,就不会再去远程仓库中去查看下载了。

Maven本地仓库配置

找到maven的用户或全局的settings.xml配置文件,如下:

<settings>
    
    <localRepository>D:/application/repo/maven</localRepository>
    
</settings>

<localRepository>用于指定本地仓库的位置。所有从远程仓库下载回来的构件都存储在这个目录中。

Maven远程仓库配置

  1. 找到maven的用户或全局的settings.xml配置文件,在<profiles>标签中添加如下代码:
<profiles>
    <profile>
        ... ...
        <repositories>
            <repository>
                <id>nexus-maven-snapshots</id>
                <url>http://10.10.10.121:8081/repository/maven-snapshots/</url>
                <releases>
                    <enabled>true</enabled>
                </releases>
                <snapshots>
                    <enabled>true</enabled>
                </snapshots>
            </repository>
        </repositories>
        <pluginRepositories>
            <pluginRepository>
                <id>nexus-maven-snapshots</id>
                <url>http://10.10.10.121:8081/repository/maven-snapshots/</url>
                <releases>
                    <enabled>true</enabled>
                </releases>
                <snapshots>
                    <enabled>true</enabled>
                </snapshots>
            </pluginRepository>
        </pluginRepositories>
        ... ...
    </profile>
</profiles>

<repository>用于配置一个远程的可供下载的构件仓库。<pluginRepository>则用于配置一个远程的可供下载的插件仓库。<id>必须是唯一的。<url>是这个仓库的地址。

  1. 在项目的pom.xml配置文件中,添加如下代码:
<repositories>
    <repository>
        <id>fanlychie-maven-repo</id>
        <url>https://raw.github.com/fanlychie/maven-repo/releases</url>
    </repository>
</repositories>

其效果可等效于在maven的用户或全局的settings.xml文件中配置的效果。

Maven仓库检索顺序

找到maven的用户或全局的settings.xml配置文件,在<profiles>标签中添加如下代码:

<profiles>
    <profile>
        <id>jdk7-development</id>
        <activation>
            <jdk>1.7</jdk>
            <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
            <maven.compiler.source>1.7</maven.compiler.source>
            <maven.compiler.target>1.7</maven.compiler.target>
            <maven.compiler.compilerVersion>1.7</maven.compiler.compilerVersion>
        </properties>
        <repositories>
            <repository>
                <id>nexus-maven-snapshots</id>
                <url>http://10.10.10.121:8081/repository/maven-snapshots/</url>
                <releases>
                    <enabled>true</enabled>
                </releases>
                <snapshots>
                    <enabled>true</enabled>
                </snapshots>
            </repository>
            <repository>
                <id>nexus-maven-releases</id>
                <url>http://10.10.10.121:8081/repository/maven-releases/</url>
                <releases>
                    <enabled>true</enabled>
                </releases>
                <snapshots>
                    <enabled>false</enabled>
                </snapshots>
            </repository>
            <repository>
                <id>nexus-maven-3rd.party</id>
                <url>http://10.10.10.121:8081/repository/3rd.party/</url>
                <releases>
                    <enabled>true</enabled>
                </releases>
                <snapshots>
                    <enabled>false</enabled>
                </snapshots>
            </repository>
        </repositories>
        <pluginRepositories>
            <pluginRepository>
                <id>nexus-maven-snapshots</id>
                <url>http://10.10.10.121:8081/repository/maven-snapshots/</url>
                <releases>
                    <enabled>true</enabled>
                </releases>
                <snapshots>
                    <enabled>true</enabled>
                </snapshots>
            </pluginRepository>
            <pluginRepository>
                <id>nexus-maven-releases</id>
                <url>http://10.10.10.121:8081/repository/maven-releases/</url>
                <releases>
                    <enabled>true</enabled>
                </releases>
                <snapshots>
                    <enabled>false</enabled>
                </snapshots>
            </pluginRepository>
            <pluginRepository>
                <id>nexus-maven-3rd.party</id>
                <url>http://10.10.10.121:8081/repository/3rd.party/</url>
                <releases>
                    <enabled>true</enabled>
                </releases>
                <snapshots>
                    <enabled>false</enabled>
                </snapshots>
            </pluginRepository>
        </pluginRepositories>
    </profile>
</profiles>

然后在项目的pom.xml配置文件中,添加如下代码:

<repositories>
    <repository>
        <id>fanlychie-maven-repo</id>
        <url>https://raw.github.com/fanlychie/maven-repo/releases</url>
    </repository>
</repositories>

<dependencies>
    <!-- 该构件托管在fanlychie-maven-repo仓库中 -->
    <dependency>
        <groupId>org.fanlychie</groupId>
        <artifactId>jexcel</artifactId>
        <version>2.2.2</version>
    </dependency>
</dependencies>

然后在命令行中执行命令:

$ mvn compile

Maven结合Nexus私服用法

可以看到,maven在下载依赖所需的构件时检索仓库的顺序依次为(仓库ID):nexus-maven-snapshots → nexus-maven-releases → nexus-maven-3rd.party → fanlychie-maven-repo → central
其本质的检索顺序是:本地仓库 → maven用户或全局配置文件settings.xml中的仓库 → 项目pom.xml文件中配置的仓库 → maven超POM中的仓库。
maven在下载依赖所需的构件时,只要一个构件在其中的任意一个仓库中查找到,就不会再继续检索其他的仓库。

Maven结合Nexus私服用法

这是第二次构建项目时输出的信息,可以看到,在第一次构建成功后,再次构建项目的时候就不会再去远程仓库下载构件了。


5. Maven镜像

如果一个仓库X可以提供仓库Y存储的所有构件,那么就可以称仓库X是仓库Y的一个镜像。由于地理位置等原因,国内网络连接Maven官方的中央仓库网速一般较慢或时常出现网络不稳定的状态,从而导致项目在构建所需的时间较长或失败。使用镜像的好处就是,它往往能提供比中央仓库更快的服务(通常选择地理位置上与自己较近且口碑较好的镜像), 从而提高下载速度, 最终达到提高项目构建效率的目的。

首先我们先找到maven的用户或全局的settings.xml配置文件,在<mirrors>标签中添加如下代码:

<mirrors>
    <mirror>
        <id>aliyun-maven-repo</id>
        <!-- 阿里云公共镜像 -->
        <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
        <!-- 匹配Maven中央仓库, 该ID在超POM中定义的 -->
        <mirrorOf>central</mirrorOf>
    </mirror>
</mirrors>

<mirror>用于配置一个镜像。<id>必须是唯一的。<url>是镜像的地址。<mirrorOf>用于匹配Maven仓库(<repository>)的ID。常见的匹配规则有:

通配符 描述
* 匹配所有的Maven仓库ID
repo1,repo2 只匹配ID为repo1或repo2的仓库
external:* 匹配除本地仓库之外的所有仓库
*,!repo1 匹配除ID为repo1之外的所有仓库

每当Maven需要去远程仓库下载一个构件时,如果这个仓库被该镜像匹配到,则去这个仓库下载构件的请求就会被该镜像拦截掉,并将此次请求转发到该镜像配置的地址中去下载。

Maven结合Nexus私服用法

相关文章:

  • 2021-11-26
  • 2021-07-24
  • 2022-12-23
  • 2021-12-12
  • 2021-07-23
  • 2022-03-09
  • 2021-11-26
猜你喜欢
  • 2022-01-15
  • 2021-10-27
  • 2022-01-01
  • 2021-12-28
  • 2021-12-13
  • 2021-12-05
  • 2021-04-16
相关资源
相似解决方案