Maven高级

文章目录

    • [1. 分模块开发](#1. 分模块开发)
    • [2. 依赖管理](#2. 依赖管理)
    • [3. 聚合和继承](#3. 聚合和继承)
    • [4. 属性](#4. 属性)
    • [5. 多环境配置与应用](#5. 多环境配置与应用)
    • [6. 私服](#6. 私服)

1. 分模块开发

  1. 分模块开发设计

    • 以前是按照功能拆分,现在要学习按照模块拆分
    • 将原始模块按照功能拆分成若干个子模块,方便模块间的相互调用,接口共享
    • 解决了代码重复的问题、团队协作开发问题等等
  2. 分模块开发实现

    需求:抽取domain层

    • 步骤1:创建新模块

    • 步骤2:项目中创建domain包,删除原项目中的domain包

      maven_03_pojo项目中创建com.itheima.domain包,并将maven_02_ssm中Book类拷贝到该包中;

      删除后,maven_02_ssm项目中用到Book的类中都会有红色提示

    • 步骤3:建立依赖关系

      maven_02_ssm项目的pom.xml添加maven_03_pojo的依赖

      因为添加了依赖,所以在maven_02_ssm中就已经能找到Book类,所以刚才的报红提示就会消失

    • 步骤4:将项目安装本地仓库

      Maven会从本地仓库找对应的jar包

      安装成功后,在对应的路径下就看到安装好的jar包

    • 步骤5:编译maven_02_ssm项目

      成功编译,运行项目

    • 总结

      对于项目的拆分,大致会有如下几个步骤:

      (1) 创建Maven模块

      (2) 书写模块代码

      分模块开发需要先针对模块功能进行设计,再进行编码。不会先将工程开发完毕,然后进行拆分。拆分方式可以按照功能拆也可以按照模块拆。

      (3)通过maven指令安装模块到本地仓库(install 指令)

2. 依赖管理

依赖格式为

xml 复制代码
<!--设置当前项目所依赖的所有jar-->
<dependencies>
    <!--设置具体的依赖-->
    <dependency>
        <!--依赖所属群组id-->
        <groupId>org.springframework</groupId>
        <!--依赖所属项目id-->
        <artifactId>spring-webmvc</artifactId>
        <!--依赖版本号-->
        <version>5.2.10.RELEASE</version>
    </dependency>
</dependencies>
  1. 依赖传递与冲突问题
    • 依赖传递:依赖是具有传递性

      说明 :A代表自己的项目;B,C,D,E,F,G代表的是项目所依赖的jar包;D1和D2 E1和E2代表是相同jar包的不同版本

      (1) A依赖了B和C,B和C有分别依赖了其他jar包,所以在A项目中就可以使用上面所有jar包,这就是所说的依赖传递

      (2) 依赖传递有直接依赖和间接依赖

      • 相对于A来说,A直接依赖B和C,间接依赖了D1,E1,G,F,D2和E2
      • 相对于B来说,B直接依赖了D1和E1,间接依赖了G
      • 直接依赖和间接依赖是一个相对的概念

      (3)因为有依赖传递的存在,就会导致jar包在依赖的过程中出现冲突问题

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

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

      不管Maven怎么选,最终的结果都会在Maven的Dependencies面板中展示出来,展示的是哪个版本

      如果想更全面的查看Maven中各个坐标的依赖关系,可以点击Maven面板中的show Dependencies

  2. 可选依赖和排除依赖
    • 可选依赖指对外隐藏当前所依赖的资源---不透明
      作用:不给其他项目使用本项目的依赖资源,断开依赖传递

      html 复制代码
      <dependency>
          <groupId>com.itheima</groupId>
          <artifactId>maven_03_pojo</artifactId>
          <version>1.0-SNAPSHOT</version>
          <!--可选依赖是隐藏当前工程所依赖的资源,隐藏后对应资源将不具有依赖传递-->
          <optional>true</optional>
      </dependency>
    • 排除依赖指主动断开依赖的资源,被排除的资源无需指定版本---不需要
      作用:使用别人的项目时不使用其项目的依赖资源

      html 复制代码
      <dependency>
          <groupId>com.itheima</groupId>
          <artifactId>maven_04_dao</artifactId>
          <version>1.0-SNAPSHOT</version>
          <!--排除依赖是隐藏当前资源对应的依赖关系-->
          <exclusions>
              <exclusion>
                  <groupId>com.itheima</groupId>
                  <artifactId>maven_03_pojo</artifactId>
              </exclusion>
          </exclusions>
      </dependency>
    • 总结

      • A依赖B,B依赖C,C通过依赖传递会被A使用到,现在要想办法让A不去依赖C
      • 可选依赖是在B上设置<optional>,A不知道有C的存在,
      • 排除依赖是在A上设置<exclusions>,A知道有C的存在,主动将其排除掉

3. 聚合和继承

  1. 聚合

    • 聚合:将多个模块组织成一个整体,同时进行项目构建的过程称为聚合

    • 聚合工程:通常是一个不具有业务功能的"空"工程(有且仅有一个pom文件)

    • 作用:使用聚合工程可以将多个工程编组,通过对聚合工程进行构建,实现对所包含的模块进行同步构建

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

    • 关于聚合具体的实现步骤为:

    • 步骤1:创建一个空的maven项目

    • 步骤2:将项目的打包方式改为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.itheima</groupId>
          <artifactId>maven_01_parent</artifactId>
          <version>1.0-RELEASE</version>
          <packaging>pom</packaging>
          
      </project>

      说明:项目的打包方式,我们接触到的有三种,分别是

      • jar:默认情况,说明该项目为java项目
      • war:说明该项目为web项目
      • pom:说明该项目为聚合或继承(后面会讲)项目
    • 步骤3:pom.xml添加所要管理的项目

      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.itheima</groupId>
          <artifactId>maven_01_parent</artifactId>
          <version>1.0-RELEASE</version>
          <packaging>pom</packaging>
          
          <!--设置管理的模块名称-->
          <modules>
              <module>../maven_02_ssm</module>
              <module>../maven_03_pojo</module>
              <module>../maven_04_dao</module>
          </modules>
      </project>

      聚合工程管理的项目在进行运行的时候,会按照项目与项目之间的依赖关系来自动决定执行的顺序和配置的顺序无关

    • 步骤4:测试

      测试发现,当maven_01_parentcompile被点击后,所有被其管理的项目都会被执行编译操作。这就是聚合工程的作用

  2. 继承

    • 解决重复配置的问题:全部项目重复、部分项目重复

    • 继承:描述的是两个工程间的关系,与java中的继承相似,子工程可以继承父工程中的配置信息,常见于依赖关系的继承

    • 作用:简化配置、减少版本冲突

    • 实现步骤:

    • 步骤1:创建一个空的Maven项目并将其打包方式设置为pom

    • 步骤2:在子项目中设置其父工程

      html 复制代码
      <!--配置当前工程继承自parent工程-->
      <parent>
          <groupId>com.itheima</groupId>
          <artifactId>maven_01_parent</artifactId>
          <version>1.0-RELEASE</version>
          <!--设置父项目pom.xml位置路径-->
          <relativePath>../maven_01_parent/pom.xml</relativePath>
      </parent>
    • 步骤3:优化子项目共有依赖导入问题(全部项目重复
      (1)将子项目共同使用的jar包都抽取出来,维护在父项目的pom.xml中
      (2)删除子项目中已经被抽取到父项目的pom.xml中的jar包

    • 步骤4:优化子项目依赖版本问题(部分项目重复
      (1)在父工程mavne_01_parent的pom.xml来定义依赖管理

      html 复制代码
      <!--定义依赖管理-->
      <dependencyManagement>
          <dependencies>
              <dependency>
                  <groupId>junit</groupId>
                  <artifactId>junit</artifactId>
                  <version>4.12</version>
                  <scope>test</scope>
              </dependency>
          </dependencies>
      </dependencyManagement>

      <dependencyManagement>标签不真正引入jar包,而是配置可供子项目选择的jar包依赖
      子项目要想使用它所提供的这些jar包,需要自己添加依赖,并且不需要指定<version>
      (2)在子项目的pom.xml添加junit的依赖

      html 复制代码
      <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <scope>test</scope>
      </dependency>
  3. 聚合与继承的区别

    两种之间的作用:

    • 聚合用于快速构建项目,对项目进行管理
    • 继承用于快速配置和管理子项目中所使用jar包的版本

    聚合和继承的相同点:

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

    聚合和继承的不同点:

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

4. 属性

  1. 属性

    使用变量来配置管理依赖版本

    • 步骤1 定义属性

      xml 复制代码
      <!--定义属性-->
      <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 使用属性

      xml 复制代码
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-core</artifactId>
          <version>${spring.version}</version>
      </dependency>
      <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>
  2. 配置文件加载属性

    • 步骤1:父工程定义属性
    xml 复制代码
    <properties>
       <jdbc.url>jdbc:mysql://127.1.1.1:3306/ssm_db</jdbc.url>
    </properties>
    • 步骤2:jdbc.properties文件中引用属性

      在jdbc.properties,将jdbc.url的值直接获取Maven配置的属性

      properties 复制代码
      jdbc.driver=com.mysql.jdbc.Driver
      jdbc.url=${jdbc.url}
      jdbc.username=root
      jdbc.password=root
    • 步骤3:设置maven过滤文件范围

      Maven在默认情况下是从当前项目的src\main\resources下读取文件进行打包。现在我们需要打包的资源文件是在maven_02_ssm下,需要我们通过配置来指定下具体的资源目录。

      xml 复制代码
      <build>
          <resources>
              <!--设置资源目录-->
              <resource>
                  <directory>../maven_02_ssm/src/main/resources</directory>
                  <!--设置能够解析${},默认是false -->
                  <filtering>true</filtering>
              </resource>
          </resources>
      </build>

      说明 :directory路径前要添加../的原因是maven_02_ssm相对于父工程的pom.xml路径是在其上一层的目录中,所以需要添加

      修改完后,注意maven_02_ssm项目的resources目录就多了些东西,如下:

    • 如果有多个项目需要配置

      方式一:

      xml 复制代码
      <build>
          <resources>
              <!--设置资源目录,并设置能够解析${}-->
              <resource>
                  <directory>../maven_02_ssm/src/main/resources</directory>
                  <filtering>true</filtering>
              </resource>
              <resource>
                  <directory>../maven_03_pojo/src/main/resources</directory>
                  <filtering>true</filtering>
              </resource>
              ...
          </resources>
      </build>

      可以配,但是如果项目够多的话,这个配置也是比较繁琐

      方式二:

      xml 复制代码
      <build>
          <resources>
              <!--
      			${project.basedir}: 当前项目所在目录,子项目继承了父项目,
      			相当于所有的子项目都添加了资源目录的过滤
      		-->
              <resource>
                  <directory>${project.basedir}/src/main/resources</directory>
                  <filtering>true</filtering>
              </resource>
          </resources>
      </build>

      说明 :打包的过程中如果报如下错误:

      原因就是Maven发现你的项目为web项目,就会去找web项目的入口web.xml[配置文件配置的方式],发现没有找到,就会报错

      解决方案1:在maven_02_ssm项目的src\main\webapp\WEB-INF\添加一个web.xml文件

      解决方案2: 配置maven打包war时,忽略web.xml检查

      html 复制代码
      <build>
          <plugins>
              <plugin>
                  <groupId>org.apache.maven.plugins</groupId>
                  <artifactId>maven-war-plugin</artifactId>
                  <version>3.2.3</version>
                  <configuration>
                      <failOnMissingWebXml>false</failOnMissingWebXml>
                  </configuration>
              </plugin>
          </plugins>
      </build>
    • 在Maven中的属性分为:

    • 自定义属性(常用)

    • 内置属性

    • Setting属性

    • Java系统属性

    • 环境变量属性

      具体如何查看这些属性:

      在cmd命令行中输入mvn help:system

  3. 版本管理

    在我们jar包的版本定义中,有两个工程版本用的比较多:

    • SNAPSHOT(快照版本)
      • 项目开发过程中临时输出的版本,称为快照版本
      • 快照版本会随着开发的进展不断更新
    • RELEASE(发布版本)
      • 项目开发到一定阶段里程碑后,向团队外部发布较为稳定的版本,这种版本所对应的构件文件是稳定的
      • 即便进行功能的后续开发,也不会改变当前发布版本内容,这种版本称为发布版本

    除了上面的工程版本,我们还经常能看到一些发布版本:

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

    对于这些版本,大家只需要简单认识下即可

5. 多环境配置与应用

  1. 多环境开发

    • 父工程配置多个环境,并指定默认激活环境

      xml 复制代码
      <profiles>
          <!--开发环境-->
          <profile>
              <id>env_dep</id>
              <properties>
                  <jdbc.url>jdbc:mysql://127.1.1.1:3306/ssm_db</jdbc.url>
              </properties>
              <!--设定是否为默认启动环境-->
              <activation>
                  <activeByDefault>true</activeByDefault>
              </activation>
          </profile>
          <!--生产环境-->
          <profile>
              <id>env_pro</id>
              <properties>
                  <jdbc.url>jdbc:mysql://127.2.2.2:3306/ssm_db</jdbc.url>
              </properties>
          </profile>
          <!--测试环境-->
          <profile>
              <id>env_test</id>
              <properties>
                  <jdbc.url>jdbc:mysql://127.3.3.3:3306/ssm_db</jdbc.url>
              </properties>
          </profile>
      </profiles>
    • 命令行实现环境切换:mvn 指令 -P 环境定义ID[环境定义中获取]

  2. 跳过测试

    • 方式一:IDEA工具实现跳过测试

    • 方式二:配置插件实现跳过测试

      xml 复制代码
      <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>

      skipTests:如果为true,则跳过所有测试,如果为false,则不跳过测试

      excludes:哪些测试类不参与测试,即排除,针对skipTests为false来设置的

      includes: 哪些测试类要参与测试,即包含,针对skipTests为true来设置的

    • 方式三:命令行跳过测试mvn 指令 -D skipTests

      注意事项:

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

6. 私服

  1. 私服简介

    • 私服:公司内部搭建的用于存储Maven资源的服务器
    • 远程仓库:Maven开发团队维护的用于存储Maven资源的服务器
    • 搭建Maven私服的方式有很多,我们来介绍其中一种使用量比较大的实现方式:Nexus
    • Nexus是Sonatype公司的一款maven私服产品
    • 启动Nexus:使用cmd进入到解压目录下的nexus-3.30.1-01\bin,执行如下命令:nexus.exe /run nexus
      看到如下内容,说明启动成功
    • 浏览器访问:http://localhost:8081
    • 首次登录需要重置密码
    • 修改基础配置信息
      • 安装路径下etc目录中nexus-default.properties文件保存有nexus基础配置信息,例如默认访问端口。
    • 修改服务器运行配置信息
      • 安装路径下bin目录中nexus.vmoptions文件保存有nexus服务器启动对应的配置信息,例如默认占用内存空间
  2. 私服仓库分类

    宿主仓库hosted

    • 保存无法从中央仓库获取的资源
      • 自主研发
      • 第三方非开源项目,比如Oracle,因为是付费产品,所以中央仓库没有

    代理仓库proxy

    • 代理远程仓库,通过nexus访问其他公共仓库,例如中央仓库

    仓库组group

    • 将若干个仓库组成一个群组,简化配置
    • 仓库组不能保存资源,属于设计型仓库
  1. 本地仓库访问私服配置

    • 步骤1:私服上配置仓库

      第5,6步骤是创建itheima-snapshot仓库

      第7,8步骤是创建itheima-release仓库

    • 步骤2:配置本地Maven对私服的访问权限

      xml 复制代码
      <servers>
          <server>
              <id>itheima-snapshot</id>
              <username>admin</username>
              <password>admin</password>
          </server>
          <server>
              <id>itheima-release</id>
              <username>admin</username>
              <password>admin</password>
          </server>
      </servers>
    • 步骤3:配置私服的访问路径

      xml 复制代码
      <mirrors>
          <mirror>
              <!--配置仓库组的ID-->
              <id>maven-public</id>
              <!--*代表所有内容都从私服获取-->
              <mirrorOf>*</mirrorOf>
              <!--私服仓库组maven-public的访问路径-->
              <url>http://localhost:8081/repository/maven-public/</url>
          </mirror>
      </mirrors>
  2. 私服资源上传与下载

    • 步骤1:配置工程上传私服的具体位置
    xml 复制代码
     <!--配置当前工程保存在私服中的具体位置-->
    <distributionManagement>
        <repository>
            <!--和maven/settings.xml中server中的id一致,表示使用该id对应的用户名和密码-->
            <id>itheima-release</id>
             <!--release版本上传仓库的具体地址-->
            <url>http://localhost:8081/repository/itheima-release/</url>
        </repository>
        <snapshotRepository>
            <!--和maven/settings.xml中server中的id一致,表示使用该id对应的用户名和密码-->
            <id>itheima-snapshot</id>
            <!--snapshot版本上传仓库的具体地址-->
            <url>http://localhost:8081/repository/itheima-snapshot/</url>
        </snapshotRepository>
    </distributionManagement>
    • 步骤2:发布资源到私服

      或者执行Maven命令mvn deploy

      注意: 要发布的项目都需要配置distributionManagement标签,要么在自己的pom.xml中配置,要么在其父项目中配置,然后子项目中继承父项目即可。

      发布成功,在私服中就能看到:

      现在发布是在itheima-snapshot仓库中,如果想发布到itheima-release仓库中就需要将项目pom.xml中的version修改成RELEASE即可。

      如果想删除已经上传的资源,可以在界面上进行删除操作:

      如果私服中没有对应的jar,会去中央仓库下载,速度很慢。可以配置让私服去阿里云中下载依赖。

相关推荐
王哲晓21 分钟前
Linux通过yum安装Docker
java·linux·docker
java66666888825 分钟前
如何在Java中实现高效的对象映射:Dozer与MapStruct的比较与优化
java·开发语言
Violet永存26 分钟前
源码分析:LinkedList
java·开发语言
执键行天涯27 分钟前
【经验帖】JAVA中同方法,两次调用Mybatis,一次更新,一次查询,同一事务,第一次修改对第二次的可见性如何
java·数据库·mybatis
Jarlen41 分钟前
将本地离线Jar包上传到Maven远程私库上,供项目编译使用
java·maven·jar
蓑 羽1 小时前
力扣438 找到字符串中所有字母异位词 Java版本
java·算法·leetcode
Reese_Cool1 小时前
【C语言二级考试】循环结构设计
android·java·c语言·开发语言
严文文-Chris1 小时前
【设计模式-享元】
android·java·设计模式
Flying_Fish_roe2 小时前
浏览器的内存回收机制&监控内存泄漏
java·前端·ecmascript·es6