【详细步骤】Maven从无到有,理解pom文件——maven使用第三弹

1,069 阅读10分钟

聚合和继承

分布式开发必须要用

聚合模块(父模块)的打包方式必须为pom,否则无法完成构建

父模块里面一般不写代码。

父模块的packaging必须是pom

image-20201126095225954

新建子模块

image-20201126095346717

新建完子模块过后父模块的pom.xml多了一个东西

image-20201126095502927

我们的maven-test就叫聚合模块或者说父模块

child-one就叫子模块

子模块的pom.xml里面有parent标签

image-20201126095745203

在聚合多个项目时,如果这些被聚合的项目中需要引入相同的jar,那么可以将这些jar写入父pom中,各个子项目继承该pom即可。父模块的打包方式必须为pom,否则无法构建项目

例:

在maven仓库里找jar包

mvnrepository.com/

maven.aliyun.com/mvn/search

image-20201126100408934

image-20201126100632467

引入依赖,点击刷新,就会自动帮我们去网上下载

image-20201126100722848

此时就能使用这个jar包里面的类了(在父模块里写的依赖,子模块在使用)

image-20201126100958878

通过在各个子模块中配置来表明其继承于那一个父模块

   <parent>
        <artifactId>maven-test</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>child-one</artifactId>

可以被继承的POM元素如下:

  • groupId:项目组ID,项目坐标的核心元素
  • version:项目版本,项目坐标的核心因素(上面的子模块里就已经没有子groupId和version标签了,直接从父模块里继承,父模块是哪个组织的,那子模块就是哪个组织的,父模块的版本是什么,子模块当前的版本就是什么)
  • properties:自定义的Maven属性 ,一般用于统一指定各个依赖的版本号
  • dependencies:项目的依赖配置,公共依赖
  • dependencyMangement:项目的依赖管理配置
  • repositories:项目的仓库配置
  • build:包括项目的源码目录配置、输出目录配置、插件配置、插件管理配置等

一些对项目的描述

  • descripitions:项目的描述信息
  • organization:项目的组织信息
  • inceptionYear:项目的创始年份
  • url:项目的URL地址
  • developers:项目的开发信息
  • contributors:项目的贡献者信息
  • distributionManagement:项目的部署配置
  • issueManagement:项目的缺陷跟踪系统信息
  • ciManagement:项目的持续继承系统信息
  • scm:项目的版本控制系统
  • malilingLists:项目的邮件列表信息
  • reporting:包括项目的报告输出目录配置、报告插件配置等

POM文件

1.基础配置

www.jianshu.com/p/0e3a1f9c9…

一个典型的pom.xml文件配置如下:

<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">
    
    
   <!-- pom模型版本,maven2和3只能为4.0.0,现在是maven2唯一支持的版本,必须这么写-->
   <modelVersion>4.0.0</modelVersion>
    
   <!-- 项目的组ID,用于maven定位,公司或组织的唯一标志,并且配置时生成的路径也是由此生成,如com.sunj.maven会将该项目打包成的jar包放本地路径:/com/sunj/ -->
   <groupId>com.sunj</groupId>
    
   <!-- 本项目的唯一ID,一个groupId下面可能有多个项目,就是靠artifactId来区分的-->
   <artifactId>test</artifactId>
    
   <!-- 本项目目前的版本-->
   <version>1.0</version>
    
   <!-- 项目的打包方式,如pom,jar,war,默认为jar-->
    <!-- 如果是聚合工程,也就是说父工程,我们就写pom-->
   <packaging>war</packaging>
    
    <!-- 为pom定义一些常量,在pom中的其他地方可以直接引用,使用方式 如下:${file.encoding}-->
    <!--常常用来整体控制一些依赖的版本号-->
    <properties>
        <file.encoding>UTF-8</file.encoding>
        <java.source.version>1.8</java.source.version>
        <!--我们定义了java.source.version的值是1.8 相当于定义了静态常量,以后想要使用时,就直接花括号包住,前面加$-->
        <java.target.version>1.8</java.target.version>
    </properties>
    
    <!--定义项目的依赖关系,就是依赖的jar包-->
    <dependencies>
        <!--每个dependency都对应这一个jar包-->
        <denpendency>
        	<!--一般情况下,maven是通过groupId、artifactId、version这三个元素(俗称坐标)来检索该构建,然后引入你的工程。如果他想引用你现在开发的这个项目(前提是已经开发完毕并发布到了远程仓库),就需要在他的pom文件中新建一个dependency节点,将本项目的groupId、artifactId、version写入,maven就会把你上传的jar包下载到本地-->
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
         <!--依赖范围-->
         <scope>compile</scope>
         <!--设置依赖是否可选。默认为false,即子项目默认都继承,如果为true,则子项目必须显示的引入-->
         <optional>false</optional>
            
         <!--依赖排除-->
            <exclutions>
                <exclution>
                    <groupId>org.slf4j</groupId>
                    <arifactId>slf4j-api</arifactId>
                </exclution>
            </exclutions>
        </denpendency>
    </dependencies>
    
    
