Maven最全知识
github地址
https://github.com/a18792721831/studyMaven.git
文章列表:
Maven最全知识
[INFO] Generating project in Batch mode
Maven项目的目录结构
Maven仓库解析
Maven pom.xml解析
MVN命令与生命周期
Maven私有仓库的搭建和使用
Maven依赖
1. Maven介绍
1.1 什么是Maven
Maven:一个用于自动化构建项目和管理项目依赖的工具。
来源于百度百科
自动化构建项目:按照企业中主流的项目模板,创建完善的项目结构。
管理项目依赖:配置式添加和管理,自动下载和导入。
正常情况下,我们创建一个项目,项目中用到的jar包都需要自己下载下来,然后手动导入到工程中,然后在工程中才能使用这些jar包,从而避免我们自己重复写轮子。
spring–hello~!(如何搭建一个spring项目)
这些都需要手动导入需要jar包,但是这样就存在一些问题:
- 手动下载、管理、导入依赖
- 代码或者说项目与IDE与开发者的环境有相关性
- 操作繁琐,不易操作
所以,一个自动化构建项目,和管理项目依赖的工具就非常的有必要性。
1.2 为什么要使用Maven
在1.1中,我们知道了,有一个自动构建,自动处理依赖的工具,是非常有用的。那么,自动化构建,自动处理依赖的工具,也有很多,不仅仅只有Maven,还有Gradle等等。可能还有一些其他的,只不过可能比较少接触到。
目前为止,我目前接触到的自动化构建和管理依赖的工具,有Maven和Gradle。
如果是简单的自动化构建项目,和管理依赖,这两个其实都非常的简单,没有什么难度。
只是,在更高深的地方有一些差异:
Maven | Gradle |
---|---|
xml | Groovy |
插件多 | 可以自己写操作 |
不灵活 | 进阶难度高 |
因为Maven是使用xml的方式进行配置,而Gradle是使用Groovy语言进行配置。所以,Gradle的灵活性上可能不如Maven。
但是,也基于Maven使用xml的方式进行配置,所以 ,学习的难度上要比Gradle更加简单,毕竟想要学习高阶的Gradle,那么Groovy语言是绕不过的门槛。
所以,Gradle高阶的难度比较高。
因为Maven使用xml进行配置,所以,如果想要定制化一些自己的操作,一般是创建自己的插件,然后在项目中使用,而Gradle是使用Groovy语言进行配置,而Groovy语言是一门编程语言,所以一些简单的,小的操作,自定义的操作,完全可以用几行Groovy代码就搞定了。前提是你要会写Groovy的代码。
基于以上种种原因,目前Maven正在逐步走向淘汰,更多的使用Gradle,而Gradle的基本的思想和理念也和Maven相同,甚至Maven项目和Gradle项目可以很轻松的互转。
2. Maven入门
2.1 Maven环境的搭建
第一步:java环境
Maven主要是构建java为主的项目,所以,Maven环境是基于Java环境的,在搭建Maven环境前,首先需要保证自己有一个版本不是非常低的java环境。
我的java环境是jdk8的java环境。保证就Java相关的环境是可用的。
第二步:下载Maven
从Maven官网下载Maven.
解压压缩包:
解压后的目录如下
第三步:配置环境变量
Maven有三个大的版本:1,2,3
在1中主要配置MAVVENN_HOME
环境变量
在2中主要配置M2_HOME
环境变量
在3中主要配置PATH
环境变量
当然,你要全部都配置上去,也是没有问题的。
我们拷贝Maven解压文件夹中bin目录的地址,然后在系统的环境变量中增加这个路径(系统的环境变量如何配置请网上查找即可)。
打开命令行,输入mvn命令有反应,那么Maven环境就算配置完成了。
MAVEN_HOME
环境变量的值是通过bin目录下mvn程序相对路劲进行查找的。
所以MAVEN_HOME
如果想要配置,配置到Maven解压目录即可。
2.2 Maven项目的创建
创建模块
首先打开idea,然后配置idea中的maven。
然后创建项目:
接着配置一些版本信息(创建的项目的版本)
接着展示最终的信息,这个信息主要是用于确认,是否和预期一致。
点击finish后,就开始自动下载数据。需要访问外网(我自己挂着vpn)
等待一会就完成了
Maven已经自动创建相关的目录。
但是这个自动创建的项目,目前已有的依赖非常有限,只有两个:
其中jdk11是project的版本,新创建的moduel是jdk8.
增加依赖
我们需要的依赖肯定不只只是这两个,所以,我们就需要在网上寻找我们需要的依赖。
打开Maven官方搜索网站搜索我们需要的依赖。
搜索servlet-api
找到最新版,然后拷贝Maven版本的依赖
这个网站支持各种各样的自动化构建工具,比如Gradle,Groovy,Scala等等。
然后复制到我们新创建的模块下的pom.xml中的dependencies
下
拷贝完成后,需要我们指定依赖范围:
报异常是因为本地没有这个版本,还未下载,所以接着点击按钮,刷新依赖
刷新完成后,就不在报异常了
接下来增加jsp的依赖
刷新完成后所有的依赖就全部搞定了。
配置插件
我们虽然将依赖引入了,但是还缺少一些插件。
同样的,在Maven官方插件搜索
但是像其中一些常用的,默认就已经加入了
我们主要是想增加tomcat的插件
点击tomcat后,会展示支持的版本
我们选择最新的版本
点进入后会看到这个版本的tomcat插件使用的一些要求,以及相关的插件配置代码
我们使用tomcat7就够了
然后刷新
运行项目
第一种,使用命令运行
创建Maven命令的方式运行:
点击运行或者调试
第一次运行会下载一些相关的数据,下载完成后,就会将容器启动成功
接着访问url,验证是否启动成功
浏览器访问成功
这个Hello World就是项目中index.jsp中的内容
第二次运行就不在重新下载数据了
第二种,使用本地tomcat运行
运行或者调试
自动打开。
3. 目录结构分析
3.1 Maven工作原理
Maven主要的工作原理
Maven说白了就是一个下载工具。
3.2 Maven目录结构
Maven项目的文件结构
-
bin:存放二进制程序
-
boot:Maven的类加载器,存储Maven自己的jar包
-
conf:里面主要是settings.xml存放位置
-
lib:存放Maven的类库文件
-
usrlibs:自定义仓库的位置
-
LICENSE:声明文件
-
NOTICE:版本信息
-
README.txt:说明文件
3.3 Maven项目的目录结构
比如
- src:源码,静态文件等等
- target:编译打包后的文件
- pom.xml:依赖对象模型
pom:
project object model 项目对象模型
package object management 依赖包对象管理器
项目目录结构,只是约定大于规范的结构。
有些目录可以缺少。
4. 仓库解析
仓库分类
远程仓库、中央仓库,镜像仓库。
本地仓库:默认:C:/User/用户名/.m2/repository/
Maven仓库私服:Neuex…
这些仓库的结构,如图所示
远程仓库配置
<mirror>
<id>aliyunMaven</id>
<name>aliyun Maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
本地仓库配置
刷新项目,重新下载依赖,此时,依赖的包已经被下载到指定的本地仓库了
5. pom.xml解析
对于Maven来说,核心的配置只有两个,分别是setting.xml
和pom.xml
。
5.1 setting.xml
在Maven的config目录下,有一Maven自己的setting.xml
文件。
相关的配置说明如下:
在配置文件中也有说明
当然,Maven和Gradle类似,在跟项目中可以配置整个跟项目的配置,跟项目的配置,全部的子项目共享。
所以,在Gradle中有setting.gradle
。setting.gradle
在跟项目的路径下。
相对应的,在Maven中也有setting.xml
。setting.xml
也在跟项目的路径下。
子项目共享跟项目的配置。
5.2 pom.xml
在项目中,有项目自己的配置。
比如在Gradle中是build.gradle
,在Maven中就是build.gradle
了。
到目前为止,我们现在有三个配置文件:Maven的配置,跟项目的配置,子项目的配置。
那么,这三个项目的优先级是怎么样的呢?
pom.xml > settings.xml(project) > settings.xml(maven)
也就是说,子项目中配置的是优先级最高的,接下来是跟项目的配置,最后是Maven的配置。
- 项目基础信息配置
- 项目构建环境配置
- 项目仓库管理配置
- 项目依赖管理配置
- 项目报表信息配置
- 项目部署分发配置
<?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">
<!-- 1.项目基本信息配置-->
<!--父项目的坐标,如果子项目中没有配置相关的信息,那么使用父项目中的配置。
坐标包括:
groupID,artifactID和version。-->
<parent>
<!--被继承的父项目标识符-->
<artifactId>studyMaven</artifactId>
<!--被继承的父项目的全球唯一标识符-->
<groupId>org.study</groupId>
<!--被继承的父项目的版本-->
<version>1.0-SNAPSHOT</version>
<!--被继承的父项目的pom.xml文件的相对路径。相对路径允许选择一个不同的路劲。默认是../pom.xml。-->
<relativePath>../pom.xml</relativePath>
</parent>
<!--生命项目描述符尊新哪一个POM模型版本。模型本身的版本很少改变,但是依然是必不可少的。-->
<modelVersion>4.0.0</modelVersion>
<!--子项目的全球唯一标识符,通常使用全限定的包名区分该项目和其他项目。并且构建时生成的路径也是由此生成。-->
<groupId>org.study</groupId>
<!--构件的标识符,它和groupId一起唯一标识一个构件。换句话说,同一个groupId下的artifactId不可重复.-->
<!--构件是项目生产的或者使用的一个东西,Maven为项目产生的构件包括:jar,war,源码和二进制。-->
<artifactId>study-helloMaven</artifactId>
<!--子项目的版本.-->
<version>1.0-SNAPSHOT</version>
<!--项目产生的构件类型。-->
<packaging>war</packaging>
<!--项目的名称,Maven用于生成文档.-->
<name>study-helloMaven Maven Webapp</name>
<!-- 项目的主页URL,Maven用于生成文档。-->
<url>http://www.example.com</url>
<!--项目的详细描述,Maven产生文档使用。
可以使用HTML格式描述,类似javaDoc.-->
<description>study maven project.</description>
<!--项目创建的年份-->
<inceptionYear>2020</inceptionYear>
<!--项目先关的邮件列表信息-->
<mailingLists>
<!--项目相关的所有的邮件列表,自动产生的网站引用这些信息.-->
<mailingList>
<!--邮件的名称-->
<name>study</name>
<!--发送邮件的地址或者链接,如果是邮件地址,创建文档时,mailto:链接会被自动创建-->
<post>[email protected]</post>
<!--订阅邮件的地址或者链接-->
<subscribe>[email protected]</subscribe>
<!--取消订阅邮件的地址或者链接-->
<unsubscribe>[email protected]</unsubscribe>
<!--浏览邮件信息的URL-->
<archive>http://localhost:8080/</archive>
</mailingList>
</mailingLists>
<!--项目开发者列表-->
<developers>
<!--某个项目开发者的信息-->
<developer>
<!--SCM李项目开发者的唯一标识-->
<id>xx</id>
<!--项目开发者的全名-->
<name>zz</name>
<!--项目开发者的email-->
<email>[email protected]</email>
<!--项目开发者的主页-->
<url>http://xxx.com</url>
<!--项目开发者在项目中扮演的角色-->
<roles>
<role>user1</role>
<role>manage1</role>
</roles>
<!--项目开发者所属组织-->
<organization>study</organization>
<!--项目开发者所属组织的URL-->
<organizationUrl>http://study.com</organizationUrl>
<!--项目开发者属性,即时信息处理等等-->
<properties>
<dept>XX</dept>
</properties>
<!--项目开发者所在的时区-->
<timezone>+8</timezone>
</developer>
</developers>
<!--项目的其他贡献者列表-->
<contributors>
<!--项目的其他贡献者-->
<contributor>
<name>zz</name>
<email>[email protected]</email>
<url>http://www.baidu.com</url>
<organization>xx</organization>
<organizationUrl>http://xx.com</organizationUrl>
<roles>
<role>xx</role>
</roles>
<properties>
<zz>x</zz>
</properties>
<timezone>7</timezone>
</contributor>
</contributors>
<!--项目所以有的License列表.-->
<licenses>
<!--项目的license,用于生成项目的web站点的license页面,一些报表等也会用到-->
<license>
<!--license用于法律上的名称-->
<name>Apache2</name>
<!--官方的license正文页面的URL-->
<url>http://www.baidu.com</url>
<!--项目分发的主要方式:repo,可以从Maven库下载;manual,用户必须手动下载和安装依赖-->
<distribution>repo</distribution>
<!--关于license的补充信息-->
<comments>this is the comments</comments>
</license>
</licenses>
<!--SCM(Source Control Management)标签允许你配置你的代码库,供Maven web站点和其他插件使用-->
<scm>
<!--SCM的URL,描述了版本库和如何连接到版本库。-->
<connection>scm:svn:http://svn.xx.com/maven/xxxxx</connection>
<!--给开发者使用,类似conntecion元素,连接不仅仅只读-->
<developerConnection>scm:svn:http://svn.xxx.com/xxxx</developerConnection>
<!--当前代码的标签,开发阶段默认为HEAD-->
<tag>1</tag>
<!--指向项目的可浏览SCM库的URL.-->
<url>http://svn.xxxx.com</url>
</scm>
<!--描述项目所属组织的各种属性,Maven产生文档使用-->
<organization>
<!--组织的全名-->
<name>hello</name>
<!--组织的主页-->
<url>http://wwww.hello.com</url>
</organization>
<!-- 2.项目构建环境配置-->
<!--描述了项目构建环境中的前提条件-->
<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>
<!--项目问题管理系统-->
<issueManagement>
<!--问题管理系统的名字-->
<system>jira</system>
<!--问题管理系统的url-->
<url>http://jira.xxxx.com</url>
</issueManagement>
<!--项目持续集成信息-->
<ciManagement>
<!--持续集成系统的名字-->
<system>jenkins</system>
<!--持续集成系统的地址-->
<url>http://jenkins.xx.com</url>
<!--构建完成时,需要通知的开发者,或者用户拒的配置:包括成功,失败,异常,警告等)-->
<notifiers>
<!--配置一个通知-->
<notifier>
<!--发布通知的方式-->
<type>mail</type>
<!--发生错误时是否通知-->
<sendOnError>true</sendOnError>
<!--构建失败时是否通知-->
<sendOnFailure>true</sendOnFailure>
<!--构建成功时是否通知-->
<sendOnSuccess>true</sendOnSuccess>
<!--构建发生警告时是否通知-->
<sendOnWarning>true</sendOnWarning>
<!--通知哪些人-->
<address>[email protected]</address>
<!--扩展配置-->
<configuration/>
</notifier>
</notifiers>
</ciManagement>
<!-- 模块(子项目) 被构建成项目的一部分。列出的每个模块元素是指向该模块的目录的相对路劲.-->
<modules>
<!--模块的名字-->
<!--
<module>helloMaven</module>
-->
</modules>
<!--项目的依赖-->
<dependencies>
<!--一个依赖-->
<dependency>
<!--被依赖的包的标识符-->
<groupId>junit</groupId>
<!--被依赖的包的唯一标识符-->
<artifactId>junit</artifactId>
<!--被依赖的包的版本-->
<version>4.11</version>
<!--被依赖的包的作用范围(子项目,全部项目,测试,系统。。。)-->
<scope>test</scope>
<!--依赖的方式-->
<type>jar</type>
<!--被依赖的jar包的编译方式-->
<!-- <classifier>jdk11</classifier>-->
<!--操作系统的路径-->
<!-- <systemPath></systemPath>-->
<!--计算依赖时,排除的依赖列表-->
<exclusions>
<!-- <exclusion>-->
<!-- <groupId>org.apache</groupId>-->
<!-- <artifactId>apache</artifactId>-->
<!-- </exclusion>-->
</exclusions>
<!--依赖是否是可选依赖-->
<optional>false</optional>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.23</version>
<scope>provided</scope>
</dependency>
</dependencies>
<!--构建项目需要得到信息-->
<build>
<!--项目源码目录,相对路径,相对于pom.xml-->
<sourceDirectory>src</sourceDirectory>
<!--项目脚本目录。脚本不会参与编译以,但是当构建完成后,会被拷贝到输出目录。因为脚本是解释执行的,不是编译执行的。-->
<scriptSourceDirectory>src/main/resources</scriptSourceDirectory>
<!--单元测试的源码目录-->
<testSourceDirectory>src/test</testSourceDirectory>
<!--编译过的应用程序的class文件存放位置-->
<outputDirectory>.out</outputDirectory>
<!--单元测试编译后的class文件存放位置-->
<testOutputDirectory>.out</testOutputDirectory>
<!--扩展的构建-->
<extensions>
<!--扩展的构建-->
<!--
<extension>
<!-扩展的构建的标识符
<groupId>xx</groupId>
<!-扩展的构建的唯一符
<artifactId>xzx</artifactId>
<!-扩展构建的版本
<version>1</version>
</extension>
-->
</extensions>
<!--项目没有规定目标时的默认值-->
<defaultGoal>succ</defaultGoal>
<!--项目的资源信息-->
<resources>
<!--一类资源-->
<resource>
<!--资源文件的目标路径-->
<targetPath>.target</targetPath>
<!--是否启用参数-->
<filtering>false</filtering>
<!--资源存放的目录,相对pom.xml的路劲-->
<directory>src/main/resources</directory>
<!--包含的模式列表-->
<includes>
<include>**/*.yaml</include>
</includes>
<!--排除的模式列表-->
<excludes>
<exclude>**/*.log</exclude>
</excludes>
</resource>
</resources>
<!--单元测试的资源信息-->
<testResources>
<testResource>
<targetPath>.target</targetPath>
<filtering>false</filtering>
<directory>src/test/resources</directory>
<includes>
<include>**/*.yaml</include>
</includes>
<excludes>
<exclude>**/*.log</exclude>
</excludes>
</testResource>
</testResources>
<!--构建产物最终的名字-->
<finalName>study-helloMaven</finalName>
<!--项目可以引用的默认插件信息。插件配置项直到被引用,才会被解析或绑定到生命周期。-->
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<!--插件列表-->
<plugins>
<!--插件信息-->
<plugin>
<!--插件在仓库中的groupId-->
<groupId>org.apache.tomcat.maven</groupId>
<!--插件在仓库中的唯一符-->
<artifactId>tomcat7-maven-plugin</artifactId>
<!--插件在仓库中的版本-->
<version>2.2</version>
<!--是否下载Maven扩展,影响性能-->
<extensions>false</extensions>
<!--构建生命周期中执行一组目标配置,可以有多组目标配置,每组目标配置可能不同-->
<executions>
<!--一组目标配置-->
<execution>
<!--目标配置的标识-->
<id>1</id>
<!--绑定构建生命周期阶段-->
<phase>clean</phase>
<!--配置的目标值-->
<goals>
<goal>run</goal>
</goals>
<!--配置传播范围-->
<inherited>false</inherited>
<!--DOM对象的配置-->
<configuration>
<address>127.0.0.1</address>
<port>8080</port>
</configuration>
</execution>
</executions>
<!--项目引入插件需要引入的额外的依赖-->
<dependencies>
<dependency>
<groupId>org.apache</groupId>
<artifactId>apache</artifactId>
<version>21</version>
<scope>provided</scope>
</dependency>
</dependencies>
</plugin>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>
<!--配置的环境列表-->
<profiles>
<!--一个环境-->
<profile>
<!--环境id-->
<id>dev</id>
<!--profile的条件,是否使用这个环境的判断条件.-->
<activation>
<!--环境是否是默认环境-->
<activeByDefault>false</activeByDefault>
<!--条件-->
<jdk>jdk11</jdk>
<!--环境的os条件-->
<os>
<!--os的名字-->
<name>Linux</name>
<!--os的组-->
<family>root</family>
<!--os的体系-->
<arch>x64</arch>
<!--os的版本-->
<version>7</version>
</os>
<!--环境的file条件-->
<file>
<!--如果存在文件-->
<exists>/usr/local/xx.l</exists>
<!--如果不存在文件-->
<missing>/usr/local/yy.l</missing>
</file>
<!--jdk和os和file任一满足就会使用环境-->
<!--环境值-->
<property>
<!--变量名-->
<name>x</name>
<!--变量值-->
<value>y</value>
</property>
</activation>
<build>
</build>
</profile>
</profiles>
<!-- 3.项目仓库管理配置-->
<!--发现依赖和扩展的远程仓库列表-->
<repositories>
<!--远程仓库-->
<repository>
<!--远程仓库的标识-->
<id>r1</id>
<!--远程仓库的名字-->
<name>release</name>
<!--远程仓库的url-->
<url>http://sss.com</url>
<!--仓库的布局类型-->
<layout>default</layout>
<!--如何处理远程仓库发布版本的下载-->
<releases>
<!--是否下载该仓库的发布版本-->
<enabled>false</enabled>
<!--更新频率-->
<updatePolicy>never</updatePolicy>
<!--Maven验证构件失败时,如何处理(ignore:忽略;fail:失败;warn:警告;)-->
<checksumPolicy>warn</checksumPolicy>
</releases>
<!--如何处理远程仓库快照版本的下载-->
<snapshots>
<!--是否下载快照版本-->
<enabled>false</enabled>
<!--更新频率-->
<updatePolicy>never</updatePolicy>
<!--处理方式-->
<checksumPolicy>warn</checksumPolicy>
</snapshots>
</repository>
</repositories>
<!--插件的远程仓库列表,插件用于构建和报表-->
<pluginRepositories>
<pluginRepository>
<id>r2</id>
<name>xx</name>
<url>http://cc.xom</url>
<layout>default</layout>
<releases>
<enabled>false</enabled>
<updatePolicy>never</updatePolicy>
<checksumPolicy>warn</checksumPolicy>
</releases>
<snapshots>
<enabled>false</enabled>
<updatePolicy>never</updatePolicy>
<checksumPolicy>warn</checksumPolicy>
</snapshots>
</pluginRepository>
</pluginRepositories>
<!--5.项目报表信息配置-->
<!--描述产生报表的规范,执行"mvn site",报表就会运行.-->
<reporting>
<!--true:不包括默认报表-->
<excludeDefaults>true</excludeDefaults>
<!--产生的报表存放在哪里-->
<outputDirectory>.site</outputDirectory>
<!--报表插件和相关的配置-->
<plugins>
<!--报表插件-->
<plugin>
<!--报表插件的groupId-->
<groupId>org.apache.maven.plugins</groupId>
<!--报表插件的唯一符-->
<artifactId>maven-site-plugin</artifactId>
<!--报表插件的版本-->
<version>3.3</version>
<!--是否传播到子项目-->
<inherited>false</inherited>
<!--配置项-->
<configuration/>
<!--报表的多重规范-->
<reportSets>
<!--一个规范-->
<reportSet>
<!--id-->
<id/>
<!--产生报表时的配置-->
<configuration/>
<!--配置是否传播到子项目-->
<inherited/>
<!--这个规范用到了哪些报表-->
<reports/>
</reportSet>
</reportSets>
</plugin>
</plugins>
</reporting>
<!--6.项目分发配置-->
<!--项目分发配置,就是执行mvn deploy后将要执行的操作-->
<distributionManagement>
<!--部署项目产生的构建发布到远程仓库需要的信息-->
<repository>
<!--分配给快照的版本号(唯一)-->
<uniqueVersion>false</uniqueVersion>
<id>1</id>
<name>xx</name>
<url>ftp://xx.com</url>
<layout>default</layout>
</repository>
<!--构建的快照部署到哪里?默认部署到repository配置的仓库,或者默认仓库-->
<snapshotRepository>
<uniqueVersion>false</uniqueVersion>
<id>1</id>
<name>xx</name>
<url>ftp://ss.com</url>
<layout>default</layout>
</snapshotRepository>
<!--部署项目的网站需要的信息-->
<site>
<!--部署位置的唯一标识符-->
<id>xxx</id>
<!--部署位置的名称-->
<name>xxxx</name>
<!--部署位置的URL-->
<url>scp://svn.baidu.com</url>
</site>
<!--项目下载页面的URL,该元素的原因是:帮助定位不在仓库里的构件-->
<downloadUrl>http://www.baidu.com</downloadUrl>
<!--如果构件有了新的groupId,artifactId,那么在这里应该列出来-->
<relocation>
<groupId>xxxx</groupId>
<artifactId>xxxx</artifactId>
<version>xxx</version>
<message>xxxx</message>
</relocation>
<!--是否有效-->
<status>none</status>
</distributionManagement>
</project>
6. GAV软件定位坐标
GAV是指(GroupId,ArtifactId,Version)首字母的简写。
- GroupId:项目id,是区分当前项目和其他项目的唯一标志.
- ArtifactId:组件id,在当前项目内,是区分当前组件和其他组件的唯一标识.
- Version:版本号,对于同一个组件,有着不同的版本,这是区分一个组件不同版本的唯一标识。
举例:
这个依赖表示:
org.apache中的logging.log4j项目,这个项目中的log4j组件,版本是2.13.3版本。
版本号的意义
软件名称.主版本号.小版本号.阶段版本号.字母版本号
- 主版本号:软件重大功能新增和修改
- 小版本号:小功能的新增和修改
- 阶段版本号:bug修复
- 字母版本号:里程碑变更(alpha,正式开启开发,内测;beta,公测版本;rc,候选;stable,正在发型;release,r,ra发型版本;final,最终版本)
7. MVN命令与生命周期
7.1 MVN命令
-
mvn --version
查看maven的版本 -
mvn clean
清楚生成的class文件等,主要是清理target中的数据 -
mvn compile
编译源码,与mvn clean
刚好相反 -
mvn package
打包,将class,资源文件打入jar包或者war包 -
mvn tomcat:run
运行tomcat容器 -
mvn test
执行test单元测试,生成测试报告 -
mvn site
生成报表 -
mvn dependency:tree
分析依赖树,在用于解决依赖冲突时,非常有效 -
mvn install
下载依赖,更新依赖 -
mvn deploy
发布打包后的文件
不过,更多的是使用ide里面的图形化操作
7.2 Maven生命周期
生命周期:描述项目构建过程。也是预定义项目执行过程。降低项目管理的难度 。
- clean:项目构建之前清理
- default:项目编译和打包,安装,分发,部署。。
- site:项目报告,站点,发布
8. Maven项目构建
8.1 纯手工构建
这是Maven项目的结构
在ide中创建一个空的java工程,然后手工创建Maven项目的其他结构:
接着填充pom.xml
此时在命令行中就可以运行Maven的命令了:
或者像这样,一次性执行多个独立的命令
但是此时ide还是不识别pom.xml文件:
需要手动导入
导入完成后,ide就会识别这些文件了
8.2 模板构建
模板构建就更简单了,直接在创建模块或者项目时,选择maven就好了。
这些文件结构,相关的pom.xml文件的文件头,以及pom.xml文件的导入等等,都会一次性完成。
而且连依赖都可以直接选择好。
8.3 命令构建
9. 依赖范围
什么是依赖范围
依赖范围:依赖的jar包,在Maven的生命周期生效的范围。
有哪些依赖范围
作用范围主要包含这几个:
- compile:全部周期
- provided:编译和运行
- runtime:运行和打包
- test:测试
- system:与provided配合使用
为什么设置依赖范围
默认的依赖范围是全局的,也就是如果不写,就默认在全部的生命周期有效。
那么,这样不是很好吗?全部都能用,这样不是更方便吗?
不是,举个最常见的例子:
我们的spring mvc项目中需要指定servlet,在开发的时候,我们用到的是jar包的servlet。在开发完成后,需要打包成jar包或者war包,然后部署到tomcat容器或者Jboss容器中,进行部署。但是,Tomcat或者Jboss的就已经包含了servlet了,我们的jar包或者war也有servlet的话,不就出现冲突了吗。
有了依赖范围,我就可以设置,让打包的时候,不要将servlet打入发布包,这样就不会存在问题了。
10. 项目继承的依赖
父子项目:依赖的继承关系只会发生在父子项目之间。
父子项目:最顶层的项目是父项目,父项目下面的项目就是子项目。
子项目默认拥有父项目的依赖,如果子项目也做了依赖的配置,那么以子项目的为准。
父子项目关系是由pom.xml中的parent
标签说明。
有了父子项目的关系后,子项目就可以使用父项目的变量,配置,依赖等等。
同时在ide中也会标识出来。
注意:父项目的打包方式必须是pom方式。
11. 项目聚合的依赖
在开发中有一个思想:尽可能使用聚合,而不是继承。
项目依赖的继承,要求项目之间必须有父子关系,才能进行继承。
如果是祖孙项目,就不能继承。
相比来说,聚合关系比依赖关系更加灵活。
聚合关系的设置:是通过modules
标签设置的。
我们在聚合的父项目上设置了servlet依赖
但是在子项目上没有设置servlet依赖:
但是子项目依然可以使用servlet依赖中的类
聚合与继承的区别:
继承是子项目维护关系,子项目通过增加parent
标签维护。
聚合是被聚合项目维护关系,子项目不需要做任何操作。
如果顶层项目下有许多的下级项目,这些下级项目都需要依赖一个jar包。
而且决定将jar包放到了顶层项目中。
如果使用继承关系,需要在全部的下级项目中增加标签。
如果使用聚合关系,只需要在顶层项目中增加全部的下级项目。
从这方面来说,可能聚合比依赖更加的快捷,方便。
聚合和继承可以同时使用。
12. 项目常用插件
插件是一些普通的Maven命令的增强。
插件按照用途有生命周期插件,有容器插件,有依赖插件,部署插件,。。。
常用的有:resource,source,clean ,compile,tomcat,denpendenc,jar,build…
插件可以去Maven官网检索。
比如依赖相关的:
通过点击useage查看如何配置:
然后将给出的代码拷贝到自己的pom.xml中对应的位置即可。
使用
不过现在IDE很强大,基本上不再这么使用了。依赖分析,IDE比命令行更加直观。
13. 私有仓库
私有服务器
一方面可以加快依赖加载速度,另一方面,可以解决一些内部依赖的安全性。
搭建私有服务器有哪些解决方案:
- Apache Archiva
- JFrog Artifactory
- Sonatype Nexus
- …
私有服务器的架设
下载nexus.
Nexus官网文档下载与配置。
不过,得益于现在docker的发展,现在基本上常见的应用,都有对应的docker镜像。
所以,我们就不在重新搭建Nexus,而是直接启动最新的镜像。
打开docker-hub官网然后搜索nexus的镜像:
各种启动的场景,都给出了相关的启动的命令和相关的示例配置
所以,我们直接在服务器上启动一个容器:
这是两个命令,在第一个命令创建成功的基础上执行第二个命令。
第一个命令将在容器内创建一个文件夹,地址在根目录下。
第二个命令将宿主机的data文件夹挂载到容器内,我们刚刚创建的容器内的文件夹内。
结果报错了,查看日志,发现我们参数传递错误:
修改命令和参数,重新启动
- 表示创建了一个docker管理的存储
- 在容器内使用刚刚创建的存储
- 刚刚创建的存储,对应容器内的目录,在宿主机上存储在
/var/lib/docker/volumes
尝试访问:
登录
我们使用自动生成的密码登录
ok ,登录成功
私有服务器配置使用
仓库分为三种:proxy,group,hosted.
proxy代理仓库,group分组管理仓库,hosted本地发布仓库。
releases稳定版本发布
snapshots快照版本发布
我们创建一个仓库
然后选择maven2类型的仓库proxy类型的
我们选择使用用户名密码访问验证就行了,是一个代理仓库,目标是阿里云的仓库。
其他两种仓库的创建方式类似。
然后获取仓库的url地址,就可以使用了。
在代码中指定依赖仓库
配置发布仓库
增加了依赖后,刷新maven,然后我们的私服就会从阿里云的仓库同步我们的依赖
当然,发布我们自己的依赖,也是可以的。
发布之前,需要配置用户名和密码
要注意,这里面的server的id需要和配置的发布仓库Id保持一致。
发布仓库和验证信息是通过id进行匹配的。
然后发布
通过浏览器也能发现确实上传了
但是却只是上传到了快照仓库,却没有上传到稳定仓库。
想上传到稳定版本,也非常的简单,只需要将我们的版本号中的快照修改为稳定,即可
当我们的版本号从快照修改为稳定后,发布就会发布到稳定仓库中
14. 依赖冲突
14.1 项目依赖的直接冲突
如果我们的项目中依赖了两个不同的依赖,但是这两个依赖都依赖其他的依赖,而且这两个依赖的C,存在版本冲突
这样,在项目就需要两个版本的相同的依赖
我们依赖这样两个依赖
然后分析依赖,就会发现存在依赖冲突
就会发现1.1和1.1.1存在版本冲突。
poi依赖的是1.1版本
beanutils-core依赖1.1.1版本
一般情况下,依赖可以向后兼容,所以我们指定最新的版本就可以了。
所以,需要排除低版本的依赖。
此时就没有了冲突了
14.2 项目依赖的传递冲突
我们的项目依赖了A,但是A依赖了B和C,项目本身不依赖C
这样就存在了依赖冲突
我们首先创建A,B,C三个模块
然后先打包C
并且上传到私服中
A,B也打包上传。
不同的是A依赖了B,C
然后在D项目中依赖A
分析依赖树
我们排除依赖C
然后分析依赖树
此时在D项目中,就不会依赖C项目了。
15. 总结
到此为止,我们主要学习了Maven基础,Maven配置,Maven实战,Maven依赖等内容。
在Maven基础中,主要是Maven环境搭建,Maven目录结构分析,代码结构分析。
在Maven配置中,主要是仓库配置,pom.xml配置,和软件定位坐标。还有Maven命令与生命周期
在Maven实战中,主要是三种创建Maven项目的方式:手动创建,模板创建,和IDE创建。
在Maven依赖中,主要是Maven依赖范围,依赖的继承和聚合,创建私有仓库,最后是解决依赖冲突。
Maven慢慢的被gradle替代,但是Maven的思想和设计,永远不会过时。