Maven教程


前言

这篇文章是通过学习从网上找的 “尚学堂官网视频” 里面的 Maven 课程,为了加深记忆,方便查阅,特意写一篇博客。
本人水平有限,如有误导,欢迎斧正,一起学习,共同进步!


一、Maven是什么?

Maven是专门用于构建和管理Java相关项目的工具。Maven是基于POM(Project Object Model,项目对象模型)模式实现的。Maven 是跨平台的,这意味着无论是在 Windows 上,还是在 Linux 或者 Mac 上, 都可以使用同样的命令。他的优点有:项目标准化、方便统一管理jar包。项目标准化是指使用Maven管理的Java 项目都有着相同的项目结构;方便统一管理是指将全部的依赖都导入了本地仓库中,方便统一的管理。

二、Maven下载

官网网址:http://maven.apache.org/download.cgi

三、Maven仓库及配置

Maven 仓库是基于简单文件系统存储的,集中化管理 Java API 资源(构件)的一个服务。仓库中的任何一个资源,都有其唯一的坐标,根据这个坐标可以定义其在仓库中的唯一存储路径。坐标有三个部分构成:GroupId、ArtifactId、Version。如果一个部分不同那么表示的就是不同的 jar。Maven仓库分为本地仓库,远程仓库。其中远程仓库又分为中央仓库,镜像仓库。

1、本地仓库

本地仓库是开发者本地电脑中的一个目录,用于存储从远程仓库下载的构件(jar 包)。文件夹结构为 groupid 分级的文件夹/artifactid 文件夹/version 文件夹/包含 jar 包。默认的本地仓库是${user.home}/.m2/repository。

2、远程仓库

2.1、中央仓库

Maven的默认远程仓库就是中央仓库。Maven中央仓库是由 Maven 社区提供的仓库,其中包含了大量常用的库。中央仓库包含了绝大多数流行的开源Java构件,以及源码、作者信息、SCM、信息、许可证信息等。一般来说,简单的Java项目依赖的构件都可以在这里下载到。需要联网才能访问。

2.2、镜像仓库

镜像:如果仓库 A 可以提供仓库 B 存储的所有内容,那么就可以认为 A 是 B 的一个镜像。通俗的讲,镜像仓库是将中央仓库的全部资源,原封不动的拷贝一份放入自己本地。镜像仓库是在本地仓库无法获取资源的时候,直接访问镜像仓库。由于直接访问中央仓库会比较慢(中央仓库是国外的),所以一般将远程仓库配置成国内的镜像仓库,如阿里镜像。

3、仓库的访问优先级

本地仓库>远程仓库
先去本地仓库中查找这个文件,若本地仓库没有,就去远程仓库中下载,下载完了存储在本地仓库中,方便下次的使用。其中远程仓库也分为两种,远程仓库、镜像仓库。默认是中央仓库(国外网站),你可以修改配置文件中的仓库路径,一般换成阿里云的仓库,这就叫镜像仓库。原理是阿里云的仓库复制了中央仓库的全部文件,然后国内直接访问阿里云比直接访问国外的中央仓库速度要快。

4、配置Maven

修改settings.xml 文件来完成配置,settings.xml可以在Idea工具中的file->setting->Build,Execution,Deployment->Maven 来定位。
setting文件定位

4.1、配置本地仓库

修改settings.xml文件。将value的值换成你希望将jar存储的本机位置。内容如下:

	 <localRepository>D:\ruanjian\maven\cangku</localRepository>	

4.2、配置镜像仓库(远程仓库)

此时是将镜像仓库配置成阿里云的仓库。

  <mirrors>
    
	<mirror> 
		<id>alimaven</id> 				
		<name>aliyun maven</name> 
		<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
		<mirrorOf>central</mirrorOf> 
	</mirror>
    
  </mirrors>

4.3、配置jdk版本

这个可以配置也可以不配置,前面两个是一般都配置的。要是有需要的话,可以如下配置:

