preface

Maven is the most popular build system for projects and is indispensable for Java-related development. There is another module management tool, Grade, on the rise, but most companies still use Maven

  • Maven and Maven’s repository
  • Maven command and build life cycle
  • Maven project pom. XML file details
  • How does Maven transfer dependencies and remove dependencies
  • Aggregation and inheritance of Maven
  • MVN Example

Pay attention to the public account, communicate together, wechat search: sneak forward

Maven and Maven’s repository

Maven repositories are used to store jars managed by Maven. There are two types: local warehouse and central warehouse

  • Local repository: Maven’s local repository of Jar packages
  • Maven central Repository: A remote repository officially provided by Maven. Maven central Repository is a repository provided by the Maven community that contains a large number of commonly used libraries. The central repository contains most of the popular open source Java artifacts
  • Remote repository: Maven also cannot find dependent files in the central repository, and it stops the build process and prints error messages to the console. To avoid this, Maven provides the concept of a remote repository, a developer’s custom repository that contains the required code base or jar files used in other projects

Maven command and build life cycle

phase To deal with describe
validate Verify the project Verify that the project is correct and that all necessary information is available
compile compiling Source code compilation is completed at this stage
test test Run the tests using an appropriate unit testing framework, such as JUnit.
package packaging Create JAR/WAR packages as mentioned in the pom.xml definition
verify check The results of integration tests are checked to ensure that quality is met
install The installation Install packaged items to a local repository for use by other projects
deploy The deployment of Copy the final project package to a remote repository to share with other developers and projects

  • When a phase is invoked through the Maven command, for examplemvn compile, and all phases before and including this phase are executed
  • Maven also has a clean command that removes all files generated during the last build
  • Often used in build environmentsmvn clean deployCommand to clear, build, and deploy items to a remote repository

Maven project pom. XML file details

<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.0http://maven.apache.org/maven-v4_0_0.xsd">     
    <!--父项目的坐标-->    
    <parent>  
        <artifactId/> <!--被继承的父项目的构件标识符-->    
        <groupId/>  <!--被继承的父项目的全球唯一标识符-->      
        <version/>  <!--被继承的父项目的版本-->    
        <!-- 父项目的pom.xml文件的相对路径-->    
        <relativePath/>    
    </parent>    
    <!--声明项目描述符遵循哪一个POM模型版本。模型本身的版本很少改变-->       
    <modelVersion>4.0.0</modelVersion>     
    <!--项目的全球唯一标识符,通常使用全限定的包名区分该项目和其他项目。并且构建时生成的路径也是由此生成, 如com.ex.app生成的相对路径为:/com/ex/app-->     
    <groupId>com.ex.app</groupId>     
    <!-- 构件的标识符,它和group ID一起唯一标识一个构件-->     
    <artifactId>erhuowang-maven2</artifactId>     
    <!--项目产生的构件类型,例如jar、war、ear、pom。插件可以创建他们自己的构件类型-->     
    <packaging>war</packaging>     
    <!--项目当前版本,格式为:主版本.次版本.增量版本-限定版本号-->     
    <version>1.0-SNAPSHOT</version>     
    <!--项目的名称, Maven产生的文档用-->     
    <name>erhuo-maven</name>     
    <!--项目主页的URL, Maven产生的文档用-->     
    <url>http://erhuowang.cn</url>     
    <!-- 项目的详细描述-->     
    <description>A maven project to study maven.</description>     
    <!-- 描述了这个项目构建环境中的前提条件。 --> 
    <prerequisites> 
        <!-- 构建该项目或使用该插件所需要的Maven的最低版本 --> 
        <maven></maven> 
    </prerequisites>
