当前位置: 首页 > news >正文

Maven教程——从入门到入坑

第1章 为什么要使用Maven

1.1 获取第三方jar包

  开发中需要使用到的jar包种类繁多,获取jar包的方式都不尽相同。为了查找一个jar包找遍互联网,身心俱疲。不仅如此,费劲心血找到的jar包里有的时候并没有你需要的那个类,又或者有同名的类没有你要的方法——以不规范的方式获取的jar包也往往是不规范的。

  使用Maven我们可以享受到一个完全统一规范的jar包管理体系你只需要在你的项目中以坐标的方式依赖一个jar包,Maven就会自动从中央仓库进行下载,并同时下载这个jar包所依赖的其他jar包——规范、完整、准确!一次性解决所有问题!

1.2 添加第三方jar包

  在今天开发领域,有大量的第三方框架和工具可以供我们使用。要使用这些jar包最简单的方法就是复制粘贴到WEB-INF目录下的lib目录下。但是这会导致每次创建一个新的工程就需要将jar包重复复制到lib目录下,从而造成工作区中存在大量重复的文件。

  而使用Maven后每个jar包只在本地仓库中保存一份,需要jar包的工程只需要维护一个文本形式的jar包的引用——我们称之为“坐标”。不仅极大的节约了存储空间,让项目更轻巧,更避免了重复文件太多而造成的混乱。

1.3 jar包之间的依赖关系

  jar包往往不是孤立存在的,很多jar包都需要在其他jar包的支持下才能够正常工作,我们称之为jar包之间的依赖关系。最典型的例子是: commons-fileupload-1.3.jar依赖于 commons-io-2.0.1.jar,如果没有IO包,FileUpload包就不能正常工作。

  那么问题来了,当你拿到一个新的从未使用过的jar包,你如何得知他需要哪些jar包的支持呢?如果不了解这个情况,导入的jar包不够,那么现有的程序将不能正常工作。再进一步,当你的项目中需要用到上百个jar包时,你还会人为的,手工的逐一确认它们依赖的其他jar包吗?这简直是不可想象的。

  而引入Maven后,Maven就可以替我们自动的将当前jar包所依赖的其他所有jar包全部导入进来,无需人工参与,节约了我们大量的时间和精力。用实际例子来说明就是:通过Maven导入commons-fileupload-1.3.jar后,commons-io-2.0.1.jar会被自动导入,程序员不必了解这个依赖关系。

1.4 处理jar包之间的冲突

  上一点说的是jar包不足项目无法正常工作,但其实有的时候jar包多了项目仍然无法正常工作,这就是jar包之间的冲突。

  举个例子:我们现在有三个工程MakeFriend、HelloFriend、和Hello。MakeFriend依赖HelloFriend,HelloFriend依赖Hello。而Hello依赖log4j.1.2.17.jar,HelloFriend依赖log4j.1.2.14.jar。如下图所示:

  那么MakeFriend工程的运行时环境中该导入log4j.1.2.14.jar呢还是log4j.1.2.17.jar呢?

  这样的问题一个两个还可以手工解决,但如果系统中存在几十上百的jar包,他们之间的依赖关系会非常复杂,几乎不可能手工实现依赖关系的梳理。

  使用Maven就可以自动的处理jar包之间的冲突问题。因为Maven中内置了两条依赖原则:最短路径者优先和先声明者优先,上述问题MakeFriend工程会自动使用log4j.1.2.14.jar。

1.5 将项目拆分成多个工程模块

  随着JavaEE项目的规模越来越庞大,开发团队的规模也与日俱增。一个项目上千人的团队持续开发很多年对于JavaEE项目来说再正常不过。

  那么我们想象一下:几百上千的人开发的项目是同一个Web工程。那么架构师、项目经理该如何划分项目的模块、如何分工呢?这么大的项目已经不可能通过package结构来划分模块,必须将项目拆分成多个工程协同开发。多个模块工程中有的是Java工程,有的是Web工程。

  那么工程拆分后又如何进行互相调用和访问呢?这就需要用到Maven的依赖管理机制。大家请看调查项目拆分的情况:

  下层模块依赖上层,所以上层模块中定义的API都可以为下层所调用和访问。

1.6 实现项目的分布式部署

  在实际生产环境中,项目规模增加到一定程度后,可能每个模块都需要运行在独立的服务器上,我们称之为分布式部署,这里同样需要用到Maven。

第2章 Maven 是什么?

2.1 自动化构建工具

  Maven是一款自动化构建工具,专注服务于Java平台的项目构建和依赖管理。在JavaEE开发的历史上构建工具的发展也经历了一系列的演化和变迁:Make→Ant→ Maven→Gradle→其他…