<project>

一般来说,上面几个配置项对任何项目都是必不可少的,定义了项目的基本属性(除了properties)。

除了dependencies我们还用到了denpendencyManagement,区别如下

dependencies

即使在子项目中不写该依赖项,那么子项目仍然会从父项目中继承在依赖项(全部继承)。

继承下来就会被编译,如果子项目根本不用这个依赖会增加子工程的负担。

dependencyManagement

通常会在父工程中定义,目的是统一各个子模块的依赖版本,有不用实际依赖

  • 只是声明依赖,并不实现引入
  • 子项目需要显示的声明需要用的依赖。如果不在子项目中声明依赖,是不会从父项目中继承下来的;

只有在子项目中写了该依赖项,并且没有指定具体版本,才会从父项目总继承该项,并且version和scope都读取自父pom;另外如果子项目中指定了版本号,那么会使用子项目中指定的jar版本。

在父模块中定义后,子模块不会直接使用对应依赖,但是在使用相同依赖的时候可以不加版本号,这样的好处是,父项目统一了版本,而且子项目可以在需要的时候才引用对应的依赖。

2.构建配置

约定大于配置,有约定尽量按照约定来,没有约定我们就进行配置。

  <build>
        <!--产生的构建的文件名,默认是${artifactId}-${version}-->
        <finalName>myProject</finalName>
        <!--构建产生的所有文件的存放目录,默认为${basedir}/target-->
        <directory>${basedir}/target</directory>
        
        
        <!--诸如以上这些还有很多,这个配置都有默认值,约定好了就这么建,你要是实在看了不爽也能改-->
    </build>

我们常用的几个配置

关于资源处理的配置

有些小伙伴就喜欢在src中填写配置文件,都加上就能保证你写在src底下的配置文件也能生效

<build>
<resources>    
   <!--这个元素描述了项目相关或测试相关的所有资源路径-->    
   <resource>    
    <!-- 描述了资源的目标路径。该路径相对target/classes目录(例如${project.build.outputDirectory})。举个例 子,如果你想资源在特定的包里(org.apache.maven.messages),你就必须该元素设置为org/apache/maven /messages。然而,如果你只是想把资源放到源码目录结构里,就不需要该配置。-->    
    <!--描述存放资源的目录,该路径相对POM路径-->    
    <directory>src/main/java</directory>/>    
    <targetPath/>    
    <!--是否使用参数值代替参数名。参数值取自properties元素或者文件里配置的属性,文件在filters元素里列出。-->    
    <filtering/>    

    <!--包含的模式列表,例如**/*.xml.-->    
    <includes/>    
    <!--排除的模式列表,例如**/*.xml-->    
    <excludes/>    
   </resource>    
  </resources>  
</build>

添加本地jar包

本地jar包,如:支付宝jar包要放到src/main/webapp/WEB-INF/lib文件夹下,如果没有配置,本地没问题,但是线上会找不到sdk类,为什么要引入,因为支付宝的jar包在中央仓库没有

   <!--geelynote maven的核心插件之一compiler插件默认只支持编译java 1.4,因此需要加上支持高版本jre的配置,在pom.xml里面加上-->