------------------------------------------------------------------------------------     
    <!--该元素描述了项目相关的所有依赖。 这些依赖组成了项目构建过程中的一个个环节。-->    
    <dependencies>     
      <dependency>    
        <!--依赖的group ID-->    
        <groupId>org.apache.maven</groupId>     
        <!--依赖的artifact ID-->    
        <artifactId>maven-artifact</artifactId>     
        <!--依赖的版本号。 在Maven 2里, 也可以配置成版本号的范围。-->    
        <version>3.8.1</version>     
        <!-- 依赖类型,默认类型是jar。它通常表示依赖的文件的扩展名,但也有例外。一个类型可以被映射成另外一个扩展名或分类器。类型经常和使用的打包方式对应, 尽管这也有例外。一些类型的例子:jar,war,ejb-client和test-jar。如果设置extensions为 true,就可以在 plugin里定义新的类型。所以前面的类型的例子不完整。-->    
        <type>jar</type>    
        <classifier></classifier>    
        <!--依赖范围。在项目发布过程中,帮助决定哪些构件被包括进来。欲知详情请参考依赖机制。    
            - compile :默认范围,用于编译      
            - provided:类似于编译,但支持你期待jdk或者容器提供,类似于classpath      
            - runtime: 在执行时需要使用      
            - test:    用于test任务时使用      
            - system: 需要外在提供相应的元素。通过systemPath来取得      
            - systemPath: 仅用于范围为system。提供相应的路径      
            - optional:   当项目自身被依赖时,标注依赖是否传递。用于连续依赖时使用-->     
        <scope>test</scope>       
        <!--当计算传递依赖时, 从依赖构件列表里,列出被排除的依赖构件-->    
        <exclusions>    
         <exclusion>     
                <artifactId>spring-core</artifactId>     
                <groupId>org.springframework</groupId>     
            </exclusion>     
        </exclusions>       
        <!--可选依赖,如果你在项目B中把C依赖声明为可选,你就需要在依赖于B的项目(例如项目A)中显式的引用对C的依赖。可选依赖阻断依赖的传递性。-->     
        <optional>true</optional>    
     </dependency>    
    </dependencies>  
