Maven-工作原理详解

文章目录

  • 概述
  • Maven 的工作机制
  • Maven中的坐标
    • 说明
    • 坐标的向量的取值方式
    • 坐标和仓库中jar包的存储路径之间的对应关系
  • 命令
  • 深入POM
    • 含义
    • 模型化思想
    • 思想落地
    • POM文件详解
    • POM的四个层次
      • 超级POM
      • 父POM
      • 有效POM
    • POM中属性的声明和引用
      • help插件的各个目标
      • help:evaluate 访问系统属性
      • help:evaluate 访问环境变量
      • help:evaluate 访问project属性
      • help:evaluate 访问setting全局配置
    • build标签详解
      • build标签的组成
      • 典型应用:制定JDK版本
      • 典型应用:SpringBoot定制化打包
    • Profile详解
      • 外部视角
      • 内部视角
      • 激活profile
    • 资源属性过滤
      • 简介
  • 依赖
    • 依赖范围
    • 依赖传递
    • 依赖仲裁
    • 依赖排除
    • 依赖继承
    • 依赖聚合
      • 聚合
  • Maven约定的目录结构
    • 目录
    • 约定目录结构的意义
  • 生命周期
    • 作用
    • 三个生命周期
  • 插件和目标
    • 插件
    • 目标
  • Nexus
    • 仓库概念
    • 将jar包部署到Nexus
    • 引用上传的jar包
  • 生产实践
    • 多模块项目仅打包某子模块
      • 切换到子模块目录再打包
      • 在父级目录通过打包选项实现
    • jar包冲突解决
      • 概述
      • IDEA的Maven Helper插件
      • Maven的enforcer插件
    • 体系外jar包导入
      • 概述
      • 方案
  • 总结

概述

Maven是一款构建管理、依赖管理、项目管理的工具。Maven提供了开发人员构建一个完整的生命周期框架。开发团队可以自动完成项目的基础工具建设,Maven使用标准的目录结构和默认构建生命周期。

在多个开发团队环境时,Maven可以设置按标准在非常短的时间里完成配置工作。由于大部分项目的设置都很简单,并且可重复使用,Maven让开发人员的工作更轻松,同时创建报表,检查,构建和测试自动化设置。

Maven 的工作机制

  • Maven核心程序:负责调度
  • Maven插件的jar:打包过程中的具体执行者

Maven中的坐标

说明

使用三个“向量”在Maven仓库中定位一个jar包。

  • groupId:公司或组织的id
  • artifiactId:一个项目或者项目中一个模块的id
  • version:版本号

坐标的向量的取值方式

  • groupId:公司或组织域名的倒序,通常也会加上项目名称。(如:com.lfc.mall)
  • artifiactId:模块的名称,将来作为Maven工程的工程名。
  • version:模块的版本号,根据需要决定。(如:1.1-SNAPSHOT 或者 2.0-RELEASE)

坐标和仓库中jar包的存储路径之间的对应关系


<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>8.0.20version>

对应于本地仓库目录(可看setting.xml中的localRepository标签):

# 文件目录
maven仓库地址/mysql/mysql-connector-java/8.0.20

# 文件结构
.
├── _remote.repositories
├── mysql-connector-java-8.0.20.jar
├── mysql-connector-java-8.0.20.jar.sha1
├── mysql-connector-java-8.0.20.pom
└── mysql-connector-java-8.0.20.pom.sha1

命令

汇总:

命令 作用 说明
mvn archetype:generate 命令行创建工程 会生成pom文件
mvn clean 清理操作 删除target目录
mvn compile 主程序编译 编译结果存放的目录:target/classes
mvn test-compile 测试程序编译 编译结果存放的目录:target/test-classes
mvn test 测试操作 测试报告存放的目录:target/surefire-reports
mvn package 打包 存放于target目录, artifactId-version 组成的jar包
mvn install 安装 将生成的jar包存入Maven仓库;还会将pom.xml文件转换成xxx.pom一起存入本地仓库。(可以直接使用mvn clean install)
mvn dependency:tree 查看依赖树 可以看出传递性
mvn dependency:list 查看依赖列表

运行命令要在对应的pom.xml所在目录,操作哪个工程就进入对应工程目录。如果执行的命令的目录没有pom文件会报错如下:

The goal you specified requires a project to execute 
but there is no POM in this directory

-D可以带参数执行命令,对插件的目标参数进行配置:
mvn -DpropA=valueA -DpropB=valueB -DpropC=valueC clean package
-DpropertyName=propertyValue
mvn clean install -Dmaven.test.skip=true

  • 如果propertyName不存在pom.xml,它将被设置。
  • 如果propertyName已经存在pom.xml,其值将被作为参数传递的值覆盖-D。

-P:指定所用的profile
mvn test -Penv=test

深入POM

含义

POM:Project Object Model,项目对象模型。和POM类似:DOM,文档对象模型。都是模型化思想的具体体现。

模型化思想

POM表示将工程抽象为一个模型,再用程序中的对象来描述这个模型,便于使用程序管理项目。在开发的过程中,最基本的做法是:将现实生活中的事物抽象成模型,然后封装模型相关的数据作为一个对象,进而可以在程序中计算与现实事物相关的数据(契合 Java中一切皆对象的思想)。

思想落地

POM理念集中体现在Maven工程根目录下pom.xml这个配置文件中。所以这个pom.xml配置文件就是Maven的核心配置文件。

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.0modelVersion>

    <groupId>com.lfcgroupId>
	<artifactId>mallartifactId>
	<version>2.1.2-SNAPSHOTversion>
	

	<name>rmallname>
	<description>林凡尘的大型门户商城description>



	<packaging>pompackaging>


	<properties>
		<commons-httpclient.version>3.1commons-httpclient.version>
		<java.version>1.8java.version>
	properties>


	<parent>
		<groupId>org.springframework.bootgroupId>
		<artifactId>spring-boot-starter-parentartifactId>
		<version>2.1.2.RELEASEversion>
		<relativePath/>
	parent>



	<organization>
		<name>Roncooname>
		<url>http://www.roncoo.comurl>
	organization>

	
	<modules>
		<module>ordermodule>
		<module>productmodule>
	modules>

	
	<distributionManagement>
		<repository>
			<id>nexus-releasesid>
			<name>Nexus Release Repositoryname>
			<url>http://192.168.1.221:8081/nexus/content/repositories/releases/url>
		repository>
		<snapshotRepository>
			<id>nexus-snapshotsid>
			<name>Nexus Snapshot Repositoryname>
			<url>http://192.168.1.221:8081/nexus/content/repositories/snapshots/url>
		snapshotRepository>
	distributionManagement>

	
	
	<dependencyManagement>
		<dependencies>
			
			<dependency>
				<groupId>org.mybatis.spring.bootgroupId>
				<artifactId>mybatis-spring-boot-starterartifactId>
				<version>${mybatis-spring-boot-starter.version}version>
				
				<scope>compilescope>
			dependency>

			<dependency>
				<groupId>com.baomidougroupId>
				<artifactId>mybatis-plusartifactId>
				<version>2.1.0version>
			dependency>


		dependencies>
	dependencyManagement>

	
	<developers>
		<developer>
			<name>Alongname>
			<id>shen.jialongid>
			<email>[email protected]email>
			<roles>
				<role>Developerrole>
			roles>
			<timezone>+8timezone>
		developer>
	developers>

	
    <build>
    	
		<finalName>order-servicefinalName>
		
		<plugins>
        	<plugin>
            	<groupId>org.springframework.bootgroupId>
            	<artifactId>spring-boot-maven-pluginartifactId>
        	plugin>
    	plugins>
		
    build>
project>

其中父工程的插件管理:

<build>
    <pluginManagement>
        <plugin>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-maven-pluginartifactId>
            <version>2.6.2version>
        plugin>
    pluginManagement>
build>

POM的四个层次

超级POM

Maven构建过程中的很多默认设定,比如:源文件存放的目录、测试源文件存放的目录、构建输出的目录等,都是经过Maven定义的,定义的位置就是:超级POM。自己创建的POM即使没有指定一个父工程(父POM),本质也默认继承了超级POM,可以类比 自己写的Java类继承了Object类。

内容如下:





<project> 
  <modelVersion>4.0.0modelVersion>  
  <repositories> 
    <repository> 
      <id>centralid>  
      <name>Central Repositoryname>  
      <url>http://repo.maven.apache.org/maven2url>  
      <layout>defaultlayout>  
      <snapshots> 
        <enabled>falseenabled> 
      snapshots> 
    repository> 
  repositories>  
  <pluginRepositories> 
    <pluginRepository> 
      <id>centralid>  
      <name>Central Repositoryname>  
      <url>http://repo.maven.apache.org/maven2url>  
      <layout>defaultlayout>  
      <snapshots> 
        <enabled>falseenabled> 
      snapshots>  
      <releases> 
        <updatePolicy>neverupdatePolicy> 
      releases> 
    pluginRepository> 
  pluginRepositories>  
  <build> 
    <directory>${project.basedir}/targetdirectory>  
    <outputDirectory>${project.build.directory}/classesoutputDirectory>  
    <finalName>${project.artifactId}-${project.version}finalName>  
    <testOutputDirectory>${project.build.directory}/test-classestestOutputDirectory>  
    <sourceDirectory>${project.basedir}/src/main/javasourceDirectory>  
    <scriptSourceDirectory>src/main/scriptsscriptSourceDirectory>  
    <testSourceDirectory>${project.basedir}/src/test/javatestSourceDirectory>  
    <resources> 
      <resource> 
        <directory>${project.basedir}/src/main/resourcesdirectory> 
      resource> 
    resources>  
    <testResources> 
      <testResource> 
        <directory>${project.basedir}/src/test/resourcesdirectory> 
      testResource> 
    testResources>  
    <pluginManagement> 
        
        
      <plugins> 
        <plugin> 
          <artifactId>maven-antrun-pluginartifactId>  
          <version>1.3version> 
        plugin>  
        <plugin> 
          <artifactId>maven-assembly-pluginartifactId>  
          <version>2.2-beta-5version> 
        plugin>  
        <plugin> 
          <artifactId>maven-dependency-pluginartifactId>  
          <version>2.1version> 
        plugin>  
        <plugin> 
          <artifactId>maven-release-pluginartifactId>  
          <version>2.0version> 
        plugin> 
      plugins> 
    pluginManagement> 
  build>  
  <reporting> 
    <outputDirectory>${project.build.directory}/siteoutputDirectory> 
  reporting>  
  <profiles> 
      
    <profile> 
      <id>release-profileid>  
      <activation> 
        <property> 
          <name>performReleasename>  
          <value>truevalue> 
        property> 
      activation>  
      <build> 
        <plugins> 
          <plugin> 
            <inherited>trueinherited>  
            <artifactId>maven-source-pluginartifactId>  
            <executions> 
              <execution> 
                <id>attach-sourcesid>  
                <goals> 
                  <goal>jargoal> 
                goals> 
              execution> 
            executions> 
          plugin>  
          <plugin> 
            <inherited>trueinherited>  
            <artifactId>maven-javadoc-pluginartifactId>  
            <executions> 
              <execution> 
                <id>attach-javadocsid>  
                <goals> 
                  <goal>jargoal> 
                goals> 
              execution> 
            executions> 
          plugin>  
          <plugin> 
            <inherited>trueinherited>  
            <artifactId>maven-deploy-pluginartifactId>  
            <configuration> 
              <updateReleaseInfo>trueupdateReleaseInfo> 
            configuration> 
          plugin> 
        plugins> 
      build> 
    profile> 
  profiles> 
project>

父POM

和Java类一样,POM之间是单继承的,当我们给一个POM指定了父POM,那么继承关系如下图所示:
Maven-工作原理详解_第1张图片

有效POM

在POM的继承关系中,子POM可以覆盖父POM中的配置;如果子POM没有覆盖,那么父POM中的配置将会被继承。按照这个规则,继承关系中的所有POM叠加到一起,就得到了最终生效的POM。显然Maven实际运行过程中,执行构建操作就是按照这个最终生效的POM来运行的。使用mvn help:effective-pom 来查看。

POM中属性的声明和引用

help插件的各个目标