<!--这个插件能保证我们编译的jdk版本是1.8,不加这个插件就默认的是1.5,要用这个插件提高java的编译版本-->
   <plugin>
        <groupId>org.apache.pulgins</groupId>
        <artifactId>maven-compiler-pulgin</artifactId>
        <configuation>
            <source>1.8</source>
            <target>1.8</target>
            <encoding>UTF-8</encoding>
            <compilerArgumnts>
                <extdirs>${project.basedir}/src/main/webapp/WEB-INF/lib</extdirs>
            </compilerArgumnts>
        </configuation>
    </plugin>

3.仓库配置

aliyun镜像在我们的settings.xml里面配置了,在pom.xml里面也能配

pom里配是针对于你这个单独的工程,

settings是对全局的配置。

如果pom里面配了,然后这个工程拿到别人的电脑上执行,他仍然会区阿里云里下载依赖,因为pom里面配了。如果不放心别人的setting里面有没有配阿里云,就可以把自己的pom里面也配一下,万无一失

  <repositories>
        <repository>
            <id>alimaven</id>
            <name>aliyun maven</name>
            <url>http://maven.aliyun.com/nexus/content/groups/public</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
            
        </repository>
    </repositories>

pom.xml里面的仓库与setting.xml里的仓库功能是一样的。主要区别在于,pom里的仓库是个性化的。比如,很多家大公司里面的setting文件时公用的,所有的项目都用一个setting文件,但各个子项目却会引用不同的第三方库,所以就需要在pom.xml里设置自己需要的仓库地址。

4.项目信息配置(知道就行)

name:给用户提供更为友好的项目名

description:项目描述,maven文档中保存

url:主页的URL,maven文档中保存

inceptionYear:项目创建年份,4位数字。当产生版权信息时需要使用这个值

licenses:该元素描述了项目所有License列表。 应该只列出该项目的-

license列表,不要列出依赖项目的 license列表。如果列出多个license,用户可以选择它们中的一个而不是接受所有license。(如下)

<license>    
    <!--license用于法律上的名称-->    
    <name>...</name>     
    <!--官方的license正文页面的URL-->    
    <url>....</url>
    <!--项目分发的主要方式:repo,可以从Maven库下载 manual, 用户必须手动下载和安装依赖-->    
    <distribution>repo</distribution>     
    <!--关于license的补充信息-->    
    <comments>....</comments>     
</license>

Maven仓库

任何构建都有唯一的坐标,Maven根据这个坐标定义了构建在仓库中的唯一存储路径,

Maven仓库分为两类:

  • 本地仓库

  • 远程仓库,远程仓库又分为3种:

    中央仓库

    ​ 私服

    ​ 其他公共库

1、本地仓库

本地仓库是Maven在本地存储构建的地方。Maven的本地仓库,在安装maven后并不会创建,它是在第一次执行Maven命令的死后才被创建。

Maven本地仓库的默认位置:无论是Windows还是Linux,在用户的目录下都有一个.m2/repository的仓库目录,这就是Maven仓库的默认位置。

image-20201126145650254

在Maven的目录下的conf目录下,有一个setting.xml文件,是Maven的配置文件,在里面可以修改本地仓库的位置。

私服是一种特殊的远程仓库,它是架设在局域网内的仓库服务,私服代理广域网上的远程仓库,供局域网内的Maven用户使用。当Maven需要下载构建的时候,他从私服请求,如果私服上不存在该构建,则从外部的远程仓库下载,缓存在私服上之后,再为Maven的下载请求提供服务。

Maven私服的优点:

  1. 加速构建
  2. 节省带宽
  3. 节省中央Maven仓库的带宽
  4. 稳定(应付一旦中央服务器出问题的情况)
  5. 可以建立本地内部仓库
  6. 可以建立公共仓库