----------------------------------------------------------------------------------------------
    <build>    
      <!--该元素设置了项目源码目录,当构建项目的时候,构建系统会编译目录里的源码。该路径是相对于pom.xml的相对路径。-->    
      <sourceDirectory/>    
      <scriptSourceDirectory/> <!--绝大多数情况下,该目录下的内容 会被拷贝到输出目录(因为脚本是被解释的,而不是被编译的)。-->      
      <testSourceDirectory/>   <!--该元素设置了项目单元测试使用的源码目录。该路径是相对于pom.xml的相对路径。-->     
      <outputDirectory/>     <!--被编译过的应用程序class文件存放的目录。--> 
      <testOutputDirectory/>  <!--被编译过的测试class文件存放的目录。-->       
      <!--使用来自该项目的一系列构建扩展-->    
      <extensions>     
           <extension>   <!--描述使用到的构建扩展。-->      
            <groupId/>   <!--构建扩展的groupId-->   
            <artifactId/> <!--构建扩展的artifactId-->  
            <version/> <!--构建扩展的版本-->       
           </extension>    
      </extensions>    
      <!--当项目没有规定目标(Maven2 叫做阶段)时的默认值-->    
      <defaultGoal/>    
      <!--这个元素描述了项目相关的所有资源路径列表,例如和项目相关的属性文件,这些资源被包含在最终的打包文件里。-->    
      <resources> <!--这个元素描述了项目相关或测试相关的所有资源路径-->    
          <resource>  <!-- 描述了资源的目标路径。该路径相对target/classes目录-->    
            <targetPath/>    
            <filtering/> 
            <directory/>   <!--描述存放资源的目录,该路径相对POM路径-->   
            <includes/> <!--包含的模式列表,例如**/*.xml.-->    
            <excludes/> <!--排除的模式列表,例如**/*.xml-->     
            </resource>    
      </resources>    
      <!--这个元素描述了单元测试相关的所有资源路径,例如和单元测试相关的属性文件。-->    
      <testResources>    
         <!--这个元素描述了测试相关的所有资源路径-->    
         <testResource></testResource>    
      </testResources>    
      <targetPath/>
      <filtering/>
      <directory/> <!--构建产生的所有文件存放的目录-->    
          <includes/><excludes/>    
      <directory/> 
      <finalName/> <!--产生的构件的文件名,默认值是${artifactId}-${version}。-->    
      <!--当filtering开关打开时,使用到的过滤器属性文件列表-->    
      <filters/>    
      
       <!--使用的插件列表-->    
      <plugins>    
        <!--参见build/pluginManagement/plugins/plugin元素-->    
        <plugin> </plugin>    
      </plugins>  
      
      <!--子项目可以引用的默认插件信息。该插件配置项直到被引用时才会被解析或绑定到生命周期。给定插件的任何本地配置都会覆盖这里的配置-->    
      <pluginManagement>  
           <plugins>  
               <!--plugin元素包含描述插件所需要的信息。-->    
               <plugin>    
                  <groupId/>   <!--插件在仓库里的group ID--> 
                  <artifactId/> <!--插件在仓库里的artifact ID-->  
                  <version/>   
                  <extensions/>    
                  <executions> <!--在构建生命周期中执行一组目标的配置。每个目标可能有不同的配置。-->   
                    <execution> <!--execution元素包含了插件执行需要的信息--> 
                      <id/>  <!--执行目标的标识符,用于标识构建过程中的目标,或者匹配继承过程中需要合并的执行目标--> 
                      <phase/> <!--绑定了目标的构建生命周期阶段,如果省略,目标会被绑定到源数据里配置的默认阶段-->      
                      <goals/>  <!--配置的执行目标-->    
                      <inherited/>    <!--配置是否被传播到子POM-->    
                      <configuration/> <!--作为DOM对象的配置-->     
                    </execution>    
                  </executions>    
                  <!--项目引入插件所需要的额外依赖-->    
                  <dependencies>    
                   <!--参见dependencies/dependency元素-->    
                   <dependency>    
                    ......    
                   </dependency>    
                  </dependencies>           
                  <!--作为DOM对象的配置-->    
                  <configuration/>    
               </plugin>    
           </plugins>    
      </pluginManagement>    
    </build>    
 -----------------------------------------------------------------------------------
    <!--在列的项目构建profile,如果被激活,会修改构建处理-->    
    <profiles>    
      <!--根据环境参数或命令行参数激活某个构建处理-->    
      <profile>    
       <id/>      
       <activation>    
        <!--profile默认是否激活的标志-->    
        <activeByDefault/> 
        <jdk/>jdk版本,如:1.8</jdk>    
        
        <!--当匹配的操作系统属性被检测到,profile被激活。os元素可以定义一些操作系统相关的属性。-->
        <!--如果Maven检测到某一个属性(其值可以在POM中通过${名称}引用),其拥有对应的名称
        值,Profile就会被激活。如果值字段是空的,那么存在属性名称字段就会激活profile,
        否则按区分大小写方式匹配属性值字段-->    
        <property> 
          <name>mavenVersion</name> <!--激活profile的属性的名称-->       
          <!--激活profile的属性的值-->    
          <value>2.0.3</value>    
        </property>    
        <!--提供一个文件名,通过检测该文件的存在或不存在来激活profile。missing检查文件是否存在,如果不存在则激活 -->    
        <file>    
         <!--如果指定的文件存在,则激活profile。-->    
         <exists>/usr/local/workspace/</exists>    
         <!--如果指定的文件不存在,则激活profile。-->    
         <missing>/usr/local/workspace/</missing>    
        </file>    
       </activation>    
       <!--构建项目所需要的信息。参见build元素-->    
       <build>    
            <defaultGoal/>    
            <resources>    
             <resource>    
              <targetPath/><filtering/><directory/><includes/><excludes/>    
             </resource>    
            </resources>    
            <testResources>    
             <testResource>    
              <targetPath/><filtering/><directory/><includes/><excludes/>    
             </testResource>    
            </testResources>    
            <directory/><finalName/><filters/>    
            <pluginManagement>    
             <plugins>    
              <!--参见build/pluginManagement/plugins/plugin元素-->    
              <plugin>    
               <groupId/><artifactId/><version/><extensions/>    
               <executions>    
                <execution>    
                 <id/><phase/><goals/><inherited/><configuration/>    
                </execution>    
               </executions>    
               <dependencies>    
                <!--参见dependencies/dependency元素-->    
                <dependency>    
                 ......    
                </dependency>    
               </dependencies>    
               <goals/><inherited/><configuration/>    
              </plugin>    
             </plugins>    
            </pluginManagement>    
            <plugins>    
             <!--参见build/pluginManagement/plugins/plugin元素-->    
             <plugin>    
              <groupId/><artifactId/><version/><extensions/>    
              <executions>    
               <execution>    
                <id/><phase/><goals/><inherited/><configuration/>    
               </execution>    
              </executions>    
              <dependencies>    
               <!--参见dependencies/dependency元素-->    
               <dependency>    
                ......    
               </dependency>    
              </dependencies>    
              <goals/><inherited/><configuration/>    
             </plugin>    
            </plugins>    
       </build>    
       <modules/>   
         <!--子项目相对路径-->
         <module></module>
       </modules>          
       <!--发现依赖和扩展的远程仓库列表。-->    
       <repositories>    
           <!--参见repositories/repository元素-->    
           <repository>    
             <releases>    
              <enabled/><updatePolicy/><checksumPolicy/>    
             </releases>    
             <snapshots>    
              <enabled/><updatePolicy/><checksumPolicy/>    
             </snapshots>    
             <id/><name/><url/><layout/>    
           </repository>    
       </repositories>    
       <!--发现插件的远程仓库列表,这些插件用于构建和报表-->    
       <pluginRepositories>    
           <!--包含需要连接到远程插件仓库的信息.参见repositories/repository元素--> 
           <pluginRepository>    
             <releases>    
              <enabled/><updatePolicy/><checksumPolicy/>    
             </releases>    
             <snapshots>    
              <enabled/><updatePolicy/><checksumPolicy/>    
             </snapshots>    
             <id/><name/><url/><layout/>    
           </pluginRepository>    
       </pluginRepositories>    
       <!--该元素描述了项目相关的所有依赖 -->    
       <dependencies>    
         <!--参见dependencies/dependency元素-->    
         <dependency/>   
       </dependencies>    
       <dependencyManagement>  
           <dependencies>    
             <!--参见dependencies/dependency元素-->    
             <dependency>    
             ......    
             </dependency>    
           </dependencies>    
       </dependencyManagement>    
       <!--参见distributionManagement元素-->    
       <distributionManagement>    
        ......    
       </distributionManagement>    
       <!--参见properties元素-->    
       <properties/>    
      </profile>    
    </profiles>    
 ------------------------------------------------------------------------------------     
    <!-- 聚合模块被构建成项目的一部分。列出的每个模块元素是指向该模块的目录的相对路径 --> 
    <modules>
        <!--子项目相对路径-->
        <module></module>
    </modules> 
 ------------------------------------------------------------------------------------ 
    <repositories>  <!--发现依赖和扩展的远程仓库列表。-->      
     <!--包含需要连接到远程仓库的信息-->    
     <repository>    
         <releases> <!--如何处理远程仓库里发布版本的下载-->    
          <!--true或者false表示该仓库是否为下载某种类型构件(发布版,快照版)开启。 -->    
         <enabled/>    
          <!-- 这里的选项是:always(一直),daily(默认,每日),interval:X(这里X是以分钟为单位的时间间隔),或者never(从不)。-->    
          <updatePolicy/>    
          <!--当Maven验证构件校验文件失败时该怎么做:ignore(忽略),fail(失败),或者warn(警告)。-->   
          <checksumPolicy/>    
         </releases>    
         <!-- 如何处理远程仓库里快照版本的下载。有了releases和snapshots这两组配置,POM就可以在每个单独的仓库中,为每种类型的构件采取不同的 策略-->    
         <snapshots>    
          <enabled/><updatePolicy/><checksumPolicy/>    
         </snapshots>    
         <!--远程仓库唯一标识符。可以用来匹配在settings.xml文件里配置的远程仓库-->    
         <id>banseon-repository-proxy</id>     
         <!--远程仓库名称-->    
         <name>banseon-repository-proxy</name>     
         <!--远程仓库URL,按protocol://hostname/path形式-->    
         <url>http://192.168.1.169:9999/repository/</url>  
         <layout>default</layout>               
     </repository>     
    </repositories>    