<profiles>
  <profile>
    <id>development</id>
    <activation>
      <jdk>1.7</jdk>
      <activeByDefault>true</activeByDefault>
    </activation>
    <properties>
      <maven.compiler.source>1.7</maven.compiler.source>
      <maven.compiler.target>1.7</maven.compiler.target>
      <maven.compiler.compilerVersion>1.7</maven.compiler.compilerVersion>
    </properties>
  </profile>
</profiles>

四、Maven的工程类型

1、Jar工程

创建一个 Java Project,在打包时会将项目打成 jar 包

2、War工程

创建一个 Web Project,在打包时会将项目打成 war 包。是一个web工程,发布在服务器上的工程,将全部的jar包打成一个war包,然后部署到tomcat中。

3、Pom工程

POM 工程是逻辑工程。用在聚合工程中,或者父级工程用来做 jar 包的版本控制。

五、Pom模型

1、依赖关系

依赖谁就是将谁的 jar 包添加到本项目中。可以依赖中央仓库的 jar,也可以依赖当前开发中其他项目打包后的 jar 包

1.1、依赖的传递性

依赖传递性是 Maven2.0 的新特性。假设你的项目依赖于一个 jar 包,而这个 jar 包又依赖于其他 jar 包。你不必自己去找出所有这些依赖,你只需要加上你直接依赖的 jar 包的 坐标,Maven 会隐式的把这些 jar 包间接依赖的库也加入到你的项目中。这个特性是靠解析从远程仓库中获取的依赖 jar 包的项目文件实现的。这些项目的所有依赖都会加入到项目中这就是依赖传递性。简单的说,A 依赖了 B ,那么当 C 依赖 A 的时候,会自动的将A、B都导入进来。

1.2、依赖相同资源的依赖原则

1.2.1、第一原则:最短路径有限原则

“最短路径优先”的意思是说,在项目的依赖关系树中,路径最短的版本会被使用。
在这里插入图片描述

1.2.2、第二原则:最先声明原则

那若是两个的依赖链路的长短一样的情况下,该怎么办呢,此时就用到了第二原则,最先声明原则。就是说,在依赖链路长度一样的情况下,在pom.xml当中,谁被先声明了,就优先解析谁。

在 maven2.0.8 及之前的版本中,这是不确定的,但是 maven2.0.9 开始,为了尽可能避免 构建的不确定性,maven定义了依赖调解的第二原则:第一声明者优先。在依赖路径长度相等的前提下,在 POM中依赖声明的顺序决定了谁会被解析使用。顺序最靠前的那个依赖优胜。

1.3、排除依赖

在特定的情况下,你可能想排除一部分依赖,这时你可以使用exclusions。比如说 A 依赖于 B 、C、D。但是你项目中只希望导入 B、C。可能是别的依赖已经导入了 D,或者其他原因,你不需要导入D,这时可以使用exclusions。需要注意的是,exclusion只能排除依赖,不能排除包含。若A 是依赖的 B ,那么可以用exclusion排除依赖;若A 里面中包含 B ,那么即使使用了exclusion,也不能排除。

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
	<exclusions> 
		<exclusion> 
			<groupId>org.springframework</groupId> 
			<artifactId>spring-aop</artifactId> 
		</exclusion>
	</exclusions>
</dependency>

1.4、依赖范围

1.4.1、scope属性可取值
1.4.1.1、compile

这是默认范围。如果没有指定,就会使用该依赖范围。表示该依赖在编译和运行时生效。在项目打包时会将该依赖包含进去。

1.4.1.2、provided

可以参与编译,测试,运行等周期,但是不会被打包到最终的 artifact 中。典型的例子是 servlet-api ,编译和测试项目的时候需要该依赖,但在项目打包的时候,由于容器已经提供,就不需要 Maven 重复的引入一遍(如:servlet-api)

1.4.1.3、runtime

runtime 范围表明编译时不需要生效,而只在运行时生效。典型的例子是 JDBC 驱动实现,项目主代码的编译只需要 JDK 提供 JDBC 接口,只有在执行测试或者运行项目的时候需要实现上述接口的具体 JDBC 驱动。

1.4.1.4、system

