之前匆匆学了maven,没有记好笔记,结果实习中挺多问题还是得百度解决,今天就系统的回顾一下maven。
我们现在的项目可能要用到很多框架,项目中依赖的jar包也越来越多,而且jar包之间的依赖关系也很复杂,使用maven可以自动的下载这些jar包并引用、可以很好的自动管理jar包之间的依赖,程序员可以省去很多工作。
可以简化项目的构建过程。当我们使用IDEA进行开发时,项目的构建都是IDEA进行自动完成的,但是如果脱离了IDE就要用专业的构建工具来完成。
使用原材料生产出一个产品的过程。
原材料:Java源代码、配置文件、图片等我们开发的东西。
产品:一个可以运行在服务器上的项目。
构建过程包含的主要的环节:
idea工具maven的Lifecycle功能讲解
clean:用于清除上次构建生成的所有文件,一般在构建前执行。执行该命令会删除项目路径下的target文件,但是不会删除本地的maven仓库已经生成的jar文件。
mvn clean
validate:验证,验证工程是否正确,所需的信息是否完整。
compile:编译,编译Java源代码成class字节码文件,编译后的class文件会存在target目录下的classes目录中。
主程序编译:mvn compile
测试程序编译:mvn test-compile
主体程序编译结果存放的目录:target/classes
测试程序编译结果存放的目录:target/test-classes
test:测试,用合适的测试框架来进行测试,测试compile中编译出来的代码,测试的东西一般不加包和部署。
mvn test
测试的报告存放的目录:target/surefire-reports
package:打包,将工程文件打包为指定的格式,例如JAR,WAR等(项目的pom文件中的packing标签指定打包类型)。存到target目录,并且拥有compile命令的功能进行编译。如果a项目依赖于b项目,打包b项目时,只会打包到b项目下target下,编译a项目时就会报错,因为找不到所依赖的b项目,说明a项目在本地仓库是没有找到它所依赖的b项目,这时就用到install命令。
verify:验证,检查package是否有效、符合标准。
install:安装,将项目的包安装到本地仓库中(本地仓库中的目录就是项目的坐标),好让其他项目引用。这个命令包含package,也会将项目打包成jar包或war包到本地仓库中。另外,安装操作还会将 pom.xml 文件转换为 XXX.pom 文件一起存入本地仓库。所以我们在 Maven 的本地仓库中想看一个项目的原始的 pom.xml 文件时,查看对应 XXX.pom 文件即可。
site:站点,生成项目的站点文档,生成的网站是在项目的“target/site”文件夹。
deploy:部署,复制最终的包至远程仓库,共享给其它开发人员和项目。
安装很简单,就不说了,主要记录一下maven目录下的conf/settings.xml设置文件
本地仓库默认值:用户家目录/.m2/repository。由于本地仓库的默认位置是在用户的家目录下,而家目录往往是在 C 盘,也就是系统盘。将来 Maven 仓库中 jar 包越来越多,仓库体积越来越大,可能会拖慢 C 盘运行速度,影响系统性能。所以建议将 Maven 的本地仓库放在其他盘符下。
<localRepository>D:\maven-repositorylocalRepository>
项目依赖的jar包如果本地仓库中没有,就会远程仓库中找,下载 jar 包默认访问境外的中央仓库,而国外网站速度很慢。改成阿里云提供的镜像仓库,访问国内网站,可以让 Maven 下载 jar 包的时候速度更快。配置的方式是:
- <mirror>
- <id>nexus-aliyunid>
- <mirrorOf>centralmirrorOf>
- <name>Nexus aliyunname>
- <url>http://maven.aliyun.com/nexus/content/groups/publicurl>
- mirror>
在settings.xml文件中设置会在所有maven项目中都生效,在pom文件中的配置只对当前项目有效。
- <profile>
- <id>jdk-1.8id>
- <activation>
- <activeByDefault>trueactiveByDefault>
- <jdk>1.8jdk>
- activation>
- <properties>
- <maven.compiler.source>1.8maven.compiler.source>
- <maven.compiler.target>1.8maven.compiler.target>
- <maven.compiler.compilerVersion>1.8maven.compiler.compilerVersion>
- properties>
- profile>
在项目的pom文件中定义好依赖的坐标后,先到本地仓库中找有没有,如果没有的话,就到私服中找,如果私服有则直接下载到本地仓库中用,反之则到远程仓库中下载,jar包下载后缓存在私服中(方便使用),最后都将jar包保存到本地仓库中使用。
maven的私有服务器,称为私服,是一种特殊的远程仓库,一般在公司中会自己的局域网内搭建自己的私服。
因为公司中一般会有很多人同时在开发一些项目,如果每个人都去远程仓库下载依赖,那么网络负载就会比较大, 在自己的局域网内搭建了私服,然后常用的依赖上传到私服中,下载访问的速度肯定比较快(提高jar包下载速度)。
如何配置私服:
-
- <repositories>
- <repository>
- <id>nexus_coracleid>
- <name>coracle private nexusname>
- <url>http://xxx:7081/nexus/content/groups/publicurl>
- repository>
- <repository>
- <id>thirdpartyid>
- <name>Repository for thirdpartyname>
- <url>http://xxx:7081/nexus/content/repositories/thirdpartyurl>
- repository>
- repositories>
标签的位置:dependencies/dependency/scope
范围可选值:compile/test/provided/system/runtime/import
默认值:compile
main目录(空间) | test目录(空间) | 开发过程(时间) | 部署到服务器(时间) | |
---|---|---|---|---|
有效 | 有效 | 有效 | 有效 | compile |
无效 | 有效 | 有效 | 无效 | test |
main目录(空间) | test目录(空间) | 开发过程(时间) | 部署到服务器(时间) | |
---|---|---|---|---|
有效 | 有效 | 有效 | 有效 | compile |
有效 | 有效 | 有效 | 有效 | provided |
总结:
compile:通常使用的第三方框架的 jar 包,项目在实际运行时要用到的 jar 包都是以 compile 范围进行依赖的,就是需要参与部署到服务器上的。比如 SSM 框架所需jar包。
test:测试过程中使用的 jar 包,以 test 范围依赖进来,也不会打包进去,不参与部署。比如 junit。
provided:在开发过程中需要用到的“服务器上的 jar 包”通常以 provided 范围依赖进来。比如 servlet-api、jsp-api,这个服务器上已经有了,tomcat服务器本身里面就有了。而这个范围的 jar 包之所以不参与部署、不放进 war 包,就是避免和服务器上已有的同类 jar 包产生冲突,同时减轻服务器的负担。说白了就是:“服务器上已经有了,你就别带啦!”
在 A 依赖 B,B 依赖 C 的前提下,C 是否能够传递到 A,取决于 B 依赖 C 时使用的依赖范围。
当 A 依赖 B,B 依赖 C 而且 C 可以传递到 A 的时候,A 不想要 C,需要在 A 里面把 C 排除掉。而往往这种情况都是为了避免 jar 包之间的冲突。
A项目依赖了B(B依赖了X-1.0),A项目也依赖了C(C依赖了X-2.0),如果X-都能传递到C的话,这样两个X-就会冲突,所以需要排除掉一个,解决包冲突。
- <dependency>
- <groupId>com.atguigu.mavengroupId>
- <artifactId>pro01-maven-javaartifactId>
- <version>1.0-SNAPSHOTversion>
- <scope>compilescope>
-
- <exclusions>
-
- <exclusion>
-
- <groupId>commons-logginggroupId>
- <artifactId>commons-loggingartifactId>
- exclusion>
- exclusions>
- dependency>
Maven工程之间,A 工程继承 B 工程
本质上是 A 工程的 pom.xml 中的配置继承了 B 工程中 pom.xml 的配置。
意义:
在父工程中统一管理项目中的依赖信息,具体来说是管理依赖信息的版本。
一个项目比较大的,通常要分成好几个模块,每个模块都会维护自己的依赖信息,有些依赖可能都是一样的,使用继承可以统一依赖的版本信息,统一依赖的最优版本组合,通过父工程统一管理维护依赖的信息的组合,可以保证依赖使用的准确性。
- <groupId>com.atguigu.mavengroupId>
- <artifactId>pro03-maven-parentartifactId>
- <version>1.0-SNAPSHOTversion>
-
-
- <packaging>pompackaging>
-
-
- <dependencyManagement>
- <dependencies>
- <dependency>
- <groupId>org.springframeworkgroupId>
- <artifactId>spring-coreartifactId>
- <version>4.0.0.RELEASEversion>
- dependency>
- <dependency>
- <groupId>org.springframeworkgroupId>
- <artifactId>spring-beansartifactId>
- <version>4.0.0.RELEASEversion>
- dependency>
- <dependency>
- <groupId>org.springframeworkgroupId>
- <artifactId>spring-contextartifactId>
- <version>4.0.0.RELEASEversion>
- dependency>
- <dependency>
- <groupId>org.springframeworkgroupId>
- <artifactId>spring-expressionartifactId>
- <version>4.0.0.RELEASEversion>
- dependency>
- <dependency>
- <groupId>org.springframeworkgroupId>
- <artifactId>spring-aopartifactId>
- <version>4.0.0.RELEASEversion>
- dependency>
- dependencies>
- dependencyManagement>
- <parent>
-
- <groupId>com.atguigu.mavengroupId>
- <artifactId>pro03-maven-parentartifactId>
- <version>1.0-SNAPSHOTversion>
- parent>
-
- <artifactId>pro04-maven-moduleartifactId>
-
- <dependencies>
- <dependency>
- <groupId>org.springframeworkgroupId>
- <artifactId>spring-coreartifactId>
- dependency>
- <dependency>
- <groupId>org.springframeworkgroupId>
- <artifactId>spring-beansartifactId>
- dependency>
- <dependency>
- <groupId>org.springframeworkgroupId>
- <artifactId>spring-contextartifactId>
- dependency>
- <dependency>
- <groupId>org.springframeworkgroupId>
- <artifactId>spring-expressionartifactId>
- dependency>
- <dependency>
- <groupId>org.springframeworkgroupId>
- <artifactId>spring-aopartifactId>
- dependency>
- dependencies>
编写一套符合要求、开发各种功能都能正常工作的依赖组合并不容易。如果公司里已经有人总结了成熟的组合方案,那么再开发新项目时,如果不使用原有的积累,而是重新摸索,会浪费大量的时间。为了提高效率,我们可以使用工程继承的机制,让成熟的依赖组合方案能够保留下来。
如上图所示,公司级的父工程中管理的就是成熟的依赖组合方案,各个新项目、子系统各取所需即可。