------------------------------------------------------------------------------------
    <!--发现插件的远程仓库列表,这些插件用于构建和报表-->    
    <pluginRepositories>    
     <!--包含需要连接到远程插件仓库的信息.参见repositories/repository元素-->    
     <pluginRepository>    
      ......    
     </pluginRepository>    
    </pluginRepositories>        
------------------------------------------------------------------------------------
    <!-- 继承自该项目的所有子项目的默认依赖信息。这部分的依赖信息不会被立即解析,而是当子项目声明一个依赖(必须描述group ID和 artifact ID信息),如果group ID和artifact ID以外的一些信息没有描述,则通过group ID和artifact ID 匹配到这里的依赖,并使用这里的依赖信息。-->    
    <dependencyManagement>    
      <dependencies>    
       <!--参见dependencies/dependency元素-->    
       <dependency>    
        ......    
       </dependency>    
      </dependencies>    
    </dependencyManagement>       
---------------------------------------------------------------------------------------------  
    <!--项目分发信息,在执行mvn deploy后表示要发布的位置。有了这些信息就可以把网站部署到远程服务器或者把构件部署到远程仓库。-->     
    <distributionManagement>    
        <!--部署项目产生的构件到远程仓库需要的信息-->    
        <repository>    
         <!--是分配给快照一个唯一的版本号-->    
         <uniqueVersion/>    
         <id>banseon-maven2</id>     
         <name>banseon maven2</name>     
         <url>file://${basedir}/target/deploy</url>     
         <layout/>    
        </repository>   
        <!--部署项目的网站需要的信息-->     
        <site>    
         <!--部署位置的唯一标识符,用来匹配站点和settings.xml文件里的配置-->     
            <id>banseon-site</id>     
            <!--部署位置的名称-->    
            <name>business api website</name>     
            <!--部署位置的URL,按protocol://hostname/path形式-->    
            <url>     
                scp://svn.baidu.com/banseon:/var/www/localhost/banseon-web      
            </url>     
        </site>    
        <!-- 给出该构件在远程仓库的状态。不得在本地项目中设置该元素,因为这是工具自动更新的。有效的值有:none(默认),converted(仓库管理员从 Maven 1 POM转换过来),partner(直接从伙伴Maven 2仓库同步过来),deployed(从Maven 2实例部 署),verified(被核实时正确的和最终的)。-->    
       <status/>           
    </distributionManagement>  
