maven基础

1.maven概述

1.maven的介绍

假设你现在做了一个crm的系统,项目中肯定要用到一些jar包,比如说mybatis,log4j,JUnit等

假如有一天你们的项目中mybatis进行了一个升级,但是它内部使用的JUnit没有升级,你升级以后的mybatis假如要用5.0的JUnit,而你项目中目前用的是4.0的,必然会出问题!这个时候管理起来会比较麻烦,你需要各种调整

就会出现几种严重的问题

1.jar包不统一,jar不兼容

2.工程升级维护过程操作繁琐

Maven的本质是一个项目管理工具,将项目开发和管理过程抽象成一个项目对象模型(POM)

Maven是用Java语言编写的。

他管理的东西统统以面向对象的形式进行设计,最终他把一个项目看成一个对象,

而这个对象叫做POM(project object model),即项目对象模型

们说一个项目就是一个对象,作为对象的行为、对象的属性都有哪些呢?

Maven说我们需要编写一个pom.xml文件,Maven通过加载这个配置文件就可以知道我们项目的相关信息了

到这里我们知道了Maven离不开一个叫pom.xml的文件。因为这个文件代表就一个项目

那Maven是如何帮我们进行项目资源管理的呢?这就需要用到Maven中的第二个东西:依赖管理。这也是它的第二个核心

所谓依赖管理 就是maven对项目所有依赖资源的一种管理 ,它和项目之间是一种双向关系,即当我们做项目的时候maven的依赖管理可以帮助你去管理你所需要的其他资源当其他的项目需要依赖我们项目的时候,maven也会把我们的项目当作一种资源去进行管理这就是一种双向关系

那maven的依赖管理它管理的这些资源存在哪儿,主要有三个位置:本地仓库,私服,中央仓库

本地仓库顾名思义就是存储在本地的一种资源仓库,如果本地仓库中没有相关资源,可以去私服上获取,私服也是一个资源仓库,只不过不在本地,是一种远程仓库,如果私服上也没有相关资源,可以去中央仓库去获取,中央仓库也是一种远程仓库

Maven除了帮我们管理项目资源之外还能帮助我们对项目进行构建,管理项目的整个生命周期,这些功能需要使用一些相关的插件来完成,整个生命周期过程中插件是需要配合使用的,单独一个无法完成完整的生命周期

2.maven的作用

1.项目构建:提供标准的,跨平台的自动化构建项目的方式

2.依赖管理:方便快捷的管理项目依赖的资源(jar包),避免资源间的版本冲突等问题

3.统一开发结构:提供标准的,统一的项目开发结构

3.maven的下载与安装

maven的官网:http://maven.apache.org/

官方下载地址:http://maven.apache.org/download.cgi

然后解压,maven是一个绿色软件,解压即安装

各目录结构说明:

bin:可执行程序目录,

boot:maven自身的启动加载器

conf:maven配置文件的存放目录

lib:maven运行所需库的存放目录

环境配置

maven的运行需要java的环境,需要配置JAVA_HOME环境变量

然后需要配置MAVEN_HOME的环境变量

设置-系统信息-高级系统设置-环境变量-新建(系统变量)-变量名:MAVEN_HOME,变量值:maven文件的根目录-打开path-新建:%MAVEN_HOME%\bin

测试:cmd中输入mvn

4.仓库

仓库:用于存储资源,主要是各种jar包

关于仓库,有三种:本地仓库,私服,中央仓库,其中私服和中央仓库都属于远程仓库

中央仓库:maven团队自身维护的仓库,属于开源的

私服:各公司/部门等小范围内存储资源的仓库,私服也可以从中央仓库获取资源

本地仓库:开发者自己电脑上存储资源的仓库,也可从远程仓库获取资源

私服的作用:

1.保存具有版权的资源,包含购买或自主研发的jar

2.一定范围内共享资源,能做到仅对内不对外开放

5.坐标

我们说maven的仓库里存储了各种各样的资源(jar包),那这些资源我们如何找到它们呢?我们需要知道它们具体的一个位置才能知道如何找到它们,这个就叫坐标