目标 说明
help:active-profiles 列出当前已激活的profile
help:all-profiles 列出当前工程所有可用的profile
help:describe 描述一个插件的Mojo属性
help:effective-pom 以XML格式展示有效的POM
help:effective-settings 为当前工程以XML格式计算得到的settings配置
help:evaluate 计算用户在交互模式下给出的Maven表达式,查看pom中property的属性,如有变量则会显示计算后的值。执行命令之后输入:${property_xxx}
help:system 显示平台详细信息列表,如系统属性和环境变量

help:evaluate 访问系统属性

具体有哪些系统属性可以在程序中通过 System.getProperties()获取。在命令可以通过以下方式获取:

  • ${java.runtime.name}
  • ${os.version}

help:evaluate 访问环境变量

  • ${env.JAVA_HOME}

help:evaluate 访问project属性

在POM中配置的元素值,可以通过${project.xxx}访问。

  • ${project.artifactId}
  • ${project.groupId}
  • ${project.parent.groupId}
  • ${project.modules[0]}

help:evaluate 访问setting全局配置

访问maven的配置文件setting.xml中配置的元素值
${setting.标签名}

  • ${settings.localRepository}

build标签详解

我们配置的build标签都是对超级POM配置的叠加,并且在默认配置无法满足需求的时候会定制构建过程。

build标签的组成

定义约定的目录结构

目录名 作用
sourceDirectory 主体源程序存放目录
scriptSourceDirectory 脚本源程序存放目录
testSourceDirectory 测试源程序存放目录
outputDirectory 主体源程序编译结果输出目录
testOutputDirectory 测试源程序编译结果输出目录
resources 主体资源文件存放目录
testResources 测试源文件存放目录
directory 构建结果输出目录

备用插件管理
通过pluginManagement 标签管理起来的插件就像dependencyManagement一样,子工程使用时可以省略版本号,起到腐工程中统一管理版本的效果。

dependencyManagement 标签存放着几个极少用到的插件:

  • maven-antrun-plugin
  • maven-assembly-plugin
  • maven-dependency-plugin
  • maven-release-plugin

生命周期插件
plugins标签存放的是默认生命周期中实际会用到的插件。

<plugin>                                                                                                                                      
                                                                               
    <groupId>org.apache.maven.pluginsgroupId>                                                                                               
    <artifactId>maven-compiler-pluginartifactId>                                                                                            
    <version>3.1version>                                                                                                                    
    <configuration>                                                                                                                           
                            
        <source>1.8source>                                                                                              
        <target>1.8target>                                                                                      
        <encoding>UTF-8encoding>
        <skipTests>trueskipTests>                                                                             
        <verbose>trueverbose>
        <showWarnings>trueshowWarnings>                                                                                                               
        <fork>truefork>                                                        
        <executable>executable>           
        <compilerVersion>1.3compilerVersion>                                                                         
        <meminitial>128mmeminitial>                                                                                      
        <maxmem>512mmaxmem>                                                                                              
        <compilerArgument>-verbose -bootclasspath ${java.home}\lib\rt.jarcompilerArgument>               
    configuration>    

	<executions>
		<execution>
			<id>default-testCompileid>
			<phase>test-compilephase>
			<goals>
				<goal>testCompilegoal>
			goals>
		execution>
	executions>                                                                                                                      
plugin>                                                                                                                                     

坐标部分:
groupId和artifactId标签定义了插件的坐标,作为Maven的自带插件这里省略了groupId。

执行部分:
executions标签内可以配置多个execution,execution标签内:

  • id:指定唯一标识
  • phase:关联的生命周期阶段
  • goals/goal:关联指定生命周期的目标
    goals标签中可以配置多个goal标签,标识一个生命周期环节可以对应当前插件的多个目标。

configuration标签内进行配置使用时的标签是插件本身定义的。

每个插件能够做哪些设置都是各个插件自己规定的,无法一概而论。

典型应用:制定JDK版本

提出问题
在本地环境通过setting.xml实现的配置的JDK版本,将Maven配置上服务器,会脱离setting.xml,该如何保证程序的运行?可以将JDK的版本信息,配置到负责编译的maven-compiler-plugin插件,让它在构建的过程中,按照我们指定的信息工作。如上文所示。

两种配置的区别:

  • setting.xml中配置:仅在本地生效,如果脱离当前setting.xml环境,则无法运行。
  • xml中配置:各个环境都可以运行。

