Maven

查看原文

<a name="8FDqF"></a>

maven--一种项目自动化构建工具

  • 所谓自动构建,那eclipse举例,eclipse是半自动构建。
  • 全自动构建:包括编译(.java --> .class )、部署(Java project --> Web Project )、jar管理,项目管理等等
  • 半自动构建:eclipse只能做到编译和部署
  • 自动化构建工具有:Make -> Ant -> Maven -> Gradle(从旧到新,Make和Ant已淘汰),Maven主流,用xml配置,Gragle使用自己的语言Groovy配置。
    <a name="feMPN"></a>

基本概念

  1. 仓库

image.png
<br />
<br />总仓库有着几乎全世界的jar包,备份到n个镜像上,分布在世界各地,你可以指定一个离你最近的镜像(如阿里云镜像),写项目时所有用到的jar包(除了jdk)都由maven管理。不用每次都复制粘贴到项目的lib文件夹中,maven首先在本地仓库找,找不到就去私服(局域网,使用nexus搭建)找,再找不到才去镜像(中央仓库)下载。项目也可以放在本地仓库中

  1. 目录结构

maven目录结构为:(以下均为文件夹)<br />

src
main
java

resources
配置文件
** test**
java

resources
配置文件
** pom.xml**

<br />src存放源代码,main是项目代码,java下面就是各个包了,resource是配置文件。<br />test是测试代码,内容结构和main一样。<br />与src同级的是maven配置文件pom.xml。
<a name="CA5Lo"></a>

测试:
package com.ezeta.maven
import org.junit.Test
public class HelloWorld{
    Hello hel = new Hellp();
  //随便调用Hello类一个方法,取得String类型返回值
  String returns = hel.returnmathod();
  //测试返回值是否是“success”
  assertEquals("success",returns);//此步称之为【断言】
}

在maven进行test时,会汇报有多少断言通过,有多少失败。
<a name="D21yO"></a>

配置文件(pom.xml)

这个很重要,maven就靠这个来运行<br />pom.xml是项目对象模型,和dom对比区别在于dom是如html当中一个标签为一个对象。
<a name="omtyt"></a>

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">
    <modelVersion>4.0.0</modelVersion>
    <!-- 上面是模型版本,头和尾标签都是固定的,copy就好 -->
  
  <!-- 继承关系 -->
  <parent>
    <!-- 1.加入父工程的GAV -->
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.5.RELEASE</version>
    <!-- 2.当前工程的pom.xml和父工程pom.xml的绝对路径 -->
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    
  <!-- 以下三个标签简称(GAV)是项目在本地仓库中的定位(坐标) -->
  <!-- groupId:组名称,[反转地址.大项目名称] -->
    <groupId>com.ezeta</groupId>
  <!-- artifactId:小项目名称(模块名称) -->
    <artifactId>signSystem</artifactId>
  <!-- version:项目版本 -->
    <version>0.0.1-SNAPSHOT</version>
    
  <!-- 名字通常和项目(模块)名称一样 -->
    <name>signSystem</name>
  <!-- 项目打包的方式(是jar包还是war包等) -->
    <packaging>jar</packaging>

   <!-- 版本配置 -->
    <properties>
        <java.version>11.0</java.version>
    </properties>

  <!-- 依赖(配置jar包) -->
    <dependencies>
        
        <!-- jdbc -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        
        <!-- druid -->
    <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.13</version>
        </dependency>
    
    </dependencies>

  <!--插件、部署等一系列配置-->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.4.2</version>
                <configuration>
                    <skipTests>true</skipTests>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

(未完待补)

<a name="JNUxs"></a>

常用命令(cmd需在项目pom.xml所在目录执行)

  1. mvn compile --编译main目录中的java文件
  2. mvn test --测试(编译test目录的java文件)
  3. mvn package --打包,java文件打包成jar/war/pom(测试通过才能打包)
  4. mvn install --将开发的模块放入本地仓库,供其他模块使用(放入的位置由GAV决定)
  5. mvn clean --删除target(编译文件)目录
  6. update project --在pom.xml配置完新的依赖后,需要右键项目->Maven->update project来更新依赖

