Maven生命周期,依赖范围

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: Maven生命周期,依赖范围

maven生命周期

构建生命周期是由阶段组成的:

这些构建生命周期中的每一个由构建阶段的不同列表定义,其中构建阶段表示生命周期中的阶段。


例如,默认(default)的生命周期包括以下阶段(注意:这里是简化的阶段,用于生命周期阶段的完整列表,请参阅下方生命周期参考):


验证(validate) - 验证项目是否正确,所有必要的信息可用

编译(compile) - 编译项目的源代码

测试(test) - 使用合适的单元测试框架测试编译的源代码。这些测试不应该要求代码被打包或部署

打包(package) - 采用编译的代码,并以其可分配格式(如JAR)进行打包。

验证(verify) - 对集成测试的结果执行任何检查,以确保满足质量标准

安装(install) - 将软件包安装到本地存储库中,用作本地其他项目的依赖项

部署(deploy) - 在构建环境中完成,将最终的包复制到远程存储库以与其他开发人员和项目共享。

这些生命周期阶段(以及此处未显示的其他生命周期阶段)依次执行,以完成默认生命周期。给定上述生命周期阶段,这意味着当使用默认生命周期时,Maven将首先验证项目,然后尝试编译源代码,运行这些源代码,打包二进制文件(例如jar),运行集成测试软件包,验证集成测试,将验证的软件包安装到本地存储库,然后将安装的软件包部署到远程存储库。


换句话说,在生命周期里面阶段是连续的,在不出错的前提下,比如执行打包(package)时就一定是执行了测试(test)之后再执行。

maven依赖范围

有哪些依赖范围

Scope: 依赖范围(compile,test,provided,runtime,system 五种状态)

  • 编译依赖范围(compile),该范围就是默认依赖范围,此依赖范围对 于编译、测试、运行三种classpath都有效,举个简单的例子,假如项目中有spring-core的依赖,那么spring-core不管是在编译,测试,还是运行都会被用到,因此spring-core必须是编译范围(构件默认的是编译范围,所以依赖范围是编译范围的无须显示指定)
     <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>2.5</version>
      <scope>compile</scope> <!--默认为该依赖范围,无须显示指定-->
    </dependency>

测试依赖范围(test),顾名思义就是针对于测试的,使用此依赖范围的依赖,只对测试classpath有效,在编译主代码和项目运行时,都将无法使用该依赖,最典型的例子就是 Junit, 构件在测试时才需要,所以它的依赖范围是测试,因此它的依赖范围需要显示指定为test ,当然不显示指定依赖范围也不会报错,但是该依赖会被加入到编译和运行的classpath中,造成不必要的浪费 。

 <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.7</version>
     <scope>test</scope>
    </dependency>

已提供依赖范围(provided),使用该依赖范围的maven依赖,只对编译和测试的classpath有效,对运行的classpath无效,典型的例子就是servlet-api, 编译和测试该项目的时候需要该依赖,但是在运行时,web容器已经提供的该依赖,所以运行时就不再需要此依赖,如果不显示指定该依赖范围,并且容器依赖的版本和maven依赖的版本不一致的话,可能会引起版本冲突,造成不良影响。

 <dependency>
      <groupId>javax-servlet</groupId>
      <artifactId>servlet-api</artifactId>
      <version>2.0</version>
     <scope>provided</scope>
    </dependency>

运行时依赖范围(runtime),使用该依赖范围的maven依赖,只对测试和运行的classpath有效,对编译的classpath无效,典型例子就是JDBC的驱动实现,项目主代码编译的时候只需要JDK提供的JDBC接口,只有在测试和运行的时候才需要实现上述接口的具体JDBC驱动。


系统依赖范围(system),该依赖与classpath的关系与 provided依赖范围完全一致,但是系统依赖范围必须通过配置systemPath元素来显示指定依赖文件的路径,此类依赖不是由maven仓库解析的,而且往往与本机系统绑定,可能造成构件的不可移植,因此谨慎使用,systemPath元素可以引用环境变量:

        <dependency>
            <groupId>javax.sql</groupId>
            <artifactId>jdbc-stext</artifactId>
            <version>2.0</version>
            <scope>system</scope>
            <systemPath>${java.home}/lib/rt.jar</systemPath>
        </dependency>

依赖传递