典型应用:SpringBoot定制化打包

需求
spring-boot-maven-plugin并不是Maven自带的插件,而是SpringBoot提供的,用来改变Maven的打包行为,默认情况下Maven调用的是maven-jar-plugin插件的jar目标,生成可运行的jar包。

<build>
	<plugins>
		<plugin>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-maven-pluginartifactId>
            <version>2.5.5version>
		plugin>
	plugins>
build>

插件目标:

插件目标 说明
spring-boot:repackage 默认goal。在mvn package之后,再次打包可执行的jar/war,同时保留mvn package生成的jar/war为.origin
spring-boot:run 运行Spring Boot应用
spring-boot:start 在mvn integration-test阶段,进行Spring Boot应用生命周期的管理
spring-boot:stop 在mvn integration-test阶段,进行Spring Boot应用生命周期的管理
spring-boot:build-info 生成Actuator使用的构建信息文件build-info.properties

Profile详解

项目协同流程:
Maven-工作原理详解_第2张图片
涉及的3套环境:

  • 开发环境:供不同开发工程师开发的不同模块相互调用,内部使用。
  • 测试环境:供测试工程师对各个模块进行测试,内部使用。
  • 生产环境:供最终用户访问,对外提供访问。

外部视角

从外部视角来看,profile可以在下面两种配置文件中配置:

  • setting.xml:全局生效,比如配置JDK1.8
  • pom.xml:当前POM生效

内部视角

从内部视角来看,配置profile有如下语法要求:

语法要求 说明
profiles/profile标签
  • 由于profile天然代表众多可配置中的一个,所以由附属形式的profiles标签统一管理
  • 由于profile标签覆盖了pom.xml中的默认配置,所以profiles标签通常是pom.xml最后的一个标签。
id标签 每个profile都必须有一个id标签,指定该profile的唯一标识 。这个id标签的值会在命令行调用profile时被用到,这个命令格式是:-D
其他允许出现的标签 一个profile可以覆盖项目的最终名称、项目依赖、插件配置等各个方面以影响构建行为。
  • build
    • defaultGoal
    • finalName
    • resources
    • testResources
    • plugins
  • reporting
  • modules
  • dependencyManagement
  • repositories
  • dependencies
  • pluginRepositories
  • properties

激活profile

  1. 列出所有激活的profile
    mvn help:active-profiles

  2. 指定某个具体的profile
    mvn compile -P

资源属性过滤

简介

Maven为了能够通过profile实现各不同运行环境切换,提供了一种【资源属性过滤】的机制。通过属性替换实现不同环境使用不同参数。

依赖

依赖范围

标签位置:dependencies/dependency/scope
可选值:compile / test / provided / system / runtime / import

compile 和 test对比

main目录(空间) test目录(空间) 开发过程(时间) 部署到服务器(时间)
compile 有效 有效 有效 有效
test 无效 有效 有效 无效

说明:

  • 是否有效:可以通过是否可编译成功作为判断标准。
  • 部署到服务器:部署到服务器之后,项目目录下是否存在该依赖的jar包。

PS:

compile 和 provided对比

main目录(空间) test目录(空间) 开发过程(时间) 部署到服务器(时间)
compile 有效 有效 有效 有效
provided 有效 有效 有效 无效

结论

  • compile:通常使用的第三方框架jar包这样再项目实际运行时真正要用到的jar包,都是以compile范围进行依赖的。
  • test:测试过程中使用的jar包,以test范围以来进行的。比如 junit。
  • provided:在开发过程中需要的“服务器上的jar”包,通常以provided范围依赖,比如servlet-api、jsp-api。而这个范围的jar包之所以不参与部署,不放进war包,是避免和服务器已有的同类jar包产生冲突,同时减轻服务器的负担。

依赖传递

概念:
A依赖B,B依赖C,那么在A没有配置对C的依赖的情况下,A里面能不能直接使用C?

传递原则:
在A依赖B,B依赖C的前提下,C是否能传递到A,取决于B依赖C时设置的依赖范围。

  • B依赖C时使用compile范围:可以传递
  • B依赖C时使用test或者provided范围:不能传递,所以需要这样的jar包时,就必须在需要的地方明确配置依赖才可以。