2.2 构建的概念

  构建并不是创建,创建一个工程并不等于构建一个项目。

  构建是一个过程,就是以我们编写的Java代码、框架配置文件、国际化等其他资源文件、JSP页面和图片等静态资源作为“原材料”,去**“生产”出一个可以运行的项目**的过程。

  那么项目构建的全过程中都包含哪些环节呢?

2.3 构建环节

  1. 清理:删除以前的编译结果,为重新编译做好准备。

  2. 编译:将Java源程序编译为字节码文件。

  3. 测试:针对项目中的关键点进行测试,确保项目在迭代开发过程中关键点的正确性。

  4. 报告:在每一次测试后以标准的格式记录和展示测试结果。

  5. 打包:将一个包含诸多文件的工程封装为一个压缩文件用于安装或部署。Java工程对应jar包,Web工程对应war包。

  6. 安装:在Maven环境下特指将打包的结果——jar包或war包安装到本地仓库中。

  7. 部署:将打包的结果部署到远程仓库或将war包部署到服务器上运行。

第3章 Maven 如何使用

  我们来看看Maven核心程序的安装和本地仓库的必要设置。然后我们就可以编写第一个Maven程序了。

3.1 安装Maven

  1. 下载地址:http://maven.apache.org/
  2. 检查JAVA_HOME环境变量。Maven是使用Java开发的,所以必须知道当前系统环境中JDK的安装目录。
  3. 解压Maven的核心程序。将apache-maven-3.6.3-bin.zip解压到一个**非中文无空格**的目录下。例如:
  4. 配置环境变量。

  1. 查看Maven版本信息验证安装是否正确

3.2 第一个Maven程序

3.2.1 Maven约定的目录结构及说明

lyk├─src│  ├─main				用于存放主程序│  │  ├─java				用于存放源代码文件│  │  └─resources		存放配置文件和资源文件│  └─test				用于存放测试程序│      ├─java│      └─resources|├─pom.xml				用来导入依赖坐标|└─target

3.2.2 通过命令行的方式运行Maven程序

  1. 在电脑的任意位置创建Hello目录(文件夹)
  2. 在Hello目录中创建src目录和pom.xml文件
  3. 在src目录中创建main和test目录
  4. 在main和test目录中分别创建java和resources目录
  5. 将以下内容复制到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.lyk</groupId><artifactId>Hello</artifactId><version>1.0-SNAPSHOT</version><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency></dependencies></project>
  1. 编写主程序:在src/main/java目录下新建文件Hello.java
public class Hello {public String sayHello(String name){return "Hello "+name+"!";}
}
  1. 运行以下常用的Maven命令
打开cmd命令行,进入Hello项目根目录(pom.xml文件所在目录)执行mvn compile命令,查看根目录变化mvn  clean命令,然后再次查看根目录变化
mvn  compile命令, 查看根目录变化
mvn  test-compile命令, 查看target目录的变化
mvn  test命令,查看target目录变化
mvn  package命令,查看target目录变化
mvn  install命令, 查看本地仓库的目录变化

注意:运行Maven命令时一定要进入pom.xml文件所在的目录!

3.3 在Eclipse中使用Maven

3.3.1 在Eclipse中配置Maven

  Eclipse中默认自带Maven插件,但是通常我们不使用自带的Maven,而是使用自己安装的,在Eclipse中配置Maven的步骤如下:
  1. 点击Eclipse中的Window→Preferences

  1. 点开Maven前面的箭头,选择Installations,点击Add…

  1. 点击Directory…选择我们安装的Maven核心程序的根目录,然后点击Finish

  1. 勾上添加的Maven核心程序

  1. 选择Maven下的User Settings,在全局设置哪儿点击Browse…选择Maven核心程序的配置文件settings.xml,本地仓库会自动变为我们在settings.xml文件中设置的路径

3.3.2 在Eclipse中创建Maven项目

1. 点击File→New→Maven Project,弹出如下窗口

  1. 点击Next,配置坐标(GAV)及打包方式,然后点击Finish

  1. 创建完工程之后发现默认的JDK的编译版本是1.5,在Maven的核心配置文件settings.xml文件中添加以下配置将编译版本改为1.8,重启Eclipse即可
<profile><id>jdk-1.8</id><activation><activeByDefault>true</activeByDefault><jdk>1.8</jdk></activation><properties><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target><maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion></properties>
</profile>
  1. 参照3.2配置pom.xml文件,创建主程序和测试程序代码
  2. 在工程名Hello或pom.xml上右键→Run As运行Maven项目

3.3.3 在Eclipse中导入Maven项目

  1. 点击File→Import…

  1. 第一次导入手动创建的Maven项目时,由于项目中没有Eclipse生成的一些文件,使用方式一导入时Eclipse认为它不是一个工程

  1. 所以必须通过方式二导入到Eclipse中

  1. 导入到Eclipse中之后就会生成一些Eclipse能识别的文件
  2. 有了这些Eclipse能识别的文件之后以后再往Eclipse中导入的时候选择方式一和方式二都可以

