Maven高级

739 阅读4分钟

maven的生命周期

Maven 拥有三套独立的生命周期,它们分别是 clean、default 和 site。

  • clean 生命周期的目的是清理项目;
  • default(build) 生命周期的目的是构建项目;
  • site 生命周期的目的是建立项目站点。
clean 生命周期

clean 生命周期的目的是清理项目,它包括以下三个阶段。

  • pre-clean:执行清理前需要完成的工作。
  • clean:清理上一次构建过程中生成的文件,比如编译后的 class 文件等。
  • post-clean:执行清理后需要完成的工作。
default 生命周期

default 生命周期定义了构建项目时所需要的执行步骤,它是所有生命周期中最核心部分,包含的阶段如下表所述,下面只列出了一些常用的阶段

名称作用
validate验证项目结构是否正常,必要的配置文件是否存在
compile编译项目中的源代码
test运行测试案例
package将编译后的 class 和资源打包,比如 jar/war/pom
verify检测测试后的包是否完好
install将打好的包安装到本地仓库中,以便共享给本地的其他项目
deploy将打好的包安装到私服中,方便所有程序员共享
site生命周期

site 生命周期的目的是建立和发布项目站点,根据不同的插件可以生成一些html文件,html文件中包含项目的依赖、描述、java文档、甚至源码等信息。

分模块开发

服务拆分

所有的功能都写在一个项目中面临如下问题:

  1. 代码臃肿,应用启动时间长;
  2. 应用容错性差,某个小小功能的程序错误可能导致系统资源的不断消耗,最后整个系统宕机;
  3. 伸缩困难,单个应用扩展性能时只能整个应用进行扩展,造成计算资源浪费。
  4. 回归测试周期长,修复一个小小bug可能都需要对所有关键业务进行回归测试。
  5. 开发协作困难,一个大型应用系统,可能几十个甚至上百个开发人员,大家都在维护一套代码的话,代码merge复杂度急剧增加。

模块聚合与继承

模块聚合

  1. packaging 类型为 pom
 <packaging>pom</packaging>
  1. 定义构建时需要关联的模块名称
 <modules>
     <module>dao</module>
     <module>service</module>
     <module>web</module>
 </modules>

模块继承

在子模块中指定父工程坐标(GAV)

<parent>
    <artifactId>MyMaven</artifactId>
    <groupId>com.eponine</groupId>
    <version>1.0-SNAPSHOT</version>
</parent>

依赖管理

将依赖统一放在父工程中进行管理,这样可以统一版本.子模块只需要从父工程继承依赖即可。

依赖管理升级版

不使用<dependencyManagement>子工程会继承全部依赖,使用之后继承指定依赖

  1. 父工程使用<dependencyManagement>标签对依赖进行管理
  2. 子工程声明自己要从父工程继承的依赖,可以省略版本号

属性(版本)管理

在父工程中会管理大量的依赖,其中一组依赖可能需要使用相同的版本,例如spring相关依赖

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.12.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.2.12.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>5.2.12.RELEASE</version>
</dependency>

在maven父工程中,可以使用<properties>标签统一管理属性,在依赖中使用${}引用定义的属性版本即可

<properties>
    <spring.version>5.2.12.RELEASE</spring.version>
</properties>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>${spring.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>${spring.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>${spring.version}</version>
</dependency>

依赖冲突

依赖冲突是指项目依赖的某一个jar包,有多个不同的版本,因而造成包版本冲突

依赖冲突很经常是包之间的间接依赖引起的。每个显式声明的包都会依赖于一些其它的隐式包,这些隐式的包会被maven间接引入进来,从而造成类包冲突

依赖冲突的解决

  1. maven自己的解决原则
  • 第一声明优先原则
  • 最短路径匹配原则
  1. 手动依赖排除
  2. 版本锁定
第一声明优先原则

直接引入:后定义的覆盖前面的

间接引入:第一声明优先原则:谁先定义,谁优先

最短路径匹配原则

image.png

手动排除依赖

排除掉5.2.12版本的冲突依赖,使用5.1.18版本的依赖

<dependencies>
    <!--第一声明原则,谁先声明,用谁的版本-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.2.12.RELEASE</version>
      <!--手动依赖排除-->
      <!--这里排除了出现冲突的5个依赖-->
      <exclusions>
        <exclusion>
          <groupId>org.springframework</groupId>
          <artifactId>spring-expression</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.springframework</groupId>
          <artifactId>spring-core</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.springframework</groupId>
          <artifactId>spring-aop</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.springframework</groupId>
          <artifactId>spring-beans</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
        </exclusion>
      </exclusions>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.1.18.RELEASE</version>
    </dependency>

  </dependencies>
版本锁定

在父工程中使用<dependencyManagement>进行版本管理就是版本锁定