Maven进阶


Maven进阶

学习目标

  • 理解分模块开发的意义
  • 能够使用聚合工程快速构建项目
  • 能够使用继承简化项目配置
  • 能够根据需求配置生产、开发、测试环境,并在各环境间切换运行

一、分模块开发与设计

1.1 分模块开发与设计的意义

  • 将原始模块按照功能拆分成若干个子模块,方便模块间的相互调用,接口共享。

1.2 分模块开发实现

1.2.1 例:抽取domain层

  • 创建一个新的模块(module),在新项目中创建com.li.domain包,并将原项目中Book类拷贝到该包中;并删除原项目中的domain包。
  • 删除后,原项目中用到Book的类中都会有红色提示,出错的原因是原项目中已经将Book类删除,所以该项目找不到Book类,所以报错。
  • 要想解决上述问题,我们需要在原项目中添加新模块的依赖。

(1)建立依赖关系

  • 在原项目中添加新模块的依赖。
  • 因为添加了依赖,所以在原项目中就已经能找到Book类,所以刚才的报红提示就会消失。
  • pom.xml
<dependency>
  <groupId>com.li</groupId>
  <artifactId>maven-ssm-02-domain</artifactId>
  <version>1.0-SNAPSHOT</version>
</dependency>

(2)编译原项目

  • 但是,会报错。Could not resolve dependencies for project
  • 我们需要将新模块安装到本地仓库即可。

(3)将项目安装本地仓库

  • 将需要被依赖的项目,使用maven的install命令,把其安装到Maven的本地仓库中。
  • 但也要确保pom里的<packaging>war</packaging>改为<packaging>jar</packaging>,用来生成jar包,这样项目才能识别。

1.2.2 其它层类似

  • 必要时在pom里添加其他需要的maven依赖,例如mybatis,mysql等。

二、依赖管理

2.1 依赖传递

2.1.1 依赖具有传递性

  • 直接依赖:在当前项目中通过依赖配置建立的依赖关系。
  • 间接依赖:被资源的资源如果依赖其他资源,当前项目间接依赖其他资源。

2.1.2 依赖传递冲突问题

  • 路径优先:当依赖中出现相同的资源时,层级越深,优先级越低,层级越浅,优先级越高。
  • 声明优先:当资源在相同层级被依赖时,配置顺序靠前的覆盖配置顺序靠后的。
  • 特殊优先:当同级配置了相同资源的不同版本,后配置的覆盖先配置的。

2.2 可选依赖

  • 可选依赖指对外隐藏当前所依赖的资源 —— 不透明
<dependencies>
    <dependency>
      <groupId>com.li</groupId>
      <artifactId>maven-ssm-02-domain</artifactId>
      <version>1.0-SNAPSHOT</version>
      <!--可选依赖是隐藏当前工程所依赖的资源,隐藏后对应资源将不具有依赖传递-->
      <!-- true表示依赖不会传递 -->
      <!-- false表示依赖传递 -->
      <optional>false</optional>
    </dependency>

2.3 排除依赖

  • 排除依赖指主动断开依赖的资源,被排除的资源无需指定版本 —— 不需要
  • 排除依赖资源仅指定GA即可,无需指定V。
<dependency>
  <groupId>com.li</groupId>
  <artifactId>maven-ssm-03-dao</artifactId>
  <version>1.0-SNAPSHOT</version>
  <!--排除依赖是隐藏当前资源对应的依赖关系-->
  <exclusions>
    <exclusion>
      <groupId>com.li</groupId>
      <artifactId>maven-ssm-02-domain</artifactId>
    </exclusion>
  </exclusions>
</dependency>

自己设置自己就是可选依赖optional,别人设置自己就是排除依赖exclusions

三、聚合与继承

3.1 聚合

  • 聚合:将多个模块组织成一个整体,同时进行项目构建的过程称为聚合。
  • 聚合工程:通常是一个不具有业务功能的"空"工程(有且仅有一个pom文件)。
  • 作用:使用聚合工程可以将多个工程编组,通过对聚合工程进行构建,实现对所包含的模块进行同步构建。

    • 当工程中某个模块发生更新(变更)时,必须保障工程中与已更新模块关联的模块同步更新, 此时可以使用聚合工程来解决批量模块同步构建的问题。

3.1.1 聚合工程的开发步骤

(1)创建一个空的maven项目

(2)将项目的打包方式改为pom、pom.xml添加所要管理的项目

  • jar:默认情况,说明该项目为java项目。
  • war:说明该项目为web项目。
  • pom:说明该项目为聚合或继承项目。
