美文网首页
Maven笔记

Maven笔记

作者: 斯文遮阳 | 来源:发表于2019-01-27 17:14 被阅读0次

一、Maven基础

1.1 Maven功能

Maven能帮助我们干什么?它主要有两个功能:

  1. 依赖管理(jar包管理):在开发过程中需要大量jar包,我们只需要在Maven的主配置文件中添加相应jar包的标识,他就会自动下载相应jar包,不用我们自己去到处搜索jar包了
  2. 构建项目:我们可以通过Maven构建项目,它定义了一套生命周期,规范了构建流程,可以一键构建,提高了大型项目的开发效率
Maven构建流程

1.2 POM文件

每个maven项目都会有一个pom.xml文件, 在这个文件里面是通过坐标来唯一标识Maven依赖,坐标元素包括groupId、artifactId、version、packaging、classifier(前三个为必选),这些元素的含义:

  • groupId:定义当前Maven项目所属的实际项目
  • artifactId:定义实际项目中的一个Maven模块
  • version:定义Maven项目当前所处的版本
  • packaging:定义Maven项目打包方式, 通常打包方式与所生成构件扩展名对应,包括:jar(默认)、war、pom、maven-plugin等
  • classifier:用来帮助定义构建输出的一些附属构件(如javadoc、sources),不能直接定义项目的classifier,须有插件的帮助

这里提一下version版本的两种类型:

  • SNAPSHOT:泛指以-SNAPSHOT为结尾的版本号,用于保存开发过程中的不稳定版本号,在mvn deploy时会主动发布到快照版本号库中;而使用快照版本号的模块,在不更改版本号的情况下直接编译打包时,maven会自己主动从镜像server上下载最新的快照版本号
  • RELEASE:所有非-SNAPSHOT结尾的版本号则都被认定为RELEASE版本,即正式版,在mvn deploy时会自己主动发布到正式版本号库中;而使用正式版本号的模块在不更改版本号的情况下,编译打包时假设本地已经存在该版本号的模块则不会主动去镜像server下载

1.3 Maven依赖

Maven最著名的就是Maven的依赖管理,它使得我们不必再到开源项目的官网一个个下载开源组件,然后再放入classpath。一个依赖声明可以包含如下元素:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>4.2.7.RELEASE</version>

    <type>jar</type>
    <scope>compile</scope>
    <optional>false</optional>
    <exclusions>
        <exclusion>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
        </exclusion>
    </exclusions>
</dependency>

依赖范围Scope

Scope 是用来限制Dependency的作用范围的, 他会影响maven项目在各个生命周期时导入的package的状态。常用scope见下图:

依赖范围Scope

依赖传递性

比如下图有Maven项目junit,项目commons-logging依赖junit,项目spring-core依赖commons-logging,项目my-app依赖spring-core;那么我们可以说my-app依赖junit;我们执行项目my-app时,会自动把spring-core、commons-logging、junit都下载导入到my-app项目的jar包文件夹中,这就是依赖的传递性。

依赖传递示例

假如现在不想执行my-app时把junit下载进来,那么我们可以用<exclusions>标签。

依赖调节的原则:

  • 如果依赖路径的长度不同,则短路优先
  • 依赖路径长度相同情况下,则先声明优先

依赖分析

mvn dependency:list
查看当前项目的已解析依赖
mvn dependency:tree
查看当前项目的依赖树
mvn dependency:analyze
自动化分析当前项目的依赖

IDEA可以安装一个很方便的插件Maven Helper来帮助我们进行依赖管理、排包等操作。

1.4 Maven仓库

Maven仓库只有两大类:

  1. 本地仓库:Maven在本地存储构件的地方;
  2. 远程仓库:在远程仓库中又分成了2种:
    a. 中央仓库:中央仓库是默认的远程仓库,maven在安装的时候,自带的就是中央仓库的配置;
    b. 私服:私服是一种特殊的远程仓库,它是架设在局域网内的仓库服务,私服代理广域网上的远程仓库,供局域网内的Maven用户使用;私服的特性有:
  • 节省外网带宽
  • 加速Maven构建
  • 部署第三方构件
  • 提高稳定性,增强控制
  • 降低中央仓库负荷

1.5 常用Maven指令

mvn clean compile
清理+编译
mvn clean test
清理+编译+执行测试
mvn clean package
清理+编译+打包
mvn clean install
清理+编译+打包+放置本地仓库
mvn archetype:generate
创建项目骨架

二、Maven生命周期和插件

Maven生命周期

Maven有三个内置的生命周期:default、clean和site。在default的生命周期处理你的项目部署,在clean的生命周期处理项目的清理,在site的生命周期处理你的项目站点文档的创建。

Maven生命周期

Maven插件

Maven本身是一个框架,实际的任务都由插件完成。插件与生命周期阶段绑定,用户通过指定生命周期阶段就能够隐式的通过插件执行任务,如:$mvn compiler:compile,冒号前是插件前缀,后面是该插件目标(即: maven-compiler-plugin的compile目标),而该目标绑定了default生命周期的compile阶段。

Maven 默认插件目标绑定源码:

<component> 
  <role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role>  
  <role-hint>jar</role-hint>  
  <implementation>org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping</implementation>  
  <configuration> 
    <lifecycles> 
      <lifecycle> 
        <id>default</id>  
        <!-- START SNIPPET: jar-lifecycle -->  
        <phases> 
          <process-resources>org.apache.maven.plugins:maven-resources-plugin:2.6:resources</process-resources>  
          <compile>org.apache.maven.plugins:maven-compiler-plugin:3.1:compile</compile>  
          <process-test-resources>org.apache.maven.plugins:maven-resources-plugin:2.6:testResources</process-test-resources>  
          <test-compile>org.apache.maven.plugins:maven-compiler-plugin:3.1:testCompile</test-compile>  
          <test>org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test</test> 
        </phases>  
        <!-- END SNIPPET: jar-lifecycle --> 
      </lifecycle> 
    </lifecycles> 
  </configuration> 
</component>

自定义绑定

除了内置绑定以外,用户还能够自定义将某个插件目标绑定到生命周期的某个阶段上。如创建项目的源码包,maven-source-plugin插件的jar-no-fork目标能够将项目的主代码打包成jar文件,可以将其绑定到verify阶段上:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.0.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

其中executions下每个execution子元素可以用来配置执行一个任务。

自定义插件开发

参考:https://blog.csdn.net/zjf280441589/article/details/53044308/

三、聚合与继承

Maven的聚合特性(aggregation)能够使项目的多个模块聚合在一起构建,而继承特性(inheritance)能够帮助抽取各模块相同的依赖、插件等配置,在简化模块配置的同时,保持各模块一致。

例如,父POM:

<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.my.app</groupId>
    <artifactId>appName</artifactId>
    <packaging>pom</packaging>
    <version>1.0.0.SNAPSHOT</version>

    <modules>
        <module>appName-client</module>
        <module>appName-core</module>
        <module>appName-web</module>
    </modules>

    <properties>
        <finalName>appName</finalName>
        <warName>${finalName}.war</warName>
        <spring.version>4.0.6.RELEASE</spring.version>
        <junit.version>4.12</junit.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <warExplodedDirectory>exploded/${warName}</warExplodedDirectory>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-beans</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>${spring.version}</version>
            </dependency>

           <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-source-plugin</artifactId>
                    <version>3.0.0</version>
                    <executions>
                        <execution>
                            <id>attach-sources</id>
                            <phase>verify</phase>
                            <goals>
                                <goal>jar-no-fork</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>
  • packaging: pom,否则无法聚合构建
  • modules: 实现聚合的核心,module值为被聚合模块相对于聚合POM的相对路径,离开聚合POM也能够独立构建(注: 模块所处目录最好与其artifactId一致)
  • dependencyManagement: 能让子POM继承父POM的配置的同时,又能够保证子模块的灵活性:在父POMdependencyManagement元素配置的依赖声明不会实际引入子模块中,但能够约束子模块dependencies下的依赖的使用(子模块只需配置groupId与artifactId)
  • pluginManagement: 与dependencyManagement类似,配置的插件不会造成实际插件的调用行为,只有当子POM中配置了相关plugin元素,才会影响实际的插件行为

子POM:

<?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">

    <parent>
        <groupId>com.my.app</groupId>
        <artifactId>appName</artifactId>
        <version>1.0.0.SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>appName-client</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

可以看到,子POM中并未定义模块groupId与version,这是因为子POM默认会从父POM继承了如下元素:

  • groupId、version
  • dependencies
  • developers and contributors
  • plugin lists (including reports)
  • plugin executions with matching ids
  • plugin configuration
  • resources

参考:

相关文章

  • maven笔记-下载和setting设置

    maven笔记-下载和setting设置 maven官方网站:http://maven.apache.org/ 下...

  • Maven备忘

    Maven 笔记 https://www.yiibai.com/maven/enable-proxy-settin...

  • maven学习笔记

    maven学习笔记 2016年1月6日 一、maven安装 windows下maven安装安装maven前,首先要...

  • 关于 maven

    慕课网《项目管理利器——maven》笔记 项目管理利器 maven maven 是基于项目对象模型(POM),可以...

  • to Learn list

    maven B 笔记 spring IOC docBspring 笔记spring 常用注解 spring AOP...

  • <JavaWeb>Maven简介

    笔记总结自网易云课堂Maven课程 什么是Maven Maven是由Apache基金会出品的,使用JAVA编写的开...

  • Maven学习笔记

    阅读《Maven实战》许晓斌的一些笔记,便于自己和道友查阅 maven依赖 maven具有传递性依赖,比如 A 依...

  • springboot 01 Getting started

    Maven配置笔记Maven两种实现方式1. 使用parent,项目继承至 spring-boot-starter...

  • 自动化构建工具Maven

    该心得全部来源于菜鸟教程-maven以及尚硅谷Java视频教程_Maven的学习过程笔记。 Maven:一个纯Ja...

  • 跟着张博学习给开源项目修bug

    本文为硬核空间张博视频笔记 给maven修bug:maven3.6.1不能成功编译kotlin模块 https:/...

网友评论

      本文标题:Maven笔记

      本文链接:https://www.haomeiwen.com/subject/zingjqtx.html