坐标:maven中的坐标用于描述仓库中资源的位置

maven仓库地址:https://repo1.maven.org/maven2/

maven坐标的主要组成

groupId:定义当前资源隶属组织名称(通常是域名反写,如:org.mybatis)

artifactId:定义当前资源的名称(通常是项目或模块名称,如:crm,sms)

version:定义当前资源的版本号

packaging:定义资源的打包方式,取值一般有如下三种

(1)jar:该资源打成jar包,默认是jar

(2)war:该资源打成war包

(3)pom:该资源是一个父资源(表明使用maven分模块管理),打包时只生成一个pom.xml不生成jar或其他包结构

需要查询一个maven资源坐标时, 可以在maven仓库查询

https://mvnepository.com/(常用)

在该网站中可直接搜索想要的资源,然后就能得到该资源的坐标

maven坐标的作用:

使用唯一标识,唯一性定义资源位置,通过该标识可以将资源的识别与下载工作交由机器完成

6.本地仓库配置

在D盘创建maven文件夹-在里面创建repository文件夹

找到maven配置文件conf/settings.xml复制在maven文件夹下

修改conf/settings.xml(这个是主配置复制的为子配置)

XML 复制代码
<!-- localRepository
   | The path to the local repository maven will use to store artifacts.
   |
   | Default: ${user.home}/.m2/repository
  <localRepository>/path/to/local/repo</localRepository>
  -->
<localRepository>D:\maven\repository</localRepository>
<!--D:\maven\repository这个目录需要自己创建出来-->

修改后覆盖子配置

注意:局部用户配置(子配置)优先与全局配置(主配置)(遇见相同配置项的时候)

另外需要注意:maven默认连接的远程仓库位置是:https://repo.maven.apache.org/maven2(即中央仓库)

此站点并不在国内,因此有时候下载速度非常慢,因此我们可以配置一个国内站点镜像,可用于加速下载资源

在主配置中找到<mirrors>标签,添加镜像配置

XML 复制代码
<mirror>
    <id>nexus-aliyun</id>
    <mirrorOf>central</mirrorOf>
    <name>Nexus aliyun</name>
    <url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>

然后覆盖子配置

2.做一个maven项目

1.手动搭建一个maven程序

maven工程目录结构

做成如图所示的结构

然后在src/main/java中创建一个包(注意在windos文件夹下就是创建目录)com/ljb,在该目录下创建Demo.java文件,作为演示所需java程序

java 复制代码
package com.ljb;

public class Demo{
	public String say(String name){
		System.out.println("hello "+name);
		return "hello "+name;
	}
}

在src/test/java中创建一个测试包(目录)com/ljb,在该包下创建测试程序 DemoTest.java

java 复制代码
package com.ljb;

import org.junit.*;

public class DemoTest{
	@Test
	public void testSay(){
		Demo d = new Demo();
		String ret = d.say("maven");
		Assert.assertEquals("hello maven",ret);
	}
}

在src同层目录下创建pom.xml(project-java/src)

XML 复制代码
<?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/maven-v4_0_0.xsd">
	
    <!--maven对象模型的版本号-->
    <modelVersion>4.0.0</modelVersion>
	
    <!--自己项目的maven坐标配置-->
    <groupId>com.ljb</groupId>  <!--自己项目的包名-->
    <artifactId>project-java</artifactId> <!--项目名-->
    <version>1.0</version> <!--项目的版本-->
    <packaging>jar</packaging> <!--这个项目开发完最终的目标,可以是作为一个jar包-->

    <!--项目需要依赖的库的坐标-->
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>

</project>

项目构建

项目构建命令

maven的构建命令以mvn开头,后面添加功能参数,可以一次性执行多个命令,用空格分离

mvn compile:编译

mvn clean:清理

mvn test:测试

mvn package:打包

mvn install:安装到本地仓库

1.在项目project-java所在的DOS命令窗口下执行mvn compile进行源码编译,首次执行需要先下载相关插件