如果你有些依赖的 jar 包没有 Maven 坐标,它完全不在 Maven 体系中,这时候你可以把它下载到本地磁盘,然后通过 system 来引用。
不推荐使用 system,因为一个项目的 pom.xml 如果使用了 scope 为 system 的 depend 后,会导致传递依赖中断,即所有其他依赖本项目的项目都无法传递依赖了。

1.4.1.5、test

test 范围表示使用此范围的依赖,只在编译测试代码和运行测试的时候需要,应用的正常运行不需要此类依赖。典型的例子就是 JUnit ,它只有在编译测试代码及运行测试的时候才需要。

1.4.2、依赖管理dependencyManagement

Maven 提供了一个机制来集中管理依赖信息,叫做依赖管理元素dependencyManagement。一般是父工程中使用 dependencyManagement 配合着 properties 来使用。properties 内可以写任意的 key ,然后 value 就写对应的版本。这样以后直接在父工程中写版本信息,子工程中直接写 groupid、artifictid 就行,不用写 version,方便了管理。dependencyManagement 和 dependencies 的区别是: dependencyManagement 不会直接将依赖注入到项目中,只是定义;而 dependencies 会直接将依赖注入到项目中。dependencyManagement 下包含 dependencies 。

2、继承关系

Maven 中的继承跟 Java 中的继承概念一样,需要有父项目以及子项目。不过不同的是若是父工程中用dependencyManagement标签,则子工程不会自动引入dependencyManagement中的依赖;而Java中的继承,子类直接拥有了父类的属性。

2.1、继承的优点

1) 依赖或插件的统一管理(在 parent 中定义,需要变更 dependency 版本时,只需要修改一处)。
2) 代码简洁(子 model 只需要指定 groupId,artifactId 即可)。
3) dependencyManagement 是 “ 按 需 引 入 ” , 即 子 model 不会继承 parent 中 dependencyManagement 所有预定义的dependency。

2.2、Maven中的多继承

Maven的继承采用的也是单继承,就是一个子工程,只能有一个父工程。但是某些特定情况,我们需要从多个项目中继承依赖时,有两种方案:①在子工程内使用parent标签配合dependencyManagement标签②在子工程内直接使用dependencyManagement标签。

方式1解释:子工程内的第一个父工程的依赖,仍用parent标签;当你想从第二个项目中引用时,在子工程内添加dependencyManagement,dependencyManagement标签内的dependencies内的dependency可以有多个,需要继承几个父工程,就添加几个dependency标签。dependency内需要添加 type 标记,值为 pom。添加 scope 标记,值为 import
方式2解释:直接在子工程内使用dependencyManagement

	<parent>
        <groupId>com</groupId>
        <artifactId>parent</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <groupId>com</groupId>
    <artifactId>child</artifactId>
    <version>1.0-SNAPSHOT</version>


<!--    maven要想实现多继承的话,有两种方式:-->
<!--    第一种:(子工程中,同时又parent、dependencyManagement)
            parent标签配合dependencyManagement标签
            parent标签内的依赖,是第一个父工程的依赖;
            dependencyManagement里面的dependency,是第二个父工程的依赖
            dependencyManagement只能有一个,但是他里面的dependency可以是多个,
            需要依赖多个父工程,就创建多个dependency标签即可
        第二种:(子工程中,直接用dependencyManagement,若依赖多个父工程,则创建多个dependency)
            直接用dependencyManagement标签

-->
    <dependencyManagement>
        <dependencies>

<!--            要依赖的第一个父工程-->
            <dependency>
                <groupId>com</groupId>
                <artifactId>parent_b</artifactId>
                <version>1.0-SNAPSHOT</version>
<!--                下面这俩也是必须的,不能少的。-->
                <type>pom</type>
                <scope>import</scope>
            </dependency>

<!--            要依赖的,第二个父工程-->


        </dependencies>
    </dependencyManagement>

3、聚合关系

为了便于项目统一管理,引入了聚合的概念。聚合包含了继承的特性。 聚合时多个项目的本质还是一个项目。这些项目被一个大的父项目包含。且这时父项目 类型为 pom 类型。同时在父项目的 pom.xml 中出现表示包含的所有子模块。聚合是为了方便管理,而继承是为了减少重复配置。