ps:在eclipse中,右键pom.xml点击Run as->Maven build...在Goals里面写上命令,Eclipse就会自动执行命令行(此处不需要写mvn,直接写命令即可),再次点击Run as->****Maven build就可以执行上一次命令。
<a name="cPwwm"></a>

Maven生命周期

举个例子:在Maven命令中,有个package命令,执行后会发现Console里面实际执行了四个个命令:<br />(resource->compile->test->package),这就是生命周期。

  • 当Maven中存在一个命令生命周期顺序:A命令 B命令 C命令 D命令 E命令

执行D命令,实际执行:A B C D

  • 生命周期包含三个阶段(了解):

clean lifecycle:清理<br />pre-clean clean post-clean<br />default lifecycle<br />有非常多命令,省略。。<br />site lifecycle:站点(发布)<br />pre-site site post-site site -dedeploy
<a name="1q1E9"></a>

依赖

  1. 依赖

形如pom.xml中

<dependencies>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>


这种就是依赖,即对jar包的依赖。这里省略了<version></version>,三个标签即GAV来定位jar包。

2. **依赖有效性**

先看这段依赖:

```xml
<dependencies>
    <dependency>
        <groupId>junit</groupId>
    <artifactId>junit</artifactId>
        <version>4.0</version>
    <scope>test</scope>
    </dependency>
</dependencies>

<scope></scope>定义了依赖的范围(有效性),值有三个:<br />compile(不声明则默认这个),test,provided。区别是:<br />
image.png

<br />原因:Maven在编译、测试、运行时,各自使用一套不同的classpath。<br />举个例子,如果我写了个Servlet,此时需要用到Servlet-api.jar,那么我编译时(主程序)会用到这个jar,测试时也会,但是部署时(运行)就不需要了(因为tomcat自带Servlet-api.jar),所以我可以将有效性设置为provide。

  1. 依赖排除

当B.jar依赖于A.jar时,引入B.jar会自动引入A.jar,如果此时依赖是部分依赖,而我只需要没有依赖的部分,那么我引入B.jar时,就不需要A.jar,此时就需要将A.jar排除。

<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.3.18.RELEASE</version>
    <!-- 这个jar会引入beans.jar,aop.jar等等,我们下面将其排除 -->
    <exclusions>
        <exclusion>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
        </exclusion>
    </exclusions>
</dependency>

如上,在dependency标签GAV下面写exclusions标签,标签内写n个exclusion标签,里面是需要排除的jar包的GA(通常不写V,因为排除的肯定是依赖同版本的)。

  1. 依赖传递性

如果A.jar->B.jar->C.jar;<br />那么A.jar->C.jar的充要条件是:但且仅当B.jar->C.jar的范围(有效性)是compile。

  1. 依赖原则
  2. 路径最短优先原则

image.png
<br /> b. 路径相同的情况下:<br />i. 在同一个pom.xml中(路径长度相同),有两个相同的jar(版本不同),则后面声明的覆盖前面声明的。(但是原则上严格禁止在同一个pom中有两个版本不同的依赖)。<br />ii. 在不同的pom.xml中(路径长度相同),分别有两个相同的jar(版本不同),则前面声明的覆盖后面声明的(反过来了)。<br />
image.png

<a name="da5Am"></a>

项目整合

Maven可以将多个项目整合成一个项目,当项目A->项目B时,两者需要通信,只需:1.将A执行install命令(将项目A打包到仓库中);2.然后让B依赖(配置)A就行了。<br />这里需要注意一下:由于Maven的“约定由于配置”,假如B在cn.hello包下的类,依赖调用了A当中cn.hello包下类,此时不需要import,因为Maven已将同样包名的类打包到了一起(哪怕不是同一个文件、甚至不是同一个项目)。<br />

image.png

<a name="YdQ5t"></a>

同一版本&编码

  1. 统一JDK版本

用<profiles><profile></profile></profiles>标签配置,一般不用这个方法,JDK版本管理方法略

  1. 统一依赖版本&编码

一般用变量的方式,动态管理版本。在<properties>配置(JDK也能配置)

<?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">
    <modelVersion>4.0.0</modelVersion>
  
    <groupId>com.ezeta</groupId>
    <artifactId>signSystem</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    
    <name>signSystem</name>

    <properties>
    <!-- JDK版本 -->
        <java.version>11.0</java.version>
    <!-- 编码 -->
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <!-- 统一版本 -->
    <cn.ezeta.jdbc.version>1.2.3</cn.ezeta.jdbc.version>
    <cn.ezeta.druid.version>1.1.13</cn.ezeta.druid.version>
    </properties>

  <!-- 依赖(配置jar包) -->
    <dependencies>
        
        <!-- jdbc -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
      <!--版本使用前面声明的变量动态控制 -->
      <version>${cn.ezeta.jdbc.version}</version>
        </dependency>
        
        <!-- druid -->
    <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
      <!--版本使用前面声明的变量动态控制 -->
            <version>${cn.ezeta.druid.version}</version>
        </dependency>
    
    </dependencies>

</project>

将properties标签写在pom上面,随意命名一个标签(名字最好显而易见,方便他人知道是什么依赖的版本),标签内容即版本号,然后在依赖标签的<version>标签中内容即是类似EL表达式的properties内的自定义标签(变量)。

<a name="RCV7I"></a>

继承

在依赖传递时,需要compile约束,如果使用继承,则子工程可以使用父工程所有依赖。<br />如A->(继承)B,则A能使用B的所有依赖(jar),不用管什么compile。<br />但通常用于更好的版本管理<br />这里需注意:父工程打包方式需要是“pom”(不是jar,不是war)。<br />

image.png
这是一个父工程(已声明pom打包方式),可以看出很简单,没有source文件夹,因为父工程都不写代码,只是在pom中配置一些依赖。

  1. 在父工程中
<dependencyManagement>
  <dependencies>
    <dependency>
      ...
    </dependency>
  </dependencies>
</dependencyManagement>

需要再<dependencies>外面套一层<dependencyManagement>。

  1. 子工程的配置见例子
  2. 子工程需要声明要用到父工程哪些依赖。
<dependency>
<!-- 声明:需要用父类的某jar(只需要写ga即可) -->
<g></g>
<a></a>
</dependency>

<a name="luzBT"></a>

聚合

前面说到,如果A->B则需要将Binstall到仓库中,A才能依赖B,但是如果A依赖很多很多项目,一个个install太麻烦<br />所以有了聚合<br />聚合有个前 置条件:聚合需要配置在一个总工程里面,这个总工程也需要pom方式打包<br />配置方式:

<?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">
    <modelVersion>4.0.0</modelVersion>
  
    <groupId>com.ezeta</groupId>
    <artifactId>project</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    
    <name>project</name>

  <!--聚合配置-->
  <modules>
    <!--需要被聚合的项目根目录的绝对路径-->
    <module>../A</module>
    <module>../B</module>
    <module>../C</module>
  </modules>
    
</project>

在<modules>中每个<module>就是一个要聚合的项目,即当启动这个总项目时,会自动按合适的顺序将<modules>内的项目依次全部启动(这里合理的顺序maven会自动按依赖关系判断,不需要特地写module的顺序),于是当启动A之前会先启动B,那么A就可以依赖B了,这样就不用一个个install了。<br />聚合的本质就是,对总工程进行什么操作,就相当于对所有聚合工程按合适的顺序依次或同时进行一样的操作(如install,package等等)
<a name="GqCa4"></a>

部署Web项目

  • <build>标签配置cargo插件
  • mvn命令deploy(部署)

实际开发中,还是不太会用cargo,一般还是开发工程师打包成war包后交给实施工程师部署。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Maven编译代码的相关命令 第一、main目录下的主代码编写完毕后,使用Maven进行编译,在项目根目录下运行命...
    加油小杜阅读 1,299评论 0 2
  • Maven的基本了解 什么是Maven? Maven就是Apache下的一个开源项目。它是用纯java开发的。是一...
    Bcome阅读 2,919评论 0 7
  • |-1-更新内容[6.从仓库解析依赖的机制(重要)] 1Maven仓库作用 仓库用来存储所有项目使用到构件,在ma...
    zlcook阅读 6,227评论 0 25
  • 收听简书播客#所以我们还是好好活着吧 作者简书主页 我有一个永远16岁的朋友,记忆中她微笑着说我很难爱上一个人,我...
    纪不了阅读 383评论 3 2
  • 配置并连接数据库 .env 文件中数据库的配置 数据库的连接 对数据库进行操作
    周怡阅读 198评论 0 0