bash 复制代码
mvn compile

第一次执行compile命令时,他会先去下载编译所需要的插件

最后会提示BUILD SUCCESS 编译成功

编译完成后在项目project-java下多了一个目录target,在这个目录下就存放的是maven编译好的一些东西

我们可以进入到target目录查看

其中生成的classes目录就是编译好的字节码文件

2.如果我们想清理掉这些东西,我们只需执行mvn clean命令即可,清理掉后target目录也就消失了

3.如果我们要执行测试包中的测试程序,我们只需执行mvn test命令即可

第一次执行test命令,也会下载测试所需要的插件

最后会提示Tests run 1 , Failures:0

这个会提示两次,上边是每一个测试的结果,下边是汇总

此时在看target目录会多一些东西

其中产生的test-classes就是测试代码的字节码文件,surefire-reports是它产生的测试报告

surefire:一定成功的,准不会有错的

txt文件是测试结果的简单描述,与控制台打印的一样

xml是详细信息:包含有测试时的环境,和测试的结果

4.使用mvn package命令进行打包

在生成的target目录中可以看到打包的结果

jar就是打包的结果

当然,如果仔细看DOS窗口输出的我们会发现,mvn package命令的时候maven会把前面两个命令mvn compile,mvn test都执行一遍

使用mvn install命令进行安装,将项目打好的包存入本地仓库

仔细查看输出会发现mvn install命令执行的时候也会将前面的命令都执行一遍

此时我们可以去本地仓库中查找,如何查找?这个很重要

maven是按照groupId/artifactId/version的结构在本地仓库进行存储

这个保存的目录是由坐标决定的:groupId+artifactId+version

5.使用mvn install命令进行安装,将项目打好的包存入本地仓库

查看输出会发现mvn install命令执行的时候也会将前面的命令都执行一遍

此时我们可以去本地仓库中查找,如何查找?这个很重要

maven是按照groupId/artifactId/version的结构在本地仓库进行存储

这个保存的目录是由坐标决定的:groupId+artifactId+version

XML 复制代码
<!--自己项目的maven坐标配置-->
<groupId>com.ljb</groupId>  <!--自己项目的包名-->
<artifactId>project-java</artifactId> <!--项目名-->
<version>1.0</version> <!--项目的版本-->

2.idea创建maven工程

通过命令来构建和管理项目,这在实际开发过程中不常用

常用的是通过相关IDE工具来进行项目的构建和管理,因此我们使用IDEA工具进行maven项目的搭建

需要注意的是:Maven和IDEA在版本上存在一些兼容性问题,因为要合理的选择Maven和IDEA的版本

不使用原型创建项目

1.新建一个空项目

2.点击项目结构SDK设为自己的jdk

3.点击模块-新建模块-点击maven(新建系统)-创建

4.文件-settings-搜索maven-修改Maven home directory-修改User setting file(都改为自己下载的)

会呈现这样的目录结构,若不同则手动修改

5.在最右边有maven的管理目录可以看到对应的生命周期和插件

添加junit坐标:修改pom.xml

XML 复制代码
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
</dependency>

然后刷新会出现依赖项

6.创建源代码:com.maven.Demo

java 复制代码
package com.maven;

public class Demo{
    public String say(String name){
        System.out.println("hello "+name);
        return "hello "+name;
    }
}

7.创建测试代码com.maven.DemoTest

java 复制代码
package com.maven;

import org.junit.Assert;
import org.junit.Test;

public class DemoTest{
    @Test
    public void testSay(){
        Demo d = new Demo();
        String ret = d.say("maven");
        Assert.assertEquals("hello maven",ret);
    }
}

8.编译

在Idea界面右侧Maven -Lifecycle -compile

简化操作

点击当前文件-编辑配置-点击+号-maven-在运行设置你想要操作的(如compile)

然后就可以使用这一组操作

可以设置多个这样的

使用原型创建项目

1.创建java工程

创建maven项目的时候选择使用原型骨架