3.1、删除聚合模块的步骤

a.右键模块,remove module
在这里插入图片描述b.右键模块,delete
在这里插入图片描述

c.删除最外层项目pom文件中的model
在这里插入图片描述

六、Maven中的常见插件

1、内置插件

Maven 自身拥有很多内置插件,每一个内置插件都代表了 Maven 的一种行为。Maven 在管理项目整个生命周期时,在不同的阶段处理的过程都是使用插件来具体完成。如:构建项目时使用构建插件、编译项目时使用编译插件、清除构建使用清除构建的插件、测试项目时使用测试插件、打包时使用资源拷贝插件以及打包插件。 我们可以在不同阶段使用 Maven 中的不同命令来触发不同的插件来执行不同的工作。换言之,Maven 的插件是需要依赖命令来执行的
Maven 在管理插件时也是通过坐标的概念和管理依赖的方式相同,通过坐标来定位唯一的一个插件。 在一般情况下,我们不需要额外配置 Maven 的内置插件,除非我们需要对插件做额外配置时才需要配置内置插件。如果我们重新配置了内置插件,那么则以我们配置的为主。 Maven 的插件配置需要在 pom.xml 文件中的标签中使用来配置。 现在在很多的 IDE 中都已经把 Maven 的常用命令通过界面中的按钮来体现,我们只要点击相应的按钮就等同于执行了相应的命令。Lifecycle中相当于执行了命令,一定能执行,但是Plugins当中有一部分需要配置插件才能执行。
在这里插入图片描述

1.1、配置编译插件

1.1.1、在settings.xml中配置全文编译插件

Maven的settings.xml,是统一的配置,位置在你的Maven安装位置,或者是idea中内置的Maven的settings.xml的位置。

<profile> 
	<!-- 定义的编译器插件 ID,全局唯一 --> 
	<id>jdk-1.8</id> 
	<!-- 插件标记,activeByDefault 默认编译器,jdk 提供编译器版本 --> 
	<activation> 
		<activeByDefault>true</activeByDefault>
		<jdk>1.8</jdk> 
	</activation>
	<!-- 配置信息 source-源信息,target-字节码信息,compilerVersion-编译过程版 本 --> 
	<properties> 
		<maven.compiler.source>1.8</maven.compiler.source> 
		<maven.compiler.target>1.8</maven.compiler.target> 
		<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion> 
	</properties> 
</profile>
1.1.2、在pom.xml当中配置局部编译插件

是单个项目(你要配置的项目)的pom.xml的位置。
解释:
在 build 标签下配置 plugins 标签,piugins 标签内可以有多个 plugin 标签,一个 plugin 标签就代表着一个插件,plugin 标签内部的 groupId、artifactId、versioin 代表着这个插件的坐标,configuration 代表着是对这个插件的配置,只针对于当前plugin的配置。

	<!-- 在pom。xml当中配置局部插件-->
    <build>
        <plugins>
			<!-- 配置编译插件-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
				<!-- 这个configuration代表着,是给这个plugin的配置-->
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
		</plugins> 
	</build>

1.2、资源拷贝插件

Maven 在打包时,默认只将 src/main/resources 下的文件拷贝到项目中并做打包处理,而非resources目录下的文件在打包时并不会添加到项目中。在某些情况下(比如说Mybatis的mapper文件),当我们希望将 src/main/java 下的某些文件也一起打包时,可以配置资源拷贝插件,指定打包时一起打包的文件的位置。值得注意的是,若你不专门配置资源拷贝插件,则默认将src/main/resources 下的文件打包;若你配置了资源路径,则只打包你配置的路径,而不打包默认的 src/main/resources 包下的文件。就跟 Java 的构造方法一样,你不提供,Java给你默认的;你提供了,他就按你的,不给你默认的。
解释:
在 build 标签下配置 resources 标签,一个 resources 标签中可以有多个 resource 标签,resource 标签下的 directory 标签表示是哪个文件夹,includes 标签下可以有多个 include 标签, include 表示哪些文件需要被打包处理。

