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

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

3.2 第一个Maven程序
3.2.1 Maven约定的目录结构及说明
lyk├─src│ ├─main 用于存放主程序│ │ ├─java 用于存放源代码文件│ │ └─resources 存放配置文件和资源文件│ └─test 用于存放测试程序│ ├─java│ └─resources|├─pom.xml 用来导入依赖坐标|└─target


3.2.2 通过命令行的方式运行Maven程序
- 在电脑的任意位置创建Hello目录(文件夹)
- 在Hello目录中创建src目录和pom.xml文件
- 在src目录中创建main和test目录
- 在main和test目录中分别创建java和resources目录
- 将以下内容复制到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>
- 编写主程序:在src/main/java目录下新建文件Hello.java
public class Hello {public String sayHello(String name){return "Hello "+name+"!";}
}
- 运行以下常用的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的步骤如下:- 点击Eclipse中的Window→Preferences

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

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

- 勾上添加的Maven核心程序

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

3.3.2 在Eclipse中创建Maven项目
1. 点击File→New→Maven Project,弹出如下窗口
- 点击Next,配置坐标(GAV)及打包方式,然后点击Finish

- 创建完工程之后发现默认的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>
- 参照3.2配置pom.xml文件,创建主程序和测试程序代码
- 在工程名Hello或pom.xml上右键→Run As运行Maven项目

3.3.3 在Eclipse中导入Maven项目
- 点击File→Import…

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


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


- 导入到Eclipse中之后就会生成一些Eclipse能识别的文件
- 有了这些Eclipse能识别的文件之后以后再往Eclipse中导入的时候选择方式一和方式二都可以
3.4 在Idea中使用Maven
3.4.1 在Idea中创建Maven项目
- 点击New Project→Maven

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

- 点击Finish即可创建成功
- 创建完工程之后在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>
- 配置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>
- 编写主代码,在src/main/java目录下新建文件Hello.java
package com.bigdata.maven;
public class Hello {public String sayHello(String name){return "Hello "+name+"!";}
}
- 编写测试代码在/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);}
}
- 使用Maven的方式运行Maven工程

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

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

- 设置Maven自动导包

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

3.5 Maven 联网问题
- 配置本地仓库
- Maven的核心程序并不包含具体功能,仅负责宏观调度。具体功能由插件来完成。Maven核心程序会到本地仓库中查找插件。如果本地仓库中没有就会从远程中央仓库下载。此时如果不能上网则无法执行Maven的具体功能。为了解决这个问题,我们可以将Maven的本地仓库指向一个在联网情况下下载好的目录。
- Maven默认的本地仓库:
~\.m2\repository目录。
Tips:~表示当前用户的家目录。
- Maven的核心配置文件位置:
apache-maven-3.6.3\conf\settings.xml - 为了以后下载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 插件和目标
- Maven的核心仅仅定义了抽象的生命周期,具体的任务都是交由插件完成的。
- 每个插件都能实现多个功能,每个功能就是一个插件目标。
- 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]中央仓库的镜像:架设在各个大洲,为中央仓库分担流量。减轻中央仓库的压力,同时更快的响应用户请求。
-
仓库中的文件
-
Maven的插件
-
我们自己开发的项目的模块
-
第三方框架或工具的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工程
- File-new-新建Module(模型),创建HelloFriend工程

- 在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>
- 主程序。在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 "小花";}
}
- 测试程序。在/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);}
}
- 关键:对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的可见性 | ||
|---|---|---|---|---|
| A | B | C | compile | √ |
| D | test | × | ||
| E | provided | × |
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工程
- 创建简单的Maven工程,打包方式为war包

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

- 在工程上右键→Build Path→Configure Build Path…

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

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

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

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

- 在MavenWeb上右键→Run As→
Run on Server部署到Tomcat上运行
7.2 通过Idea创建Maven版Web工程
1. 点击New Project,使用webapp模板
- 项目名称MavenWeb

- 确定maven配置信息

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

