Maven笔记

2019-01-27  本文已影响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(前三个为必选),这些元素的含义:

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

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用户使用;私服的特性有:

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>

子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继承了如下元素:

参考:

上一篇下一篇

猜你喜欢

热点阅读