依赖仲裁

  • 最短路径优先
  • 路径相同时,先声明者优先。

依赖排除

概念:
当A依赖B,B依赖C而且C可以传递到A的时候,A不想要C,需要在A里面把C排除掉,而往往这种情况都是为了避免jar包之间的冲突。
Maven-工作原理详解_第3张图片
所以配置以来的排除其实就是阻止某些jar包的传递。

配置方式:

<dependency>
	<groupId>com.lfcgroupId>
	<artifactId>commonartifactId>
	<version>2.1.0version>
	
	<exclusions>
		
		<exclusion>
			
			<groupId>commons-logginggroupId>
			<artifactId>commons-loggingartifactId>
		exclusion>
	exclusions>

dependency>

依赖继承

概念:
Maven工程之间,A工程集成B工程
B:父工程
A:子工程
本质上是A工程的pom.xml中配置继承了B工程中pom.xml的配置。

作用:
在父工程中统一管理项目中的依赖信息,具体来说是管理依赖信息的版本。简言之:父工程管理依赖,子工程各取所需。
它的背景:

  • 对一个比较大型的项目进行模块拆分。
  • 一个project下面创建很多个module。
  • 每一个module都需要配置自己的依赖信息。

背后的需求:

  • 在每一个module中各自维护各自的依赖信息很容易发生冲突,不易于统一管理。
  • 使用同一个框架内的不同jar包,它们应该是同一个版本,所以整个项目中使用的框架版本需要统一。
  • 使用框架时所需的jar包(依赖信息组合)需要经过长时间的摸索和反复测试,最终确定一个可用的组合,这个耗费很大的精力总结出来的方案不应该在新的项目中重新摸索。

注意:
只有打包方式为pom的 Maven工程才能够管理其他的Maven工程,打包方式为pom的Maven工程中不写业务代码,它是专门管理其他Maven工程的工程。

实际意义:
Maven-工作原理详解_第4张图片
编写一套符合要求,开发各种功能都能正常工作的雨来组合并不容易。如果公司里有人总结了成熟的方案,在开发新项目时,如果不使用原有的积累,而是重新摸索,会浪费大量的时间。为了提高效率,我们可以使用工程继承的机制,让成熟的依赖组合方案能够保留下来。如图所示,公司级的父工程中管理的就是成熟的依赖组合方案,各个新项目、子系统各取所需即可。

依赖聚合

聚合

概念:
使用一个“总工程”将各个“模块工程”汇集成一个整体对应完整的项目。
从集成关系角度:

  • 父工程
  • 子工程

从聚合关系角度:

  • 总工程
  • 模块工程

目的:

  • 一键执行Maven命令:很多构建命令都可与在“总工程”中一键执行。以mvn install 命令为例,Maven要求有父工程时先安装父工程;有依赖的工程时,先安装被依赖的工程,自己管理这些规则非常麻烦;有了工程聚合之后,在总工程执行mvn install 可以一键完成安装,而且会自动按照正确的顺序执行。
  • 配置聚合之后,各个模块工程会在总工程展示一个列表,让项目中的各个模块一目了然。

聚合的位置:

<modules>
	<module>ordermodule>
	<module>productmodule>
	<module>paymodule>
<modules>

依赖循环问题:
如果A工程以来B工程,B工程以来C工程,C工程反过来又依赖A工程。那么在执行构建时会报错如下:

[ERROR][ERROR] The projects in the reator contains a cyclic reference 

Maven约定的目录结构

目录


├── pom.xml
└── src  # 源码目录
    └── main  # 主体程序目录
        ├── java  # Java源代码
        │   └── com  # package目录
        └── resources  # 配置文件
    ├── test  # 单元测试目录
        ├── java  # Java源代码
            └── com # package目录

另外还有一个target目录存放构建输出的结果(class字节码文件、jar包、war包等)。

约定目录结构的意义

Maven为了让构建过程尽可能自动化完成,所以必须约定目录结构。比如进行编译操作:先去java源程序目录读取Java源代码,然后执行编译,最后吧编译的结果存放到target中。

生命周期

作用

为了让构建过程自动化完成,Maven设定了三个生命周期,生命周期中的每一个环节对应构建过程中的一个操作。