3.4 在Idea中使用Maven

3.4.1 在Idea中创建Maven项目

  1. 点击New Project→Maven

  1. 点击Next,项目名称:Hello,配置要继承的模块(如果直接创建的是Project不存在这一项)、坐标(GAV)、路径。不同的Idea版本可能有所差别,这里使用的是2019.3.3的版本

  1. 点击Finish即可创建成功
  2. 创建完工程之后在settings→Build,Execusion,Development→Compiler→Java Compiler中发现默认的JDK的编译版本是1.5,在Maven的核心配置文件settings.xml文件中添加以下配置将编译版本改为1.8,重启Idea即可
<profile><id>jdk-1.8</id><activation><activeByDefault>true</activeByDefault><jdk>1.8</jdk></activation><properties><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target><maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion></properties></profile>
  1. 配置Maven的核心配置文件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.lyk</groupId><artifactId>Hello</artifactId><version>1.0-SNAPSHOT</version><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency></dependencies></project>
  1. 编写主代码,在src/main/java目录下新建文件Hello.java
package com.bigdata.maven;
public class Hello {public String sayHello(String name){return "Hello "+name+"!";}
}
  1. 编写测试代码在/src/test/java目录下新建测试文件HelloTest.java
package com.bigdata.maven;
import org.junit.Test;
public class HelloTest {@Testpublic void testHello(){Hello hello = new Hello();String maven = hello.sayHello("Maven");System.out.println(maven);}
}
  1. 使用Maven的方式运行Maven工程

3.4.2 在Idea中配置Maven

  Idea中也自带Maven插件,而且我们也可以给自带的Maven插件进行配置,所以我们可以使用自带的Maven,也可以使用我们安装的Maven核心程序
  1. 配置自带的Maven插件
  2. Idea自带的Maven在Idea的安装目录的plugins目录中

  1. 在自带的Maven里配置了本地仓库之后打开Idea之后会发现本地仓库自动变成了我们设置的仓库

  1. 设置Maven自动导包

  1. 配置我们自己安装的Maven
  2. 点击工具栏中的Settings

3.5 Maven 联网问题

  1. 配置本地仓库
  2. Maven的核心程序并不包含具体功能,仅负责宏观调度。具体功能由插件来完成。Maven核心程序会到本地仓库中查找插件。如果本地仓库中没有就会从远程中央仓库下载。此时如果不能上网则无法执行Maven的具体功能。为了解决这个问题,我们可以将Maven的本地仓库指向一个在联网情况下下载好的目录。
  3. Maven默认的本地仓库:~\.m2\repository目录。

Tips:~表示当前用户的家目录。

  1. Maven的核心配置文件位置:apache-maven-3.6.3\conf\settings.xml
  2. 为了以后下载jar包方便,配置阿里云镜像

  将以下标签配置到标签里面

<mirror><id>nexus-aliyun</id><mirrorOf>central</mirrorOf><name>Nexus aliyun</name><url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>

第4章 Maven的核心概念

4.1 POM

  Project Object Model:项目对象模型。

  将Java工程的相关信息封装为对象作为便于操作和管理的模型。

  Maven工程的核心配置。可以说学习Maven就是学习pom.xml文件中的配置。

4.2 约定的目录结构

   约定>配置>编码。意思就是能用配置解决的问题就不编码,能基于约定的就不进行配置。而Maven正是因为指定了特定文件保存的目录才能够对我们的Java工程进行自动化构建。

4.3 插件和目标

  1. Maven的核心仅仅定义了抽象的生命周期,具体的任务都是交由插件完成的。
  2. 每个插件都能实现多个功能,每个功能就是一个插件目标。
  3. Maven的生命周期与插件目标相互绑定,以完成某个具体的构建任务。

例如:compile就是插件maven-compiler-plugin的一个功能;pre-clean是插件maven-clean-plugin的一个目标。

4.4 生命周期

4.4.1 什么是Maven的生命周期?

Maven生命周期定义了各个构建环节的执行顺序,有了这个清单,Maven就可以自动化的执行构建命令了。