maven引入的传递性依赖机制,一方面大大简化和方便了依赖声明,另一方面,大部分情况下我们只需要关心项目的直接依赖是什么,而不用考虑这些直接依赖会引入什么传递性依赖。但有时候,当传递性依赖造成问题的时候,我们就需要清楚地知道该传递性依赖是从哪条依赖路径引入的。


maven对于依赖相同的资源,默认会做出以下优化:

第一原则:以短路径长度为准

例如,项目A有这样的依赖关系 : A–>B–>C–>X(1.0)、A–>D–>X(2.0),X是A的传递性依赖,但是两条依赖路径上有两个版 本的X,那么哪个X会被maven解析使用呢?两个版本都被解析显然是不对的,因为那会造成依赖重复,因此必须选择一个。maven依赖调解的第一原则:路径最近者优先。该例中X(1.0)的路径长度为3,而X(2.0)的路径长度为2,因此X(2.0)会被解析使用。

第二原则:相同路径长度时,以pom中声明顺序为准

依赖调解第一原则不能解决所有问题,比如这样的依赖关系:A–>B–>Y(1.0),A–>C–>Y(2.0),Y(1.0)和Y(2.0)的依赖路径长度是一样的,都为2。那么到底谁会被解析使用呢?在maven2.0.8及之前的版本中,这是不确定的,但是maven2.0.9开始,为了尽可能避免构建的不确定性,maven定义了依赖调解的第二原则:第一声明者优先。在依赖路径长度相等的前提下,在POM中依赖声明的顺序决定了谁会被解析使用。顺序最靠前的那个依赖优胜。


maven中去除依赖

maven pom中配置 exclusion标签 手动去除依赖

    <dependency>
      <groupId>sample.ProjectA</groupId>
      <artifactId>Project-A</artifactId>
      <version>1.0</version>
      <scope>compile</scope>
      <exclusions>
        <exclusion>  <!-- declare the exclusion here -->
          <groupId>sample.ProjectB</groupId>
          <artifactId>Project-B</artifactId>
        </exclusion>
      </exclusions>
    </dependency>

dependencyManagement与dependencies区别

dependencies即使在子项目中不写该依赖项,那么子项目仍然会从父项目中继承该依赖项(全部继承)

dependencyManagement里只是声明依赖,并不实现引入,因此子项目需要显示的声明需要用的依赖。如果不在子项目中声明依赖,是不会从父项目中继承下来的;只有在子项目中写了该依赖项,并且没有指定具体版本,才会从父项目中继承该项,并且version和scope都读取自父pom;另外如果子项目中指定了版本号,那么会使用子项目中指定的jar版本。

maven插件配置说明

maven-compiler-plugin

maven是个项目管理工具,如果我们不告诉它我们的代码要使用什么样的jdk版本编译的话,它就会用maven-compiler-plugin默认的jdk版本来进行处理,这样就容易出现版本不匹配,以至于可能导致编译不通过的问题。

        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.1</version>
          <configuration>
            <source>1.8</source>
            <target>1.8</target>
          </configuration>
        </plugin>

spring-boot-maven-plugin

在添加了该插件之后,当运行“mvn package”进行打包时,会打包成一个可以直接运行的 JAR 文件,使用“Java -jar”命令就可以直接运行。这在很大程度上简化了应用的部署,只需要安装了 JRE 就可以运行。

可以在POM中,指定生成 的是Jar还是War。

        <plugin>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-maven-plugin</artifactId>
          <version>2.0.3.RELEASE</version>
          <configuration>
            <!--debug 能够断点-->
            <jvmArguments>
              -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005
            </jvmArguments>
          </configuration>
        </plugin>

maven-resources-plugin

该插件的作用 主要是处理将 主程序与 测试程序所需的源文件复制到输出编译文件夹中。

构建Maven项目的时候,如果没有进行特殊的配置,Maven会按照标准的目录结构查找和处理各种类型文件。


1)src/main/java和src/test/java目录下的所有*.java文件分别在comile和test-comiple阶段被编译,编译结果分别放到了target/classes和targe/test-classes目录中,但是这两个目录中的其他文件都会被忽略掉。


2)src/main/resouces和src/test/resources这两个目录中的文件也会分别被复制到target/classes和target/test-classes目录中。


但是会出现如下情况