三个生命周期

生命周期 作用 环节
Clean 清理相关操作 pre-clean
clean
post-clean
Site 生成相关站点 pre-site
site
post-site
deploy-site
Default 主要构建过程 validate
compile
test
package
verify
install
site
deploy

插件和目标

插件

Maven的核心程序负责宏观调度,不做具体工作。具体工作都是由Maven插件完成的。例如:编译就是由maven-compiler-plugin-3.1.jar插件来完成的。

目标

一个插件可以对应多个目标,而每一个目标都和生命周期中的某一环节对应。
Default生命周期中有compile和test-compile两个和编译相关的环节,这两个环节对应compile和test-compile两个目标,而这两个目标都是由maven-compiler-plugin-3.1.jar插件来执行的。

Nexus

仓库概念

仓库类型 说明
proxy 某个远程仓库的代理
group 存放:通过Nexus获取的第三方jar包
hosted 存放:本团队其他开发人员 部署到Nexus 的jar包
仓库名称 说明
maven-central Nexus对Maven中央仓库的代理
maven-public Nexus默认创建,供开发人员下载使用的组仓库
maven-release Nexus默认创建,供开发人员部署自己jar包的宿主仓库,要求release版本
maven-snapshots Nexus默认创建,供开发人员部署自己jar包的宿主仓库,要求snapshots版本

将jar包部署到Nexus

 
    <distributionManagement>
        <repository>
            <id>nexusid>
            <name>nexus RELEASEname>
            <url>http://127.0.0.1:8089/nexus/repository/maven_release/url>
        repository>
        <snapshotRepository>
            <id>nexusid>
            <name>nexus SNAPSHOTname>
            <url>http://127.0.0.1:8089/nexus/repository/maven_snapshot/url>
        snapshotRepository>
    distributionManagement>

执行
mvn deploy

引用上传的jar包

<repositories>
	<repository>
		<id>maven_snapshotid>
		<url>http://127.0.0.1:8089/nexus/repository/maven_snapshoturl> 
		<releases>
        	<enabled>trueenabled>
      	releases>
      	<snapshots>
        	<enabled>falseenabled>
      	snapshots>
	repository>
repositories>

生产实践

多模块项目仅打包某子模块

切换到子模块目录再打包

在命令行cd 到子模块的目录(含pom.xml的目录)再执行mvn clean package,即可打包子模块。

在父级目录通过打包选项实现

mvn clean install -pl 单模块名 -am -Dmaven.test.skip=true

指令名 说明
-pl 打包指定模块,以逗号分隔
-am 打包所指定模块的依赖模块
-amd 打包所指定模块的依赖模块的依赖,含有传递依赖
-rf 按指定顺序开始打包

jar包冲突解决

概述

基本思路:

  • 第一步:把彼此冲突的jar包找到
  • 第二步:在冲突的jar包中选定一个,具体做法无非是通过exclusions标签排除依赖,或是明确声明依赖

IDEA的Maven Helper插件

这个插件是IDEA插件,不是Maven插件。它能够给我们罗列出来同一个jar包的不同版本,以及他们的来源。但是对不同的jar包中同名的类没有办法。

Maven的enforcer插件

使用Maven的enforcer插件即可以检测同一个jar包的不同版本,又可以检测不同jar包中的同名的类。

体系外jar包导入

概述

实际开发过程中用到的一些jar包并非用Maven的方式发布,自然也没法通过Maven导入。比如人脸识别通用的jar包、银行sdk的jar包、海康威视jar包等。

方案

  1. 将该jar包安装到Maven仓库
mvn install:install-file -Dfile=[jar包路径] \
-DgroupId=[给该jar包 强行设定坐标groupId] \
-DartifactId=[给该jar包 强行设定坐标artifactI] \
-Dversion=1 \
-Dpackage=jar

总结

实际工作中,主要掌握以下几种操作:

  1. 微服务打包,并通过shell脚本/容器启动该jar包。
  2. 搭建公司的Nexus私服,并引用。
  3. 体系外的jar包导入和引用。

参考:
尚硅谷的封捷老师:https://www.bilibili.com/video/BV12q4y147e4?p=1

你可能感兴趣的:(Java,maven,java)