<groupId>com.li</groupId>
  <artifactId>maven-ssm-00</artifactId>
  <version>1.0-SNAPSHOT</version>
    <!--  修改packaging为pom-->    
  <packaging>pom</packaging>

    <!--设置管理的模块名称-->
  <modules>
    <module>../maven-ssm-01</module>
    <module>../maven-ssm-01/maven-ssm-02-domain</module>
    <module>../maven-ssm-01/maven-ssm-03-dao</module>
  </modules>
  • 说明:聚合工程管理的项目在进行运行的时候,会按照项目与项目之间的依赖关系来自动决定执行的顺序和配置的顺序无关。
  • 聚合工程主要是用来管理项目

3.2 继承

  • 概念:继承描述的是两个工程间的关系,与java中的继承相似,子工程可以继承父工程中的配置信息,常见于依赖关系的继承
  • 作用:简化配置、减少版本冲突。

(1)创建一个空的Maven项目并将其打包方式设置为pom

  <groupId>com.li</groupId>
  <artifactId>maven-ssm-00</artifactId>
  <version>1.0-SNAPSHOT</version>
<!--  修改packaging为pom-->
  <packaging>pom</packaging>

(2)在子项目中设置其父工程

<parent>
  <groupId>com.li</groupId>
  <artifactId>maven-ssm-00</artifactId>
  <version>1.0-SNAPSHOT</version>
  <!--设置父项目pom.xml位置路径-->
  <relativePath>../maven-ssm-00/pom.xml</relativePath>
</parent>

(3)优化子项目共有依赖导入问题

  • 将子项目共同使用的jar包都抽取出来,维护在父项目的pom.xml中
<?xml version="1.0" encoding="UTF-8"?>

<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.li</groupId>
  <artifactId>maven-ssm-00</artifactId>
  <version>1.0-SNAPSHOT</version>
<!--  修改packaging为pom-->
  <packaging>pom</packaging>

  <modules>
    <module>../maven-ssm-01</module>
    <module>../maven-ssm-01/maven-ssm-02-domain</module>
    <module>../maven-ssm-01/maven-ssm-03-dao</module>
  </modules>

<dependencies>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.2.10.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.2.10.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>5.2.10.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.6</version>
  </dependency>
  <dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.3.0</version>
  </dependency>
  <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.47</version>
  </dependency>
  <dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.16</version>
  </dependency>

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

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

  <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.0</version>
  </dependency>

</dependencies>

<build>
<plugins>
  <plugin>
    <groupId>org.apache.tomcat.maven</groupId>
    <artifactId>tomcat7-maven-plugin</artifactId>
    <version>2.1</version>
    <configuration>
      <port>80</port>
      <path>/</path>
    </configuration>
  </plugin>
</plugins>
</build>
  
</project>

(4)在子工程中配置使用父工程中可选依赖的坐标

  • 注意事项:子工程中使用父工程中的可选依赖时,仅需要提供群组id和项目id,无需提供版本,版本由父工程统一提供,避免版本冲突子工程中还可以定义父工程中没有定义的依赖关系。
        <!--定义依赖管理-->
<dependencyManagement>
<dependencies>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
  </dependency>
</dependencies>
</dependencyManagement>

在其他模块的pom.xml添加junit的依赖

  • 这里就不需要添加版本了,这样做的好处就是当父工程dependencyManagement标签中的版本发生变化后,子项目中的依赖版本也会跟着发生变化。
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <scope>test</scope>
</dependency>

3.3 聚合与继承的区别

  • 作用:

    • 聚合用于快速构建项目。
    • 继承用于快速配置。
  • 相同点:

    • 聚合与继承的pom.xml文件打包方式均为pom,可以将两种关系制作到同一个pom文件中。
    • 聚合与继承均属于设计型模块,并无实际的模块内容。
  • 不同点:

    • 聚合是在当前模块中配置关系,聚合可以感知到参与聚合的模块有哪些。
    • 继承是在子模块中配置关系,父模块无法感知哪些子模块继承了自己。

四、属性管理

4.1 属性

4.1.1 解决步骤

(1)父工程中定义属性

<properties>
  <spring.version>5.2.10.RELEASE</spring.version>
  <junit.version>4.12</junit.version>
  <mybatis-spring.version>1.3.0</mybatis-spring.version>
</properties>

(2)修改依赖的version

  • 格式:${.....}
<dependencies>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-webmvc</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>
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>${mybatis-spring.version}</version>
  </dependency>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>${junit.version}</version>
    <scope>test</scope>
  </dependency>
  </dependencies>