新建模块-maven archetype-maven-archetype-quickstart(archetype)-创建

maven-archetype-quickstart:就是创建ajva工程的模板(原型)

创建完成后发现通过这种方式缺少一些目录,我们需要手动去补全目录,并且要对补全的目录进行标记

创建后若发现没有src骨架

设置-maven-运行程序-VM选项输入"-Darchetype=Internal"-然后重新创建项目即可

2.创建web工程

选择web对应的原型骨架

与创建Java工程相同只是改为选择webapp原型骨架

同样补全目录

3.tomcat插件安装和web工程启动

web工程创建好之后需要启动运行,需要使用一个tomcat插件来运行项目

清除web.xml与pom.xml的多余部分

在pom.xml中添加

XML 复制代码
<!--构建-->
<build>
    <!--设置插件-->
    <plugins>
        <!--具体的插件配置-->
        <plugin>
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <version>2.1</version>
            <configuration>
                <port>80</port> <!--配置tomcat的端口-->
                <path>/</path><!--配置项目虚拟目录-->
            </configuration>
        </plugin>
    </plugins>
</build>

右侧就会出现tomcat7的命令

双击tomcat7:run运行,然后访问

pom文件说明

XML 复制代码
  <!--指定pom的模型版本-->
  <modelVersion>4.0.0</modelVersion>
  <!--打包方式,web工程打包为war,java工程打包为jar-->
  <packaging>war</packaging>

  <!--组织id-->
  <groupId>com.ljb</groupId>
  <!--项目id-->
  <artifactId>web01</artifactId>
  <!--版本号:release,snapshot-->
  <version>1.0-SNAPSHOT</version>

  <!--设置当前工程的所有依赖-->
  <dependencies>
    <!--具体的依赖-->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13.2</version>
    </dependency>
  </dependencies>

  <!--构建-->
  <build>
    <!--设置插件-->
    <plugins>
      <!--具体的插件配置-->
      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.2</version>
        <configuration>
          <port>80</port>
          <path>/</path>
        </configuration>
      </plugin>
    </plugins>
  </build>
    
</project>

简化运行操作 (与之前提到的相似)

3.maven依赖管理

依赖配置

依赖是指在当前项目中运行所需的jar,一个项目可以设置多个依赖

XML 复制代码
<!--设置当前项目所依赖的所有jar-->
    <dependencies>
        <!--设置具体的依赖-->
        <dependency>
            <!--依赖所属群组id-->
            <groupId>junit</groupId>
            <!--依赖所属项目id-->
            <artifactId>junit</artifactId>
            <!--依赖版本号-->
            <version>4.12</version>
        </dependency>
    </dependencies>

依赖传递

依赖具有传递性

1.直接依赖:在当前项目中通过依赖配置建立的依赖关系

2.间接依赖:被依赖的资源如果依赖其他资源,则表明当前项目间接依赖其他资源

例:

项目2依赖项目3

XML 复制代码
<dependency>
    <groupId>com.ljb</groupId>
    <artifactId>project03</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

项目3添加junit

XML 复制代码
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
</dependency>

依赖传递的冲突问题

在依赖传递过程中产生了冲突,有三种优先法则

1.路径优先:当依赖中出现相同资源时,层级越深,优先级越低,反之则越高

2.声明优先:当资源在相同层级被依赖时,配置顺序靠前的覆盖靠后的

3.特殊优先:当同级配置了相同资源的不同版本时,后配置的覆盖先配置的

可选依赖

可选依赖指对外隐藏当前所依赖的资源--不透明(A引用B依赖,B自己内部提前设置了自己内部依赖是否传递)

XML 复制代码
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <optional>true</optional>
</dependency>

排除依赖

排除依赖指主动断开依赖的资源,被排除的资源无需指定版本--不需要(A引用B依赖时,主动的排除B内部的依赖)

XML 复制代码
<dependency>
    <groupId>com.ljb</groupId>
    <artifactId>project03</artifactId>
    <version>1.0-SNAPSHOT</version>
    <exclusions>
        <exclusion>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
        </exclusion>
    </exclusions>