maven再默认的青鸾管辖是从中央仓库下载构建,也就是id为central的仓库。如果没有特殊需求,**一般只需要将私服地址配置为镜像,同时配置其代理所有的仓库就可以实现通过私服下载依赖的供能。**镜像配置如下:

<mirror>
	<id>Nexus Mirror</id>
    <name>Nexus Mirror</name>
    <url>http://localhost:8081/nexus/content/groups/public</url>
    <mirror>*</mirror>
</mirror>

Maven插件

Maven插件介绍 plugin放在plugins里,plugins放在build里

Maven实际上是一个依赖插件执行的框架,每个任务实际上是由插件完成。Maven插件通常被用来:

  • 打包jar文件
  • 创建war文件
  • 编译代码文件
  • 代码单元测试
  • 创建工程文档
  • 创建工程报告

插件通常提供了一个目标的集合,并且可以使用下面的语法执行;

mvn [pulgin-name]:[goal-name]

例如,一个java工程可以使用maven-compiler-plugin的compile-goal编译,使用以下命令

mvn compiler:compile

2.maven-compiler-plugin

设置maven编译的版本,maven3默认用jdk1.5,maven2默认用jdk1.3

这个插件基本每个项目都要加上

<plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
            <source>1.8</source><!--源代码使用的jdk版本-->
            <target>1.8</target><!--需要生成的目标class文件的编译版本-->
            <encoding>UTF-8</encoding><!--字符集编码-->
        </configuration>
    </plugin>

Tomcat插件

在maven里建web工程

新建一个工程右击Add Framework Support:

image-20201126161225541

image-20201126161346378

在pom.xml里添加Tomcat插件,jdk的插件几乎每个项目都要引

image-20201126163619985

可以通过命令行命令启动 也可以通过点击右边的插件启动

image-20201126164709407

解决问题:老是标红是因为没有配置中央仓库

blog.csdn.net/Hello_World…

配置后:

image-20201126182546551

image-20201126182429737

mvnrepository.com/

这个网站里有插件的坐标,怕错的话可以直接复制

image-20201126182832283

image-20201126182933679

Maven项目模板

Archetype是一个Maven插件,其任务是按照其模板来创建一个xiangmujieg。

执行如下命令即可创建Maven项目

mvn archetype:generate

常用的archetype有以下两种:

maven-archetype-quickstar默认的Archetype

基本内容包括:

一个包含junit依赖声明的pom.xml

src/main/java主代码目录机一个名为App的类

src/test/java测试代码目录及一个名为AppTest的测试用例

mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4 -DinteractiveMode=false

没啥用

也可以新建的时候选模板

image-20201126190333122

Maven父子工程进行版本统一

工程和工程之间是要进行交互的,我们用的依赖的版本应该一致

一些常用的工具类应该加到父工程pom.xml里的dependencies里,这里面的依赖会被传递到子工程。而dependencyManage里面写的依赖如果没有在子工程的pom里声明就不会被传递给子工程,如果子工程里声明(还是平常写依赖的方法,就是不写版本号)了,就会被传递过来(声明的时候是不需要写版本的,这就达到了版本的统一)

在父工程里定义properties,约定我们所有依赖的版本号

然后使用dependencyManagement把所有相关里依赖放在里面,进行版本的统一管理

如果有子工程需要依赖相关的jar包,只要声明即可,不需要写版本号

如果我们有一些共用类,特别是一些工具类,依然可以放在父工程的dependency里,传递给所有子工程。

总结:

Maven总得来说就是一个工具,工具没什么好理解的主要就是使用,用得多了就行,今后的项目基本就是建立在maven之上的,它可以帮助我们省去很多构建的过程,以后管理svn的时候,只需要把模块和pom文件传上去就行了。

哪怕自己的IDEA有问题,那就不用IDEA构建就行了,直接用mvn命令也行。

引到eclipse,eclipse也运行maven命令就行。

开发工具是多元化的,可能他们之间各种构建过程,jar包啥的都不一样,maven就可以给我们提供一个统一的处理解决方案。

把工程放到linux上,在linux上装个mvn,配个mvn环境也能跑起来。