pom.xml 文件
一个maven工程都有一个pom.xml文件,通过pom.xml文件定义项目的坐标、项目依赖、项目信息、插件目标等。
定义maven坐标
? 每个maven工程都需要定义本工程的坐标,坐标是maven对jar包的身份定义,比如:入门程序的坐标定义如下:
<groupId>org.westos</groupId>
<artifactId>maven-first</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging > :打包类型
? jar:执行package会打成jar包
? war:执行package会打成war包
? pom :用于maven工程的继承,通常父工程设置为pom
导入依赖常见问题
Maven项目中Failure to transfer问题以及解决方法
提示错误如下
Description Resource Path Location Type
Failure to transfer org.springframework.boot:spring-boot-maven-plugin:pom:2.1.3.RELEASE from https://repo.maven.apache.org/maven2 was cached in the local repository, resolution will not be reattempted until the update interval of central has elapsed or updates are forced. Original error: Could not transfer artifact org.springframework.boot:spring-boot-maven-plugin:pom:2.1.3.RELEASE from/to central (https://repo.maven.apache.org/maven2): connect timed out pom.xml /firstweb line 1 Maven pom Loading Problem
问题分析 从问题描述上可以发现,其实是目前Maven项目无法获取缺失的plugins信息,会产生如下记录:
.m2/repository/net/bytebuddy/byte-buddy/1.9.16/byte-buddy-1.9.16-javadoc.jar.lastUpdated
Maven在下载仓库中找不到相应资源时,会生成一个.lastUpdated为后缀的文件。这个文件的存在导致了无法更新获取jar
解决办法 在*unix/macos上删除lastUpdated文件:
find ~/.m2 -name “*.lastUpdated” -exec grep -q “Could not transfer” {} ; -print -exec rm {} ;
在windows下执行如下命令:
cd %userprofile%.m2\repository for /r %i in (*.lastUpdated) do del %i
说明:这里的.m2是指maven的jar文件仓促的磁盘位置。 在删除lastUpdated文件之后,选中项目,点击右键,选中Maven->Update Project -> 选中项目和更新设置,进行更新:
问题解决 执行上述操作之后,就可以正确获取所需jar包文件了。
自动导入设置
问题 在2020.1.1版本之前IDEA pom文件导包是这样的
idea 升级到 2020.x 版后,变更 MAVEN 不会自动更新依赖、也没有设置选项。
通用方案
当我们修改了 maven 依赖以后,当前 pom 文件的右上角会出现一个 maven 的小图标,点一下就可以更新依赖了。
将鼠标放到 maven 图标上后,会出现快捷键提示。
MAC Shift + Command + O Windows:Ctrl + Shift + O
项目聚合
工程分析
在现实生活中,汽车厂家进行汽车生产时,由于整个生产过程非常复杂和繁琐,工作量非常大,所以车场都会将整个汽车的部件分开生产,最终再将生产好的部件进行组装,形成一台完整的汽车。
在企业项目开发过程中,由于项目规模庞大,业务复杂,参与的人员比较多,一般会通过合理的模块拆分将一个大型的项目拆分为N多个小模块,分别进行开发。而且拆分出的模块可以非常容易的被其他模块复用。
常见的拆分方式有两种:
第一种:按照业务模块进行拆分,每个模块拆分成一个maven工程,例如将一个项目分为用户模块、订单模块、购物车模块等,每个模块对应就是一个maven工程
第二种:按照层进行拆分,例如持久层、业务层、表现层等,每个层对应就是一个maven工程
不管是上面哪种拆分方式,通常都会提供一个父工程,将一些公共的代码和配置提取到父工程中进行统一管理和配置。
maven工程的继承
通常继承和聚合同时使用。
何为继承?
继承是为了消除重复,如果将 dao、service、web 分开创建独立的工程则每个工程的 pom.xml文件中的内容存在重复,比如:设置编译版本、锁定 spring 的版本的等,可以将这些重复的配置提取出来在父工程的 pom.xml 中定义。
在父工程的 pom.xml 中抽取一些重复的配置的,比如:锁定 jar 包的版本、设置编译版本等。
在Java语言中,类之间是可以继承的,通过继承,子类就可以引用父类中非private的属性和方法。同样,在maven工程之间也可以继承,子工程继承父工程后,就可以使用在父工程中引入的依赖。继承的目的是为了消除重复代码。
被继承的maven工程通常称为父工程,父工程的打包方式必须为pom,所以我们区分某个maven工程是否为父工程就看这个工程的打包方式是否为pom. 继承其他maven父工程的工程通常称为子工程,在pom.xml文件中通过parent标签进行父工程的继承。
聚合
何为聚合?
项目开发通常是分组分模块开发(拆分),每个模块开发完成要运行整个工程需要将每个模块聚合在一起运行(聚合),比如:dao、service、web 三个工程最终会打一个独立的 war 运行。
在maven工程的pom.xml文件中可以使用标签将其他maven工程聚合到一起,聚合的目的是为了进行统一操作。
例如拆分后的maven工程有多个,如果要进行打包,就需要针对每个工程分别执行打包命令,操作起来非常繁琐。这时就可以使用标签将这些工程统一聚合到maven工程中,需要打包的时候,只需要在此工程中执行一次打包命令,其下被聚合的工程就都会被打包了。
把拆分零散的模块聚合到一起编写一个完整的项目,这就是maven聚合思想。
版本锁定
面对众多的依赖,有一种方法不用考虑依赖路径、声明优化等因素可以采用直接锁定版本的方法确定依赖构件的版本,版本锁定后则不考虑依赖的声明顺序或依赖的路径,以锁定的版本的为准添加到工程中,此方法在企业开发中常用。
Maven 的依赖管理
- 依赖管理系统(Dependency Management System)
通过maven的依赖管理对项目所依赖的jar 包进行统一管理。
比如:项目依赖junit4.9,通过在pom.xml中定义junit4.9的依赖即使用junit4.9,如下所示是junit4.9的依赖定义:
?<dependencies>
?
?<dependency>
?
? <groupId>junit</groupId>
?
? <artifactId>junit</artifactId>
?
? <version>4.9</version>
?
? <scope>test</scope>
?</dependency>
?</dependencies>
依赖范围的介绍
添加jar包的坐标时,还可以指定这个jar包将来的作用范围
依赖继承
父子项目继承 1.1、dependencies 如果父项目pom中使用的是
<dependencies>
....
</dependencies>
则子项目pom会自动使用pom中的jar包。
1.2、dependencyManagement 如果父项目pom使用的是
<dependencyManagement>
<dependencies>
....
</dependencies>
</dependencyManagement>
则子项目pom不会自动使用父pom中的jar包,
如果需要使用,就要给出groupId和artifactId,无需给出version
的作用是统一管理版本信息 在子工程中使用时,还是需要引入坐标的,但是不需要给出version
pom文件中,当子项目中引用一个依赖而不用显示的列出版本号, Maven会沿着父子层次向上找,直到找到一个拥有元素的项目,然后它就会使用在这个元素中指定的版本号;若找不到则报错。
依赖传递规则
传递依赖 当存在传递依赖的情况时,主工程对间接依赖的jar可以访问吗?
例如:A.jar依赖于B.jar,而B.jar依赖于C.jar,那么要怎么修改配置文件,才会让A.jar 也依赖 C.jar 呢?
这要看传递依赖的jar包引入时的依赖范围——只有依赖范围为compile时可以访问
即 要使A.jar 依赖于C.jar 当且仅当C.jar的范围是compile
2.2、依赖原则 依赖原则目的:防止jar包的冲突 为了避免造成依赖重复,需要选择一个依赖路径
2.2.1、路径最短优先原则 即优先选择传递路径最短的依赖包
2.2.2、路径长度相同 路径长度相同的情况下,又可以分为是否有在同一个pom.xml两种情况
覆盖 如果在同一pom.xml文件中有2个相同的依赖;后面声明的会覆盖前面的依赖 但这里要说严禁使用本情况,严禁在同一个pom中声明两个不同的依赖 优先 如果是在不同pom.xml中有2个相同的依赖;则先声明的依赖,会覆盖后面声明的依赖
Maven 的项目构建
设置编译器版本
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
Maven常用命令介绍
**注意:**运行maven命令的时候,首先需要定位到maven项目的目录,也就是项目的pom.xml文件所在的目录。否则,必以通过参数来指定项目的目录。
Maven****命令列表 | |
---|
mvn –version | 显示版本信息 | mvn clean | 清理项目生产的临时文件,一般是模块下的target目录 | mvn compile | 编译源代码,一般编译模块下的src/main/java目录 | mvn package | 项目打包工具,会在模块下的target目录生成jar或war等文件 | mvn test | 测试命令,或执行src/test/java/下junit的测试用例. | mvn install | 将打包的jar/war文件复制到你的本地仓库中,供其他模块使用 | mvn deploy | 将打包的文件发布到远程参考,提供其他人员进行下载依赖 | mvn site | 生成项目相关信息的网站 | mvn eclipse:eclipse | 将项目转化为Eclipse项目 | mvn dependency:tree | 打印出项目的整个依赖树 | mvn archetype:generate | 创建Maven的普通java项目 | mvn tomcat:run | 在tomcat容器中运行web应用 需要插件支持 只有tomcat1.7的插件,没有1.8的所以tomcat8.0用不了此命令 | mvn jetty:run | 调用 Jetty 插件的 Run 目标在 Jetty Servlet 容器中启动 web 应用 |
**注意:**运行maven命令的时候,首先需要定位到maven项目的目录,也就是项目的pom.xml文件所在的目录。否则,必以通过参数来指定项目的目录。
Maven命令
compile
compile是maven工程的编译命令,作用是将src/main/java下的文件编译为class文件输出到target目录下。
test
test是maven工程的测试命令,会执行src/test/java下的单元测试类。
cmd执行mvn test执行src/test/java下单元测试类,下图为测试结果,运行1个测试用例,全部成功。
clean
clean是maven工程的清理命令,执行 clean会删除target目录的内容。
package
package是maven工程的打包命令,对于java工程执行package打成jar包,对于web工程打成war包。
install
install是maven工程的安装命令,执行install将maven打成jar包或war包发布到本地仓库。
从运行结果中,可以看出:
当后面的命令执行时,前面的操作过程也都会自动执行,
生命周期(了解)
三套生命周期
? maven对项目构建过程分为三套相互独立的生命周期,请注意这里说的是“三套”,而且“相互独立”,这三套生命周期分别是:
Clean Lifecycle 在进行真正的构建之前进行一些清理工作。
Default Lifecycle 构建的核心部分,编译,测试,打包,部署等等。
Site Lifecycle 生成项目报告,站点,发布站点。
一个项目生命周期(Project Lifecycle)
? 使用maven完成项目的构建,项目构建包括:清理、编译、测试、部署等过程,maven将这些过程规范为一个生命周期,如下所示是生命周期的各各阶段:
maven通过执行一些简单命令即可实现上边生命周期的各各过程,比如执行mvn compile执行编译、执行mvn clean执行清理。
一组标准集合
? maven将整个项目管理过程定义一组标准,比如:通过maven构建工程有标准的目录结构,有标准的生命周期阶段、依赖管理有标准的坐标定义等。
插件(plugin)目标(goal)
maven 管理项目生命周期过程都是基于插件完成的。
|