</dependency>

依赖范围

依赖的jar默认情况可以在任何地方可用,可以通过scope标签设定其作用范围

主要是指以下三种范围

1.主程序范围有效(src/main目录范围内)

2.测试程序范围内有效(src/test目录范围内)

3.是否参与打包(package指令范围内)

scope标签的取值有四种:compile,test,provided,runtime

这四种取值与范围的对应情况如下:

scope 主代码 测试代码 打包 范例
compile(默认) Y Y Y log4j
test Y junit
provided Y Y servlet-api
runtime Y jdbc

compile:任何范围都可以使用

test:只能用于测试

provided:主代码与测试代码可用(provided是提供支持,只给代码提供支持。线上运行不能用,只有在开发测试阶段能够用)

servlet-api不用打包进去,因为代码打包完之后是运行在tomcat中,而tomcat中自带servlet-api这个包

runtime:打包可用(runtime:运行时,这个运行是指定程序上线运行,与provided正好相反)

jdbc这个jar包其实在代码中没有用过,因为我们并没有import导入jdbc中哪个类,只是用了他的类名,Class.forName("com.mysql.jdbc.Driver")

依赖范围的传递性

带有依赖范围的资源在进行传递时,作用范围将受到影响

间接依赖\直接依赖 compile test provided runtime
compile compile test provided runtime
test
provided
runtime runtime test provided runtime

比如:项目1依赖项目2

那么项目1在依赖项目2时配置的范围,是横向的(直接依赖,因为项目1直接依赖了项目2)

那么项目2内部的依赖就属于间接依赖,是纵向的(间接依赖,因为项目1间接依赖了项目2的依赖)

例:

项目1依赖项目2的时候配置范围test

项目2中配置mybatis的范围runtime:结果在项目1中mybatis是test

4.maven生命周期与插件

1.生命周期

maven的构建生命周期描述的是一次构建过程经历了多少个事件

例如:compile -- test-compile -- test -- package -- install

maven对项目构建的生命周期划分为三套

1.clean:清理工作

pre-clean:执行一些在clean之前的工作

clean:移除上一次构建产生的所有文件

post-clean:执行一些在clean之后立刻完成的工作

2.default:核心工作,例如编译,测试,打包,部署等

对于default生命周期,每个事件在执行之前都会将之前的所有事件依次执行一遍

3.site:产生报告,发布站点等

pre-site:执行一些在生成站点文档之前的工作

site:生成项目的站点文档

post-site:执行一些在生成站点文档之后完成的工作,为部署做准备

site-deploy:将生成的站点文档部署到特定的服务器上

2.插件

maven的插件用于执行maven生命周期中的相关事件

插件与生命周期内的阶段绑定,在执行到对应生命周期时执行对应的插件

maven默认在各个生命周期上都绑定了预先设定的插件来完成相应功能

插件还可以完成一些自定义功能

相关推荐
Theodore_10223 小时前
4 设计模式原则之接口隔离原则
java·开发语言·设计模式·java-ee·接口隔离原则·javaee
冰帝海岸4 小时前
01-spring security认证笔记
java·笔记·spring
世间万物皆对象5 小时前
Spring Boot核心概念:日志管理
java·spring boot·单元测试
没书读了5 小时前
ssm框架-spring-spring声明式事务
java·数据库·spring
小二·5 小时前
java基础面试题笔记(基础篇)
java·笔记·python
开心工作室_kaic6 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端
懒洋洋大魔王6 小时前
RocketMQ的使⽤
java·rocketmq·java-rocketmq
武子康6 小时前
Java-06 深入浅出 MyBatis - 一对一模型 SqlMapConfig 与 Mapper 详细讲解测试
java·开发语言·数据仓库·sql·mybatis·springboot·springcloud
转世成为计算机大神6 小时前
易考八股文之Java中的设计模式?
java·开发语言·设计模式
qq_327342737 小时前
Java实现离线身份证号码OCR识别
java·开发语言