<!--    在pom。xml当中配置局部插件-->
    <build>
<!--        资源拷贝插件,当你不配置时,打包install时默认将resources下的文件跟着打包;
            但是你一旦配置了,就按你配置的资源路径打包,不在将默认的resources下的文件打包了
            就跟构造方法一样,你不写,他给你默认提供一个;你写了,他就用你的,不用默认的。
            一个resources下可以有多个resource标签
-->
        <resources>
<!--            这个是配置的java下的xml文件能被打包-->
            <resource>
                <directory>src/main/java</directory>
<!--                这个意思是,将src/main/java目录下的全部的子文件的。xml。properties打包-->
                <includes>
                    <include>**/*.xml</include>
                    <include>**/*.properties</include>
                </includes>
            </resource>

<!--            这个是将默认的resource目录下的文件能被打包-->
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.xml</include>
                    <include>**/*.properties</include>
                </includes>
            </resource>
        </resources>

    </build>

2、扩展插件

2.1、Tomcat插件

Tomcat 插件是 Maven 的扩展插件,其作用是为基于 Maven 开发的 Web 项目提供一个内置的 Tomcat 支持,这样我们在开发阶段可以不在依赖外部的 Tomcat 来运行 Web 项目,该插件目前使用的 Tomcat 版本为 Tomcat7。该插件的作用很强大,除了提供了 Tomcat 以外,还可以通过该插件实现项目的远程热部署。
解释:
一样的道理,在 build 标签下有 plugins 标签,plugins 标签下有 plugin 标签。plugin 标签内的 groupId、artifactId、version 代表着这个插件的坐标,configuration 代表着对这个插件单独的配置。

<plugin>
    <groupId>org.apache.tomcat.maven</groupId>
    <artifactId>tomcat7-maven-plugin</artifactId>
    <version>2.2</version>
    <configuration>
		<!-- 配置 Tomcat 监听端口 -->
		<port>8080</port>
		<!-- 配置项目的访问路径(Application Context) -->
		<path>/</path>
    </configuration>
</plugin>

2.2、插件管理

类似于依赖的父子关系 dependencyManagement、dependency 。插件也有对应的父子关系 pluginManagement、plugin 。同样是在父工程中,定义插件,在子工程中,具体的配置,使用。

父工程中:

<pluginManagement> 
	<plugins> 
		<plugin> 
			<groupId>org.apache.tomcat.maven</groupId> 
			<artifactId>tomcat7-maven-plugin</artifactId> 
			<version>2.2</version> 
		</plugin> 
		
	</plugins> 
</pluginManagement>

子工程中:

<plugin> 
	<groupId>org.apache.tomcat.maven</groupId> 
	<artifactId>tomcat7-maven-plugin</artifactId> 
	<configuration> 
		<!-- 配置 Tomcat 监听端口 --> 
		<port>8080</port> 
		<!-- 配置项目的访问路径(Application Context) --> 
		<path>/</path> 
	</configuration> 
</plugin>

七、Maven常用命令

1、clean

清除已编译信息,删除工程中的 target 目录

2、validate

验证项目是否正确

3、compile

只编译。 javac 命令

4、test

用于执行项目的测试。如果在 test 目录下含有测试代码,那么 Maven 在执行 install 命令会先去执行 test 命令将所有的 test 目录下的测试代码执行一遍,如果测试代码执行失败,那么 instatll 命令将会终止。

5、package

打包。包含编译、打包两个功能。

6、verify

运行任何检查,验证包是否有效且达到质量标准。

7、install

本地安装,包含编译、打包、安装到本地仓库。
编译 - javac
打包 - jar ,将 java 代码打包为 jar 文件
安装到本地仓库 - 将打包的 jar 文件,保存到本地仓库目录中。

8、site

项目站点文档创建的处理,该命令需要配置插件。

9、deploy

远程部署命令。


总结

相比于 Gradle ,Maven 可能在引用时更加冗余一些。不过 Gradle 的版本兼容的问题让人更加难以接受。因此,使用 Maven 亦或者 Gradle 还是需要我们开发人员来自己抉择。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值