以前开发的时候,如果A项目需要某个jar包,可能去网上搜索下载jar包,然后复制粘贴在开发对应的位置,如果B项目也需要这个jar包,那么同样需要再次手动复制粘贴到对应的位置。
为了解决这个问题,包管理应运而生,其中最通用以maven和gradle为主,前者主要侧重于java项目,后者侧重于android项目。注意,说的是侧重于,而不是就是。
什么是maven呢,让我们来看下官方定义
At first glance Maven can appear to be many things, but in a nutshell Maven is an attempt to apply patterns to a project's build infrastructure in order to promote comprehension and productivity by providing a clear path in the use of best practices. Maven is essentially a project management and comprehension tool and as such provides a way to help with managing:
- Builds
- Documentation
- Reporting
- Dependencies
- SCMs
- Releases
- Distribution
If you want more background information on Maven you can check out The Philosophy of Maven and The History of Maven. Now let's move on to how you, the user, can benefit from using Maven.
通过官方定义我们可以知道maven通俗来说就是管理项目周期的,包括了我们最常听到的,编译,下载,依赖,部署等。
如何下载安装Maven
这一步我就不再赘述了,网上随便一搜就是一大堆
如何验证下载安装是否成功呢(一般是配了系统环境的),在命令行的任一个目录下输入mvn -v
,出现类似以下信息则说明配置成功,包括了mvn的版本号。
基本概念和配置
在构建一个maven应用之前可以先来讲下关于仓库的基本概念和一些必要的配置。
- 本地仓库:在本地pc中划分一个文件夹来存储jar包
- 中心仓库:maven官方统一管理jar包的仓库
- 远程仓库:自己或者公司搭建的给内部团队使用的jar包的仓库
当引入一个依赖的时候
- 去本地仓库寻找是否有jar包
- 如果没有则去maven管理的中心仓库去寻找
- 如果中央仓库还没有,就会去远程仓库寻找,如果连远程仓库都没有创建,那么直接抛出错误,找不到依赖
- 有远程仓库,但是远程仓库也找不到需要的jar包,同样会抛出错误,找不到依赖
除此之外,还有一个镜像的概念,只要仓库A能够包含仓库B所有的jar包,那么就可以说A是B的镜像。由于一些不可抗因素,有时候访问不了中心仓库,这时候就需要用阿里云或者其他的镜像仓库来提高访问效率。
目前为止只需要了解这几个概念,了解完后就是进行设置,对本地仓库的位置、镜像仓库的url和远程仓库的url设置。
默认的配置文件路径是{user.home}/.m2/settings.xml ,默认的本地仓库地址是{user.home}/.m2/repository/
可以看到有两个层级,一个是用户级别的修改,那么配置文件就是对应{user.home}/.m2/settings.xml,另外一个是全局修改,也就是对所有用户都生效,那么配置文件的路径对应的则是{maven.home}/conf/settings.xml
修改本地仓库位置
添加镜像地址
配置远程仓库
在配置镜像和远程仓库的时候,记得id标签是全局唯一的
查看当前生效的配置文件,可以采用mvn help:effective-settings
image-20211007170654446
可以看到配置文件中去掉了多余注释的部分,只留下了刚才手动配置的本地仓库和镜像仓库的位置。
搭建第一个maven应用
使用命令行来搭建第一个maven应用,以后可能99.99%的情况都是直接通过idea来搭建
mvn -B archetype:generate -DgroupId=com.maven.learn.cutey -DartifactId=my-first-maven -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4
可以先不管这串命令是啥意思,等后面讲了再回过头来看会有种不一样的感觉,生成项目后使用tree来看项目的目录结构长啥样
有个pom.xml,也就是后面常说的pom文件,全名Project Object Model
项目对象模型文件,描述这个项目的。
<?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.maven.learn.cutey</groupId>
<artifactId>my-first-maven</artifactId>
<version>1.0-SNAPSHOT</version>
<name>my-first-maven</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<!--省略了一些插件-->
</build>
</project>
有几个非常常用的标签
groupId
也就是组织id,一般是公司的域名倒写artifactId
可以简单的理解为项目id,一般是通过groupId:artifactId
来定位一个jar包dependencies
依赖,可以通俗的理解为jar包
其他的都可以顾名思义,这里就不再一一解释。
常用命令
编译 compile
在往常会使用javac来编译得到class文件来执行,在maven中也有类似的命令,使用mvn compile
对项目进行编译。编译完成后再看下文件目录结构,可以发现多了target目录,然后对应的路径上也有了class文件。
进到classes文件夹下,使用java命令行启动java文件,可以发现能正常运行
测试 test
在上面的目录结构中,除了main文件夹,还有一个test文件夹目录,也就是常说的测试用例目录。
默认的测试用例比较简单,没有什么好说的。可以使用mvn test
来运行测试用例
测试用例能够跑成功,然后再次使用tree来看下目录结构
可以看到又增加了一些文件,其中surefire-reports是maven的一个插件。还有一个值得注意的点是看到了testCompile
,说明是mvn test
也是经过编译后才运行的
那么mvn test-compile
即可达到只编译不运行的效果。
打包 package
真实情况下一般是不会编译所有的文件,然后放在服务器上跑class文件的,而是把项目打包成一个jar包运行,或者打成war包部署在服务器的tomcat上运行。
使用mvn package
即可按照进行打包,打包完后使用tree
查看目录结构
赫然可以看到有个jar包生成,然后使用java -jar
命令行执行jar包。但是,在这个例子里是会报错的。
上网查找资料后发现是缺少了主启动类的入口,不过在之后的springboot项目中没有这种烦恼,应该是已经配好了,感兴趣的同学可以一层一层地看下spring的pom文件。解决方法是在pom文件加入以下代码。
代码语言:javascript复制<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.maven.learn.cutey.App</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
注意
<plugins>
是放在build标签下,而不是pluginManagement标签下
再来使用java -jar
执行jar包,可以看到能够正确执行。
下载到本地 install
完成了以上的工作后,去本地的jar包上看是还没有的。
但是在现实的开发环境中,一个project是由多个module组成的,各个module之间可能需要引用依赖,这就可能要求把开发好的module下载到本地供其他module使用。使用mvn install
即可完成上述要求
可以看到在对应的位置上已经生成了jar包以及对应的版本号等,而所谓对应的位置也就是由我们一开始自定义的groupId和artifactId共同组成。
清除target目录 clean
有些情况下可能需要清楚编译生成的二进制文件,然后再编译,这就需要用到mvn clean
了
可以看到清楚完后,目录结构又变得很干净了。但是,注意,虽然target目录清空了,install下载jar包到本地的jar包在本地仓库还是存在的。
骨架 archetype
archetype 的意思是原型,可以理解为模版或者骨架,但更本质地来说,它就是maven的一个插件。一开始搭建的第一个maven应用就是用到了archetype,但是是在命令行中配好了选择哪个模版(maven-archetype-quickstart),然后把groupId和artifactId都输入了。
mvn -B archetype:generate -DgroupId=com.maven.learn.cutey -DartifactId=my-first-maven -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4
这次试试不自动生成,采用mvn archetype:generate
出现了警告,说是在远程编录中找不到骨架,只加载了本地的,所以我们只看到了10个internal的骨架,但是这不妨碍下来的动作。所以这个报警可以不用管,如果有强迫症的小伙可以上网搜下解决方案。
默认选择是7,一看第7个,就是maven-archetype-quickstart
,这次为了不同,我手动选择10,也就是maven-archetype-webapp
,顾名思义就是web项目。
选择完骨架后就是去仓库进行下载,并且让你填写groupId和artifactId和一些基本值
查看下目录结构
自定义骨架
上面两个例子都是采用别人的骨架,但是能够自定义骨架呢,maven是提供这种支持的。
首先生成骨架,在项目的根目录下,也就是和pom文件同级的目录下采用mvn archetype:create-from-project
目录结构如下
其次切到target 中的archetype目录下,先执行mvn install
,再执行mvn archetype:crawl
Build success后去前面设置的仓库根目录下
可以看到多出了一个archetype-catalog.xml
文件,查看该文件内容
可以看到最新的,自定义的archetype也在该文件下,下面就尝试看能不能成功使用自定义的骨架生成一个项目,照样执行mvn archetype:generate
可以看到第11个就是我们自己的archetype,同时可以发现,每个数字后面都跟着一个英文,internal或者local,其实还有一个remote。有时候我们只想要local,或者只想要remote,maven也提供了这样的命令加一个-DarchetypeCatalog=xxx
即可。
比如,mvn archetype:generate -DarchetypeCatalog=local
就是只加载本地的骨架
途中默认选择的是2,但是3才是自定义的,同样输入一些必要的信息
创作不易,如果对你有帮助,欢迎点赞,收藏和分享啦!
下面是个人公众号,有兴趣的可以关注一下,说不定就是你的宝藏公众号哦!!!