Maven有三套相互独立的生命周期,分别是:

  • Clean Lifecycle在进行真正的构建之前进行一些清理工作。
  • Default Lifecycle构建的核心部分,编译,测试,打包,安装,部署等等。
  • Site Lifecycle生成项目报告,站点,发布站点。

  再次强调一下它们是相互独立的,你可以仅仅调用clean来清理工作目录,仅仅调用site来生成站点。也可以直接运行 `mvn clean install site 运行所有这三套生命周期。

  每套生命周期都由一组阶段(Phase)组成,我们平时在命令行输入的命令总会对应于一个特定的阶段。比如,运行mvn clean,这个clean是Clean生命周期的一个阶段。有Clean生命周期,也有clean阶段。

clean生命周期
Clean生命周期一共包含了三个阶段:
  • pre-clean 执行一些需要在clean之前完成的工作
  • clean 移除所有上一次构建生成的文件
  • post-clean 执行一些需要在clean之后立刻完成的工作
Site生命周期
  • pre-site 执行一些需要在生成站点文档之前完成的工作
  • site 生成项目的站点文档
  • post-site 执行一些需要在生成站点文档之后完成的工作,并且为部署做准备
  • site-deploy 将生成的站点文档部署到特定的服务器上

  这里经常用到的是site阶段和site-deploy阶段,用以生成和发布Maven站点,这可是Maven相当强大的功能,Manager比较喜欢,文档及统计数据自动生成。

Default生命周期
  Default生命周期是Maven生命周期中最重要的一个,绝大部分工作都发生在这个生命周期中。这里,只解释一些比较重要和常用的阶段:
validategenerate-sourcesprocess-sourcesgenerate-resourcesprocess-resources 复制并处理资源文件,至目标目录,准备打包。**<font style="color:#FF0000;">compile</font>** 编译项目的源代码。process-classesgenerate-test-sourcesprocess-test-sourcesgenerate-test-resourcesprocess-test-resources 复制并处理资源文件,至目标测试目录。**<font style="color:#FF0000;">test-compile</font>** 编译测试源代码。process-test-classes**<font style="color:#FF0000;">test</font>**<font style="color:#FF0000;"> </font>使用合适的单元测试框架运行测试。这些测试代码不会被打包或部署。prepare-package**<font style="color:#FF0000;">package</font>** 接受编译好的代码,打包成可发布的格式,如JAR。pre-integration-testintegration-testpost-integration-testverify

**install**将包安装至本地仓库,以让其它项目依赖。

  deploy将最终的包复制到远程的仓库,以让其它开发人员与项目共享或部署到服务器上运行。

4.5 生命周期与自动化构建

   运行任何一个阶段的时候,它前面的所有阶段都会被运行,例如我们运行mvn install 的时候,代码会被编译,测试,打包。

  这就是Maven为什么能够自动执行构建过程的各个环节的原因。

  此外,Maven的插件机制是完全依赖Maven的生命周期的,因此理解生命周期至关重要。

4.6 仓库

分类
  • 本地仓库:为当前本机电脑上的所有Maven工程服务。
  • 远程仓库

[1] 私服:架设在当前局域网环境下,为当前局域网范围内的所有Maven工程服务。

[2]中央仓库:架设在Internet上,为全世界所有Maven工程服务。

[3]中央仓库的镜像:架设在各个大洲,为中央仓库分担流量。减轻中央仓库的压力,同时更快的响应用户请求。

  1. 仓库中的文件

  2. Maven的插件

  3. 我们自己开发的项目的模块

  4. 第三方框架或工具的jar包

    ※不管是什么样的jar包,在仓库中都是按照坐标生成目录结构,所以可以通过统一的方式查询或依赖。

4.7 Maven的坐标

使用如下三个向量在Maven的仓库中唯一的确定一个Maven工程。
  • groupId:公司或组织的域名倒序+当前项目名称
  • artifactId:当前项目的模块名称
  • version:当前模块的版本
<groupId>com.lyk</groupId>
<artifactId>Hello</artifactId>
<version>1.0-SNAPSHOT</version>

?如何通过坐标到仓库中查找jar包?

  将三个向量连起来:com.lyk+Hello+1.0-SNAPSHOT

  以连起来的字符串作为目录结构到仓库中查找:com/bigdata/maven/Hello/1.0-SNAPSHOT/Hello-1.0-SNAPSHOT.jar

4.8 第二个Maven工程

  1. File-new-新建Module(模型),创建HelloFriend工程

  1. 在pom.xml配置文件中配置当前工程依赖Hello
<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/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.lyk</groupId><artifactId>HelloFriend</artifactId><version>1.0-SNAPSHOT</version><name>Archetype - HelloFriend</name><url>http://maven.apache.org</url><dependencies><dependency><groupId>com.lyk</groupId><artifactId>Hello</artifactId><version>1.0-SNAPSHOT</version><scope>compile</scope></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency></dependencies>
</project>
  1. 主程序。在src/main/java目录下新建文件HelloFriend.java
package com.lyk;import come.lyk.Hello;public class HelloFriend {public String sayHelloToFriend(String name){Hello hello = new Hello();String str = hello.sayHello(name)+" I am "+this.getMyName();return str;}public String getMyName(){return "小花";}
}
  1. 测试程序。在/src/test/java目录下新建测试文件HelloFriendTest.java
import com.lyk.HelloFriend;
import org.junit.Test;
public class HelloFriendTest {@Testpublic void testHelloFriend(){HelloFriend helloFriend = new HelloFriend();String results = helloFriend.sayHelloToFriend("lyk");System.out.println(results);}
}
  1. 关键:对Hello的依赖

  这里Hello就是我们的第一个Maven工程,现在HelloFriend对它有依赖。任何一个Maven工程会根据坐标到本地仓库中去查找它所依赖的jar包。如果能够找到则可以正常工作,否则就不行。

4.9 依赖管理

  当A jar包需要用到B jar包中的类时,我们就说A对B有依赖。例如: commons-fileupload-1.3.jar依赖于commons-io-2.0.1.jar。

通过第二个Maven工程我们已经看到,当前工程会到本地仓库中根据坐标查找它所依赖的jar包。

  配置的基本形式是使用dependency标签指定目标jar包的坐标。例如:

<dependency><!--坐标--><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><!--依赖的范围--><scope>test</scope></dependency>

  如果A依赖B,B依赖C,那么A→B和B→C都是直接依赖,而A→C是间接依赖。

4.9.1 依赖的范围

compile(默认就是这个范围)
  • main目录下的Java代码**可以**访问这个范围的依赖
  • test目录下的Java代码**可以**访问这个范围的依赖

部署到Tomcat服务器上运行时**要**放在WEB-INF的lib目录下

例如:对Hello的依赖。主程序、测试程序和服务器运行时都需要用到。

test
  • main目录下的Java代码**不能**访问这个范围的依赖
  • test目录下的Java代码**可以**访问这个范围的依赖

部署到Tomcat服务器上运行时**不要**放在WEB-INF的lib目录下

例如:对junit的依赖。仅仅是测试程序部分需要。

provided
  • main目录下的Java代码**可以**访问这个范围的依赖
  • test目录下的Java代码**可以**访问这个范围的依赖

部署到Tomcat服务器上运行时**不要**放在WEB-INF的lib目录下

例如:servlet-api在服务器上运行时,Servlet容器会提供相关API,所以部署的时候不需要。

其他
runtime、import、system等。

各个依赖范围的作用可以概括为下图:

  HelloFriend项目在src/main目录下写方法添加@Test注解,会报错。

4.9.2 依赖的传递性

当存在间接依赖的情况时,主工程对间接依赖的jar可以访问吗?这要看间接依赖的jar包引入时的依赖范围——只有依赖范围为compile时可以访问,即依赖范围是compile时才具有传递性。例如:

Maven工程依赖范围对A的可见性
ABCcompile
Dtest×
Eprovided×

HelloFriend项目注释junit依赖,报错原因是依赖范围是test传递不可见。

同时修改Hello项目的test改成compile,测试完恢复。

4.9.3 依赖的原则:解决jar包冲突

路径最短者优先

路径相同时先声明者优先

  这里“声明”的先后顺序指的是dependency标签配置的先后顺序。
在这里插入图片描述

4.9.4 依赖的排除

有的时候为了确保程序正确可以将有可能重复的间接依赖排除。请看如下的例子:
  • 假设当前工程为MakeFriend,直接依赖OurFriends。
  • OurFriends依赖commons-logging的1.1.1对于MakeFriend来说是间接依赖。
  • 当前工程MakeFriend直接依赖commons-logging1.1.2

加入exclusions配置后可以在依赖OurFriends的时候排除版本为1.1.1的commons-logging的间接依赖


在这里插入图片描述

4.9.5 统一管理目标jar包的版本

以对Spring的jar包依赖为例:Spring的每一个版本中都包含`spring-context`,`springmvc`等jar包。我们应该导入版本一致的Spring jar包,而不是使用5.3.1的`spring-context`的同时使用5.3.2的springmvc。
<!--统一管理当前模块的jar包的版本-->
<properties><spring.version>5.3.1</spring.version>
</properties><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</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><dependency><groupId>org.springframework</groupId><artifactId>spring-orm</artifactId><version>${spring.version}</version></dependency>
</dependencies>

第5章 继承

5.1 为什么需要继承机制?

  由于非compile范围的依赖信息是不能在“依赖链”中传递的,所以有需要的工程只能单独配置。例如:
在这里插入图片描述

  此时如果项目需要将各个模块的junit版本统一为4.13.1,那么到各个工程中手动修改无疑是非常不可取的。使用继承机制就可以将这样的依赖信息统一提取到父工程模块中进行统一管理。

5.2 创建父工程

  父工程的打包方式为pom,父工程只需要保留pom.xml文件即可

<groupId>com.bigdata.maven</groupId>
<artifactId>Parent</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>

5.3 在子工程中引用父工程

  Hello项目和HelloFriend项目添加

<!-- 继承 -->
<parent><!-- 父工程坐标 --><groupId>com.lyk</groupId><artifactId>Parent</artifactId><version>1.0-SNAPSHOT</version><!--指定从当前pom.xml文件出发寻找父工程的pom.xml文件的相对路径--><relativePath>../Parent/pom.xml</relativePath></parent>

  此时如果子工程的groupId和version如果和父工程重复则可以删除。

5.4 在父工程中管理依赖

  将 Parent项目中的`dependencies`标签,用`dependencyManagement`标签括起来
<!--依赖管理-->
<dependencyManagement><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency></dependencies>
</dependencyManagement>

  在子项目中重新指定需要的依赖,删除范围和版本号

<dependency><groupId>junit</groupId><artifactId>junit</artifactId>
</dependency>

第6章 聚合

6.1 为什么要使用聚合?

  将多个工程拆分为模块后,需要手动逐个安装到仓库后依赖才能够生效。修改源码后也需要逐个手动进行clean操作。而使用了聚合之后就可以批量进行Maven工程的安装、清理工作。

6.2 如何配置聚合?

  在总的聚合工程Parent中使用modules/module标签组合,指定模块工程的相对路径即可

<!--聚合-->
<modules><module>../MakeFriend</module><module>../OurFriends</module><module>../HelloFriend</module><module>../Hello</module>
</modules>

  Maven可以根据各个模块的继承和依赖关系自动选择安装的顺序

第7章 通过Maven创建Web工程

7.1 通过Eclipse创建Maven版Web工程

  1. 创建简单的Maven工程,打包方式为war包

  1. 创建完成之后因缺少web.xml文件工程出现小红叉

  1. 在工程上右键→Build Path→Configure Build Path…

  1. 点击Project Facets欺骗Eclipse当前工程不是Web工程,点击应用

  1. 再告诉Eclipse当前工程是一个Web工程,点击应用并关闭

  1. 发现MavenWeb工程小红叉消失,并出现了WebContext目录

  1. 在WebContext下创建index.jsp页面并添加Tomcat库

  1. 在MavenWeb上右键→Run As→Run on Server部署到Tomcat上运行

7.2 通过Idea创建Maven版Web工程

1. 点击New Project,使用webapp模板

  1. 项目名称MavenWeb

  1. 确定maven配置信息

  1. src/main目录下新建java和resources目录,src目录下新建test,src/test目录下新建java和resources目录

  1. 部署到Tomcat上运行

第8章 Maven库下载网站

  我们可以到 http://mvnrepository.com 或 http://search.maven.org 搜索需要的jar包的依赖信息。

相关文章:

Maven教程——从入门到入坑

第1章 为什么要使用Maven 1.1 获取第三方jar包   开发中需要使用到的jar包种类繁多&#xff0c;获取jar包的方式都不尽相同。为了查找一个jar包找遍互联网&#xff0c;身心俱疲。不仅如此&#xff0c;费劲心血找到的jar包里有的时候并没有你需要的那个类&#xff0c;又或者有…...

研究生深度学习入门的十天学习计划------第九天

第9天&#xff1a;深度学习中的迁移学习与模型微调 目标&#xff1a; 理解迁移学习的核心概念&#xff0c;学习如何在实际应用中对预训练模型进行迁移和微调&#xff0c;以应对不同领域的任务。 9.1 什么是迁移学习&#xff1f; 迁移学习&#xff08;Transfer Learning&#…...

perl的学习记录——仿真regression

1 记录的背景 之前只知道有这个强大语言的存在&#xff0c;但一直侥幸自己应该不会用到它&#xff0c;所以一直没有开始学习。然而人生这么长&#xff0c;怎就确定自己不会用到呢&#xff1f; 这次要搭建一个可以自动跑完所有case并且打印每个case的pass信息到指定的文件中。…...

【Go】go连接clickhouse使用TCP协议

离开你是傻是对是错 是看破是软弱 这结果是爱是恨或者是什么 如果是种解脱 怎么会还有眷恋在我心窝 那么爱你为什么 &#x1f3b5; 黄品源/莫文蔚《那么爱你为什么》 package mainimport ("context""fmt""log""time&q…...

Emlog-Pro访问网站时需要密码验证插件

插件介绍 EmlogPro访问网站密码验证插件&#xff0c;为你的网站添加输入密码访问网站功能&#xff0c;在应用中的场景往往运用在为内部或是个人使用的页面里面&#xff0c;在访问的时候可以提示输入密码&#xff0c;做隐私保护。 下载地址&#xff1a; Emlog-Pro访问网站时需…...

Apache ShardingSphere数据分片弹性伸缩加解密中间件

Apache ShardingSphere Apache ShardingSphere 是一款分布式 SQL 事务和查询引擎,可通过数据分片、弹性伸缩、加密等能力对任意数据库进行增强。 软件背景 ShardingSphere是一套开源的分布式数据库中间件解决方案组成的生态圈,它由Sharding-JDBC、Sharding-Proxy和Sharding…...

Django+Vue家居全屋定制系统的设计与实现

目录 1 项目介绍2 项目截图3 核心代码3.1 需要的环境3.2 Django接口层3.3 实体类3.4 config.ini3.5 启动类3.5 Vue 4 数据库表设计5 文档参考6 计算机毕设选题推荐7 源码获取 1 项目介绍 博主个人介绍&#xff1a;CSDN认证博客专家&#xff0c;CSDN平台Java领域优质创作者&…...

如何把自动获取的ip地址固定

在大多数网络环境中&#xff0c;‌设备通常会自动从DHCP服务器获取IP地址。‌这种动态分配IP的方式虽然灵活方便&#xff0c;‌但在某些特定场景下&#xff0c;‌我们可能需要将设备的IP地址固定下来&#xff0c;‌以确保网络连接的稳定性和可访问性。‌本文将详细介绍如何把自…...

Java应用的数据库死锁问题分析与解决

Java应用的数据库死锁问题分析与解决 大家好&#xff0c;我是微赚淘客返利系统3.0的小编&#xff0c;是个冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 数据库死锁是多线程环境中常见的问题&#xff0c;尤其是在复杂的事务处理和数据访问中。死锁发生时&#x…...

ImportError: cannot import name ‘DglNodePropPredDataset‘ from ‘ogb.nodepropp

ImportError: cannot import name DglNodePropPredDataset from ogb.nodepropp 问题&#xff1a; 在跑深度学习时引入这个模块一直报错不能引入&#xff0c; 但看环境相关的包都安装好了&#xff0c;就是读取不到&#xff0c;时间还白白浪费。 解决办法 from ogb.nodeproppr…...

基于SSM(Spring、SpringMVC、MyBatis)框架的高校信息管理系统

基于SSM&#xff08;Spring、SpringMVC、MyBatis&#xff09;框架的高校信息管理系统是一个典型的Java Web应用开发项目。这类系统通常需要处理大量的学生、教师及课程信息&#xff0c;并提供相应的管理功能。下面是一个简化的设计方案&#xff0c;旨在帮助你理解如何构建这样的…...

C++第一节入门

一、历史 C是在C上继承拓展的&#xff01; java是一家公司&#xff08;甲骨文&#xff09;借鉴C生成的&#xff01; C#是微软借鉴java生成的&#xff01; 二、命名空间 当我们定义一个名叫rand的变量&#xff0c;但是由于stdlib头文件里面有个函数跟rand重名&#xff01;因此…...

全能型 AI 的崛起:未来的市场宠儿还是昙花一现?

近日&#xff0c;OpenAI 宣布将在秋季推出代号为“草莓”的新一代 AI 模型。这款 AI 被描述为全能型&#xff0c;从处理复杂的数学问题到应对主观性强的营销策略&#xff0c;它的能力可以覆盖多个领域。听起来像是科技界的“万能钥匙”&#xff0c;无论面对什么问题&#xff0c…...

如何在PPT中插入已经绘制好的excel表格数据

1、新建一个演示文稿 2、点击“插入—对象” 3、点击“由文件创建—浏览” 4、浏览选择电脑上所处理好的excel表格数据 5、这样就可将excel表格数据插入PPT中...

微积分直觉:隐含微分

目录 一、介绍 二、梯子问题 三、结论 四、一个额外的例子 一、介绍 让我们想象一个半径为 5 的圆&#xff0c;以 xy 平面为中心。现在假设我们想在点 &#xff08;3,4&#xff09; 处找到一条切线到圆的斜率。 好吧&#xff0c;为了做到这一点&#xff0c;我们必须非常接近圆和…...

Matlab自学笔记三十五:表table数据与外部文件的读入和写出

1.首先新建一个表变量t xingming{zhangsan;lisi;wangwu}; xuehao{1001;1002;1003}; chengji[89 95;90 87;88 84]; ttable(xingming,xuehao,chengji) 2.把表t的数据写出到student.txt writetable(t,student.txt) %使用writetable函数写出数据到txt文件 3.从student.txt文…...

闯关leetcode——3.Longest Substring Without Repeating Characters

大纲 题目地址内容 解题代码地址 题目 地址 https://leetcode.com/problems/longest-substring-without-repeating-characters/description/ 内容 Given a string s, find the length of the longest substring without repeating characters. Example 1: Input: s “abc…...

Android Radio2.0——公告注册及监听(三)

前面文章内容介绍了 Radio 相关功能的设置,我们知道可以通过设置来监听不同内容的广播公告,但是在开启对应功能的同时,还需要先注册对应公告监听,这里我们就来看一下广播公告监听的注册流程。 一、注册公告 1、接口封装 private final AtomicBoolean mHasRegisterTa = n…...

【C++】类和对象(三)再探构造函数|static成员函数|友元函数|内部类|匿名对象|对象拷贝时的编译优化

欢迎来到HarperLee的学习笔记&#xff01; 一、再探构造函数 初始化列表&#xff1a;构造函数初始化的第二种方式&#xff08;第一种是使用函数体内赋值&#xff09;。使用方式&#xff1a;以一个冒号:开始&#xff0c;用逗号,分隔数据成员列表&#xff0c;每个成员变量后面跟…...

2024中国算力大会 2024 China Computational Power Conference

文章目录 一、会议详情二、重要信息三、大会介绍四、出席嘉宾五、征稿主题六、咨询 一、会议详情 二、重要信息 大会官网&#xff1a;https://ais.cn/u/vEbMBz提交检索&#xff1a;EI Compendex、IEEE Xplore、Scopus会议时间&#xff1a;2024年9月27-29日会议地点&#xff1a…...

jEasyUI 扩展行显示细节

jEasyUI 扩展行显示细节 jEasyUI 是一个基于 jQuery 的前端框架,它提供了一系列的 UI 组件,使得 Web 应用的界面开发变得更加简单快捷。在 jEasyUI 的表格(datagrid)组件中,扩展行显示细节是一个常用的功能,它允许用户通过点击一行来展开更多的信息,这样可以有效地展示…...

YOLOv8+Deepsort+PyQt+GUI 语义分割+目标检测+姿态识别 三者合一(集成于一套系统)综合视觉分析系统

综合视觉分析系统 技术栈&#xff1a; YOLOv8&#xff1a;用于目标检测&#xff0c;是一个快速且准确的目标检测框架。DeepSORT&#xff1a;用于目标跟踪&#xff0c;结合了深度学习特征提取和卡尔曼滤波器来预测目标轨迹。GUI&#xff1a;提供一个直观易用的图形用户界面&am…...

机器学习无监督学习

版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhl1. 无监督学习概述 1.1 定义与特点 无监督学习是一种数据挖掘技术,它允许机器通过观察数据来学习数据的内在结构和模式,而无需预先标注的输出变量。这种方法特别适用于数据探索和发现隐藏在数据…...

windows10-VMware17-Ubuntu-22.04-海康2K摄像头兼容问题,求解(已解决)

文章目录 1.webrtc camera测试2.ffmpeg 测试3.Ubuntu 自带相机4.解决办法 环境&#xff1a;windows10系统下&#xff0c;VMware的Ubuntu-22.04系统 问题&#xff1a;摄像头出现兼容问题&#xff0c;本来是想开发测试的&#xff0c;Ubuntu方便些。买了海康2K的USB摄像头&#xf…...

【系统架构设计师】解释器模式

解释器模式&#xff08;Interpreter Pattern&#xff09;是一种行为型设计模式&#xff0c;它定义了文法的表示&#xff0c;并定义了一个解释器&#xff0c;该解释器使用该表示来解释语言中的句子。在解释器模式中&#xff0c;通常包括一个抽象语法树&#xff08;Abstract Synt…...

Hive原理剖析

1. 概述 背景介绍 Apache Hive是一个基于Hadoop的开源数据仓库软件&#xff0c;为分析和管理大量数据集提供了SQL-like的接口。最初由Facebook开发并贡献给Apache&#xff0c;Hive现已成为大数据处理领域的重要工具之一。它将传统的SQL功能与Hadoop的强大分布式处理能力结合&…...

在 Ubuntu 上查看重复文件

一般情况下 1. 使用 fdupes 工具 fdupes 是一个专门用于查找重复文件的工具。 安装: sudo apt-get install fdupes 使用: fdupes -r /path/to/directory -r 选项会递归查找子目录中的重复文件。 2. 使用 rmlint 工具 rmlint 是另一个强大的重复文件查找工具&#xf…...

docker容器高效连接 Redis 的方式

在微服务架构中&#xff0c;Redis 是一种常见的高效缓存解决方案&#xff0c;通常用于存储临时数据、会话信息或 token。如何在服务容器中高效、稳定地连接 Redis 是架构设计中的一个重要环节。 这篇博客将以实际项目为例&#xff0c;详细介绍如何配置 Flask 应用中的服务容器…...

手撕Python之生成器、装饰器、异常

1.生成器 生成器的定义方式&#xff1a;在函数中使用yield yield值&#xff1a;将值返回到调用处 我们需要使用next()进行获取yield的返回值 yield的使用以及生成器函数的返回的接收next() def test():yield 1,2,3ttest() print(t) #<generator object test at 0x01B77…...

LabVIEW步进电机控制方式

在LabVIEW中控制步进电机可以通过多种方式实现。每种方法都有其独特的优缺点&#xff0c;适用于不同的应用场合。下面详细介绍几种常见的步进电机控制方式&#xff0c;并进行比较。 1. 开环控制&#xff08;Open-Loop Control&#xff09; 特点 通过定期发出脉冲信号来控制步进…...