---------------------------------------------------------------------------------------------- 
    <!--以值替代名称,Properties可以在整个POM中使用,也可以作为触发条件(见settings.xml配置文件里activation元素的说明)。格式是<name>value</name>。-->    
    <properties/>    
</project>    
Copy the code

How does Maven transfer dependencies and remove dependencies

  • Pass dependencies: If our project references a Jar package that in turn references another Jar package, Maven downloads both the directly referenced and concisely-referenced JARS locally by default when the project is compiled
  • Dependency exclusion: If we only want to download directly referenced Jar packages, we need to do the following configuration in pom.xml
<exclusions>
    <exclusion>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
    </exclusion>
</exclusions>
Copy the code
  • Dependency conflicts: Dependency conflicts can occur when multiple jars in a project reference the same Jar at the same time, but Maven uses two strategies to avoid conflicts, so there are no dependency conflicts in Maven
    • Short circuit priority, for exampleA.jar -- > B.jar -- > X.jar; SAN Antonio ar - > X.j ar, the short-path x. jar is preferred
    • Declaration priority; If the reference path is of the same length, who is declared first in pom.xml

Aggregation and inheritance of Maven

  • Configuring multiple running projects at the same time is called aggregation. The aggregated projects have a parent pom.xml file, and each project has its own pom.xml
  • When aggregating multiple projects, if the same JARS need to be introduced in the aggregated projects, these jars can be written to the parent POM.xml, from which each child project inherits
  • Father pom. XML
<! -- Aggregate multiple items --> <modules> <module>.. Module A</module> <module>.. /module B</module> <module>.. /module C</module> </modules> <dependencies> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.2.2</version> </dependency> </dependencies> </dependencies> </dependencies>Copy the code
  • Son of pom. The XML configuration
<! <parent> <groupId> </groupId> <artifactId> artifactId</artifactId> <version> Version number of the project where the parent POM resides </version> </parent>Copy the code

MVN Example

MVN archetype: create-dgroupid =packageName -DartifactId=projectName MVN test-railcraft compile-railcraft test-compile // Run the test MVN test // clear the generated project MVN clean // Install jar MVN in the local Repository MVN clean install // Clean the old project, generate the new JAR and upload the remote repository MVN clean install deployCopy the code

Corrections are welcome

Refer to the article

  • Maven tutorial
  • Maven’s pom.xml file is the most comprehensive overview ever
  • Maven usage details
  • Maven common commands set