4.1.2 配置文件加载属性(没啥必要)

  • 自己了解下就行。

4.2 版本管理

  • 在我们jar包的版本定义中,有两个工程版本用的比较多:
  • SNAPSHOT(快照版本)

    • 项目开发过程中临时输出的版本,称为快照版本。
    • 快照版本会随着开发的进展不断更新。
  • RELEASE(发布版本)

    • 项目开发到一定阶段里程碑后,向团队外部发布较为稳定的版本,这种版本所对应的构件文件是稳定的。
    • 即便进行功能的后续开发,也不会改变当前发布版本内容,这种版本称为发布版本。
  • 除了上面的工程版本,我们还经常能看到一些发布版本:

    • alpha版:内测版,bug多不稳定,内部版本不断添加新功能。
    • beta版:公测版,不稳定(比alpha稳定些),bug相对较多不断添加新功能。
    • 纯数字版。

五、多环境配置与应用

5.1 多环境开发

  • 我们平常都是在自己的开发环境进行开发, 当开发完成后,需要把开发的功能部署到测试环境供测试人员进行测试使用, 等测试人员测试通过后,我们会将项目部署到生成环境上线使用。
  • 这个时候就有一个问题是,不同环境的配置是不相同的,如不可能让三个环境都用一个数据库,所 以就会有三个数据库的url配置, 我们在项目中如何配置?
  • 要想实现不同环境之间的配置切换又该如何来实现呢?
  • maven提供配置多种环境的设定,帮助开发者在使用过程中快速切换环境。

5.1.1 具体实现步骤

  • 父工程配置多个环境,并指定默认激活环境。
<profiles>
  <!--开发环境-->
  <profile>
    <id>sql_dep</id>
    <properties>
      <jdbc.url>jdbc:mysql://127.1.1.1:3307/ssm_db</jdbc.url>
    </properties>
  </profile>
  <!--生产环境-->
  <profile>
    <id>sql_pro</id>
    <properties>
      <jdbc.url>jdbc:mysql://127.2.2.2:3306/ssm_db</jdbc.url>
    </properties>
    <!--设定是否为默认启动环境-->
    <activation>
      <activeByDefault>true</activeByDefault>
    </activation>
  </profile>
  <!--测试环境-->
  <profile>
    <id>sql_test</id>
    <properties>
      <jdbc.url>jdbc:mysql://127.3.3.3:3306/ssm_db</jdbc.url>
    </properties>
  </profile>
</profiles>

命令行实现环境切换

  • 虽然已经能够实现不同环境的切换,但是每次切换都是需要手动修改,如何来实现在不改变代码的前提下完成环境的切换呢?
  • mvn install -P sql_test

多环境切换-格式

  • 父工程中定义多环境
<profiles>
<profile>
  <id>环境名称</id>
  <properties>
    <key>value</key>
  </properties>
  <activation>
    <activeByDefault>true</activeByDefault>
  </activation>
</profile>
...
</profiles>
  • 使用多环境(构建过程)
  • mvn 指令 -P 环境定义ID[环境定义中获取]

5.2 跳过测试(了解)

(1)IDEA工具实现跳过测试

  • 图中的按钮为Toggle 'Skip Tests' Mode , Toggle翻译为切换的意思,也就是说在测试与不测试之间进行切换。

(2)配置插件实现跳过测试

  • 在父工程中的pom.xml中添加测试插件配置。
  • skipTests:如果为true,则跳过所有测试,如果为false,则不跳过测试。
  • excludes:哪些测试类不参与测试,即排除,针对skipTests为false来设置的。
  • includes:哪些测试类要参与测试,即包含,针对skipTests为true来设置的。
<build>
<plugins>
  <plugin>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.12.4</version>
    <configuration>
      <skipTests>false</skipTests>
      <!--排除掉不参与测试的内容-->
      <excludes>
        <exclude>**/BookServiceTest.java</exclude>
      </excludes>
    </configuration>
  </plugin>
</plugins>
</build>

(3)命令行跳过测试

  • 使用Maven的命令行,mvn 指令 -D skipTests
  • mvn package -D skipTests
  • 注意事项:执行的项目构建指令必须包含测试生命周期,否则无效果。
  • 例如执行compile生命周期,不经过test生命周期。
  • 该命令可以不借助IDEA,直接使用cmd命令行进行跳过测试,需要注意的是cmd要在pom.xml所在目录下进行执行。

声明:三二一的一的二|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - Maven进阶


三二一的一的二