1)放在src/main/java下的xml文件,比如mybatis中的mapper.xml,是不会被默认加载的。


2)想要排除默认加载的某些文件,比如我不想加载init.json文件


这个时候就要用到标签和maven-resources-plugin插件了,用法如下:


resource的filtering属性用来表示资源文件中的占位符是否需要被替换,true为需要替换。

false为不需要替换。

    <resources>
      <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
      </resource>
      <resource>
        <directory>src/main/java</directory>
        <includes>
          <include>**/*.xml</include>
        </includes>
      </resource>
    </resources>

maven打包项目的时候pom.xml配置文件里可以配置对项目进行统一编码,但是部分文件 可能不需要进行重新编码,例如: 证书文件;重新编码后可能导致证书不可用。

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <configuration>
                    <nonFilteredFileExtensions>
                        <nonFilteredFileExtension>xlsx</nonFilteredFileExtension>
                        <nonFilteredFileExtension>xls</nonFilteredFileExtension>
                        <nonFilteredFileExtension>zip</nonFilteredFileExtension>
                        <nonFilteredFileExtension>cer</nonFilteredFileExtension>
                        <nonFilteredFileExtension>pfx</nonFilteredFileExtension>
                        <nonFilteredFileExtension>py</nonFilteredFileExtension>
                        <nonFilteredFileExtension>keystore</nonFilteredFileExtension>
                    </nonFilteredFileExtensions>
                </configuration>
            </plugin>


相关文章
|
19天前
|
Java Maven
Maven的生命周期
Maven生命周期分为清理、构建和站点生成三部分,每部分含多个固定顺序执行的阶段。清理包括pre-clean和clean;构建涵盖validate、compile、test、package、install及deploy;站点生成则有pre-site、site、post-site与site-deploy。
35 6
|
4月前
|
Java Maven 容器
java依赖冲突解决问题之Maven在编译打包过程中对依赖的jar包如何解决
java依赖冲突解决问题之Maven在编译打包过程中对依赖的jar包如何解决
|
1月前
|
Java Maven
maven打瘦包,且只打入部分想打入的依赖瘦包
maven打瘦包,且只打入部分想打入的依赖瘦包 设计 工程结构分析 环境管理 城市资源 安全工程 工程管理
53 10
|
2月前
|
Java API Apache
除了 Maven,还有哪些工具可以管理项目的依赖和版本冲突
除了Maven,常用的项目依赖管理和版本冲突解决工具有Gradle、Ivy、Ant+Ivy、SBT等。这些工具各有特点,适用于不同的开发环境和需求。
163 2
|
2月前
|
XML 安全 Java
【Maven】依赖管理,Maven仓库,Maven核心功能
【Maven】依赖管理,Maven仓库,Maven核心功能
684 3
|
2月前
|
Java Maven
Maven 依赖管理
Maven 一个核心的特性就是依赖管理。当我们处理多模块的项目(包含成百上千个模块或者子项目),模块间的依赖关系就变得非常复杂,管理也变得很困难。针对此种情形,Maven 提供了一种高度控制的方法。
113 5
|
3月前
|
Java Maven
Maven 引入外部依赖
如果我们需要引入第三方库文件到项目,该怎么操作呢?
48 5
|
4月前
|
安全 Java Maven
优化Maven镜像配置:使用阿里云加速依赖下载
更新Maven镜像配置至关重要,尤其使用阿里云仓库时。在`settings.xml`中加入特定镜像配置可显著提升依赖下载速度。示例配置指定了阿里云镜像ID、替代表态仓库、安全的URL、默认布局及启用版本管理。需定位至用户目录下的`.m2/`文件夹编辑`settings.xml`,添加镜像信息后保存测试。若下载仍慢,考虑网络状况或备选镜像。多镜像设置时需注意避免冲突。
737 3
|
4月前
|
Java 测试技术 Maven
单元测试问题之在Maven项目中引入JUnit 5和Mockito的依赖如何解决
单元测试问题之在Maven项目中引入JUnit 5和Mockito的依赖如何解决
257 1
|
4月前
|
Java Maven
intellij idea如何查看项目maven依赖关系图
这篇文章介绍了如何在IntelliJ IDEA中查看项目的Maven依赖关系图,包括使用Maven工具栏和相关操作来展示和查看依赖细节。