- 部署到Tomcat上运行
第8章 Maven库下载网站
我们可以到 http://mvnrepository.com 或 http://search.maven.org 搜索需要的jar包的依赖信息。
相关文章:
Maven教程——从入门到入坑
第1章 为什么要使用Maven 1.1 获取第三方jar包 开发中需要使用到的jar包种类繁多,获取jar包的方式都不尽相同。为了查找一个jar包找遍互联网,身心俱疲。不仅如此,费劲心血找到的jar包里有的时候并没有你需要的那个类,又或者有…...
研究生深度学习入门的十天学习计划------第九天
第9天:深度学习中的迁移学习与模型微调 目标: 理解迁移学习的核心概念,学习如何在实际应用中对预训练模型进行迁移和微调,以应对不同领域的任务。 9.1 什么是迁移学习? 迁移学习(Transfer Learning&#…...
perl的学习记录——仿真regression
1 记录的背景 之前只知道有这个强大语言的存在,但一直侥幸自己应该不会用到它,所以一直没有开始学习。然而人生这么长,怎就确定自己不会用到呢? 这次要搭建一个可以自动跑完所有case并且打印每个case的pass信息到指定的文件中。…...
【Go】go连接clickhouse使用TCP协议
离开你是傻是对是错 是看破是软弱 这结果是爱是恨或者是什么 如果是种解脱 怎么会还有眷恋在我心窝 那么爱你为什么 🎵 黄品源/莫文蔚《那么爱你为什么》 package mainimport ("context""fmt""log""time&q…...
Emlog-Pro访问网站时需要密码验证插件
插件介绍 EmlogPro访问网站密码验证插件,为你的网站添加输入密码访问网站功能,在应用中的场景往往运用在为内部或是个人使用的页面里面,在访问的时候可以提示输入密码,做隐私保护。 下载地址: 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 项目介绍 博主个人介绍:CSDN认证博客专家,CSDN平台Java领域优质创作者&…...
如何把自动获取的ip地址固定
在大多数网络环境中,设备通常会自动从DHCP服务器获取IP地址。这种动态分配IP的方式虽然灵活方便,但在某些特定场景下,我们可能需要将设备的IP地址固定下来,以确保网络连接的稳定性和可访问性。本文将详细介绍如何把自…...
Java应用的数据库死锁问题分析与解决
Java应用的数据库死锁问题分析与解决 大家好,我是微赚淘客返利系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿! 数据库死锁是多线程环境中常见的问题,尤其是在复杂的事务处理和数据访问中。死锁发生时&#x…...
ImportError: cannot import name ‘DglNodePropPredDataset‘ from ‘ogb.nodepropp
ImportError: cannot import name DglNodePropPredDataset from ogb.nodepropp 问题: 在跑深度学习时引入这个模块一直报错不能引入, 但看环境相关的包都安装好了,就是读取不到,时间还白白浪费。 解决办法 from ogb.nodeproppr…...
基于SSM(Spring、SpringMVC、MyBatis)框架的高校信息管理系统
基于SSM(Spring、SpringMVC、MyBatis)框架的高校信息管理系统是一个典型的Java Web应用开发项目。这类系统通常需要处理大量的学生、教师及课程信息,并提供相应的管理功能。下面是一个简化的设计方案,旨在帮助你理解如何构建这样的…...
C++第一节入门
一、历史 C是在C上继承拓展的! java是一家公司(甲骨文)借鉴C生成的! C#是微软借鉴java生成的! 二、命名空间 当我们定义一个名叫rand的变量,但是由于stdlib头文件里面有个函数跟rand重名!因此…...
全能型 AI 的崛起:未来的市场宠儿还是昙花一现?
近日,OpenAI 宣布将在秋季推出代号为“草莓”的新一代 AI 模型。这款 AI 被描述为全能型,从处理复杂的数学问题到应对主观性强的营销策略,它的能力可以覆盖多个领域。听起来像是科技界的“万能钥匙”,无论面对什么问题,…...
如何在PPT中插入已经绘制好的excel表格数据
1、新建一个演示文稿 2、点击“插入—对象” 3、点击“由文件创建—浏览” 4、浏览选择电脑上所处理好的excel表格数据 5、这样就可将excel表格数据插入PPT中...
微积分直觉:隐含微分
目录 一、介绍 二、梯子问题 三、结论 四、一个额外的例子 一、介绍 让我们想象一个半径为 5 的圆,以 xy 平面为中心。现在假设我们想在点 (3,4) 处找到一条切线到圆的斜率。 好吧,为了做到这一点,我们必须非常接近圆和…...
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的学习笔记! 一、再探构造函数 初始化列表:构造函数初始化的第二种方式(第一种是使用函数体内赋值)。使用方式:以一个冒号:开始,用逗号,分隔数据成员列表,每个成员变量后面跟…...
2024中国算力大会 2024 China Computational Power Conference
文章目录 一、会议详情二、重要信息三、大会介绍四、出席嘉宾五、征稿主题六、咨询 一、会议详情 二、重要信息 大会官网:https://ais.cn/u/vEbMBz提交检索:EI Compendex、IEEE Xplore、Scopus会议时间:2024年9月27-29日会议地点:…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...
Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...
Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
省略号和可变参数模板
本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...
适应性Java用于现代 API:REST、GraphQL 和事件驱动
在快速发展的软件开发领域,REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名,不断适应这些现代范式的需求。随着不断发展的生态系统,Java 在现代 API 方…...
