一、maven到底是什么?
Maven是基于项目对象模型(POM project object model),可以通过一小段描述信息(配置)来管理项目的构建,报告和文档的软件项目管理工具。
Maven的核心功能便是合理叙述项目间的依赖关系。
1.获取jar包的过程
2.groupId:包名,一般是域名的反写
artifactId:项目名
version:所需jar的版本
scope:jar包作用的范围
二、使用命令行管理maven项目
1.创建maven java项目:mvn archetype:create -DgroupId=com.wuhao.maven.quickstart -DartifactId=simple -DarchetypeArtifactId=maven-archetype-quickstart
mvn:核心命令
archetype:create:创建项目,现在maven高一点的版本都弃用了create命令而使用generate命令了。
-DgroupId=com.wuhao.maven.quickstart :创建该maven项目时的groupId是什么,该作用在上面已经解释了。一般使用包名的写法。因为包名是用公司的域名的反写,独一无二
-DartifactId=simple:创建该maven项目时的artifactId是什么,就是项目名称
-DarchetypeArtifactId=maven-archetype-quickstart:表示创建的是[maven]java项目。
2.创建maven web项目:mvn archetype:create -DgroupId=com.wuhao.maven.quickstart -DartifactId=myWebApp -DarchetypeArtifactId=maven-archetype-webapp -Dversion=0.0.1-snapshot
比上面多了一个-Dversion=0.0.1-snapshot,还有-DarchetypeArtifactId的参数不同。
3.命令操作maven java或web项目:
编译:mvn compile --src/main/java目录中java源码编译生成class,在target目录下。
测试:mvn test --src/test/java 目录编译
清理:mvn clean --删除target目录,就是将class文件删除
打包:mvn package --生成压缩文件:java项目#jar包;web项目#war包,也是放在target目录下
安装:mvn install --讲压缩文件(jar或者war)上传到本地仓库
部署|发布:mvn deploy --讲压缩文件上传到私服
4.其他命令:
maven java或者web项目转化Eclipse工程:
mvn eclipse:eclipse
mvn eclipse:clean 清除eclipse设置信息,即又把eclipse工程转换为maven原生项目了
转为为IDEA工程:
mvn idea:idea
mvn idea:clean 同上
三、maven生命周期
三个标准的生命周期:当执行生命周期后面的命令时,前面步骤的命令自动执行。
clean lifecycle:
Phase | Description |
---|---|
pre-clean | execute processes needed prior to the actual project cleaning |
clean | remove all files generated by the previous build |
post-clean | execute processes needed to finalize the project cleaning |
default (or build)lifecycle:项目构建真正需要执行的所有步骤:23个阶段
Phase | Description |
---|---|
validate | validate the project is correct and all necessary information is available. |
initialize | initialize build state, e.g. set properties or create directories. |
generate-sources | generate any source code for inclusion in compilation. |
process-sources | process the source code, for example to filter any values. |
generate-resources | generate resources for inclusion in the package. |
process-resources | copy and process the resources into the destination directory, ready for packaging. |
compile | compile the source code of the project. |
process-classes | post-process the generated files from compilation, for example to do bytecode enhancement on Java classes. |
generate-test-sources | generate any test source code for inclusion in compilation. |
process-test-sources | process the test source code, for example to filter any values. |
generate-test-resources | create resources for testing. |
process-test-resources | copy and process the resources into the test destination directory. |
test-compile | compile the test source code into the test destination directory |
process-test-classes | post-process the generated files from test compilation, for example to do bytecode enhancement on Java classes. For Maven 2.0.5 and above. |
test | run tests using a suitable unit testing framework. These tests should not require the code be packaged or deployed. |
prepare-package | perform any operations necessary to prepare a package before the actual packaging. This often results in an unpacked, processed version of the package. (Maven 2.1 and above) |
package | take the compiled code and package it in its distributable format, such as a JAR. |
pre-integration-test | perform actions required before integration tests are executed. This may involve things such as setting up the required environment. |
integration-test | process and deploy the package if necessary into an environment where integration tests can be run. |
post-integration-test | perform actions required after integration tests have been executed. This may including cleaning up the environment. |
verify | run any checks to verify the package is valid and meets quality criteria. |
install | install the package into the local repository, for use as a dependency in other projects locally. |
deploy | done in an integration or release environment, copies the final package to the remote repository for sharing with other developers and projects. |
Maven生命周期中常用的指令:
mvn compile //让当前项目经历生命周期中的1–>7 阶段 :完成编译主源代码编译
mvn package //让当前项目经历生命周期中的1–>17阶段 :完成打包
mvn install //让当前项目经历生命周期中的1–>22阶段 :完成包安装到本地仓库
mvn deploy //让当前生命经历生命周期中的1–>23阶段 :完成包部署到中心库中
site lifecycle:对项目的一个描述,相当于使用指南
Phase | Description |
---|---|
pre-site | execute processes needed prior to the actual project site generation |
site | generate the project's site documentation |
post-site | execute processes needed to finalize the site generation, and to prepare for site deployment |
site-deploy | deploy the generated site documentation to the specified web server |
四、maven依赖详解
1.常见的配置:
groupId、artifactId、version是依赖的基础坐标,缺一不可,具体含义上面已经讲过。
1.1 type:依赖的类型,比如是jar包还是war包等。默认是jar,表示依赖的是jar包。
注意:<type>pom.lastUpdated</type>看到lastUpdated的意思是表示使用更新描述信息,占位符作用,通俗点讲,选择该类型,jar包不会被加载进来,只是将该jar包的一些描述信息加载进来,使别的jar包在引用他时,能够看到一些相关的提示信息,仅此而已,所以说他是个占位符,只要记住他的jar包不会被加载进来。
1.2 optional:标记依赖是否可选。默认为false。
比如struts2中内置了log4j这个记录日志的功能,就是将log4j内嵌入struts2的jar包中,而struts2有没有log4j这个东西都没关系,有它,提示的信息更多,没它,也能够运行,只是提示的信息就相对而言少一些,所以这个时候,就可以对它进行可选操作,想要它就要,不想要,就设置为false。
1.3 exclusions:排除依赖传递,解决jar冲突问题。
A依赖B v1.0 C依赖B v2.0,如果一个项目同时需要A和C,那么就会传递依赖把B给加载进来,但是所依赖的B版本不同,将两个都加载进来就会引起冲突,这个时候就要使用exclusions这个属性配置。
maven同样也会有个机制避免两个都加载进来,maven默认配置在前面的优先使用,但是我们还是需要使用exclusions来配置更合理。
比如我们想要使用B v1.0,那么就在C的依赖中添加exclusions标签,在其中配置exclusion标签,在其中把B的groupId和artifactId写上就好了。这样就把C中的B v2.0给排除掉了,只剩下了A中的B v1.0.
依赖调节原则:
- 第一原则:路径近者优先原则
A-->B-->C-->D–X(1.6)
E→D→X(2.0)
使用X(2.0),因为其路径更近 - 第二原则:第一声明者优先原则。就是如果路径相同,maven默认配置在前面的优先使用
A-->B→X(1.6)
C→D→X(2.0)
这样就是路径相同,因为A在前面,C在后面,所以使用X(1.6)
maven会先根据第一原则进行选择,第一原则不成,则按第二原则处理。
1.4 scope:依赖范围,意思就是通过pom.xml加载进来的jar包,什么范围内使用生效,范围包括编译时,运行时,测试时。
compile:默认值,如果选择此值,表示编译、测试和运行都使用当前jar
test:表示只在测试时当前jar生效,在别的范围就不能使用该jar包。例如:junit。
provided:表示编译和测试时都使用当前jar,运行时就不在使用该jar了。例如servlet-api、jsp-api等。注意:tomcat和servlet版本的对应!
runtime:表示测试和运行时使用当前jar,编译时不用该jar。例如:JDBC驱动。因为JDBC驱动,我们在写代码的时候都是采用接口编程,压根就没有使用到JDBC驱动包内任何东西,只有在运行时才用的到,所有这个就是典型的使用runtime的例子。
system:从参与度来说,和provided相同,不过被依赖项不会从maven仓库下载,而是从本地文件系统拿。需要添加systemPath的属性来定义路径
import:只能在dependencyManagement中定义,可以引用这个pom文件,解决单继承的问题。
2.父子工程
2.1 意义:继承是为了消除重复,如果将dao、service、web分开创建独立的工程则每个工程的pom.xml文件中的内容存在重复,比如:设置编译版本、锁定spring的版本的等,可以将这些重复的配置提取出来在父工程的pom.xml中定义将三层都独立分开来了,web层如何调用service层代码?service层又如何调用dao层的代码呢?
这个在没有maven之前是不可以这样做的,但是有了maven一切都不一样了,web层调用service层的代码其实很简单,因为service是一个完整的项目,那么我们在web层这个项目中想要使用别得项目中的代码,只需要通过maven的pom.xml文件编写对应的坐标,将其jar包加入进来即可达到目的,因此,看图中,ssh-web依赖ssh-service,ssh-service依赖ssh-dao,其中的原理就是我说的这样,所以才能将这三层分开成独立的项目,并且进一步抽取其公有依赖的jar包,统一交由父工程来管理,这就maven带来的效果。
2.2 直接依赖传递和间接依赖传递
原文链接:https://blog.csdn.net/weixin_34653979/article/details/86633711