Maven学习笔记

Maven

一、Maven简介

1. 什么是Maven

​ maven [ˈmeɪvn] 专家、内行

​ Apache Maven 是一个软件项目管理和构建工具,可以帮助创建和管理项目

​ 基于项目对象模型(POM:Project Object Model)的概念,帮助开发者构建一个项目的完整生命周期

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

2. 为什么使用Maven

  • 项目的管理工具

    项目规模很大时一定会将项目进行拆分,拆分成多个工程,使用Maven在多个工程之间建立依赖关系

  • jar包的管理工具

    通过仓库管理jar包、解决jar包的依赖、自动下载jar包

  • 自动化的构建工具

    编译代码、执行测试、打包、部署等

3. 术语

二、安装Maven

1. 下载安装包

​ 从maven官网下载安装包,这里使用apache-maven-3.6.0-bin.tar.gz

2. 解压安装包

​ 将安装包解压到无中文、无空格的路径下,如:D:\software\apache-maven-3.6.0

​ 配置环境变量,将bin目录添加到Path变量中,如:D:\software\apache-maven-3.6.0\bin

​ 测试,在DOS窗口中执行以下命令:

bash 复制代码
mvn  -version

3. 配置本地仓库

本地仓库的默认位置: ~/.m2/repository(如 C:/Users/登录用户/.m2/repository)

修改本地仓库的位置:编辑conf/setting.xml文件

xml 复制代码
<settings>
  <!--指定本地仓库的位置-->
  <localRepository>D:\maven-repos</localRepository>
</settings>

4. 配置镜像仓库

​ 使用maven时默认从中央仓库下载所需的包(插件),比较慢,可以配置使用阿里云提供的镜像仓库

​ 编辑maven主目录下的/conf/setting.xml文件,在<mirrors></mirrors>标签中添加如下内容:

xml 复制代码
<mirror>
  <id>aliyunmaven</id> <!-- 名称自定义,必须唯一 -->
  <mirrorOf>*</mirrorOf> <!-- 所有访问都使用该镜像仓库 -->
  <name>阿里云公共仓库</name>
  <url>https://maven.aliyun.com/repository/public</url>
</mirror>

5. 配置Maven的JDK版本

​ 修改maven默认使用的jdk版本,编辑conf/setting.xml文件,在profiles标签里面添加如下内容

xml 复制代码
<profile>
  <id>jdk‐1.8</id>
  <activation>
    <activeByDefault>true</activeByDefault>
    <jdk>1.8</jdk>
  </activation>
  <properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
  </properties>
</profile>

三、使用Maven

1. 在IDEA中集成maven

指定Maven主目录和配置文件:Settings------>搜索Maven------>Maven home path和User settings file

注:切换Porject后要重新配置maven

2. 创建maven项目

File------>New------>Module------>Maven Archetype

  • Archetype:maven-archetype-quickstart(Java项目) / maven-archetype-webapp(Java Web项目)
  • GroupId : net.wanho.shop(组织域名反向+项目名称)
  • ArtifactId : shop-product(模块名称)
  • Version : 1.0.1(版本)

3. 目录结构

Maven项目的目录结构如下:

java 复制代码
|-项目名称
	|-src				//程序代码
		|-main			//主代码
			|-java		//源代码
				|-用于存放源代码,相当于传统项目中的src,传统项目的包名.类名,如net.wanho.shop.dao
			|-resources	//配置文件
				|-用于存放配置文件
			|-webapp	//网站根目录
        |-WEB-INF
        	|-web.xml
		|-test			//测试代码,目录结构和main中完全一致
			|-java
			|-resources
	|-pom.xml			//maven核心配置文件

如果没有对应的目录,可以自己创建,但必须符合该目录结构

在IDEA中目录是分类型的,常用的有四种:

  • Sources Root:主代码的目录------>src/main/java
  • Test Sources Root:测试代码的目录------>src/test/java
  • Resources Root:主代码所需资源的目录------>src/main/resources
  • Test Resources Root:测试代码所需资源的目录------>src/test/resources

默认情况下新建的目录是普通的Directory,创建后可以设置目录的类型:

  • 右击目录------>Mark Directory As
  • 每种目录的图标有所不同

4. 执行maven操作

在IDEA中管理所有Maven项目:View------>Tool Windows------>Maven

Maven项目的生命周期:

命令 作用 描述
clean 清理 删除target目录
compile 编译 将main/中的源代码编译成字节码文件,放在target/classes目录下
test 测试 执行测试类(使用JUnit),并生成测试报告,放在target/surefire-reports目录下
package 打包 将java项目打包成jar,将web项目打包成war,放在target目录下
install 安装 将项目的jar包安装到本地仓库,供其他项目使用

注意:

  • 问题:在Maven Projects中项目显示为灰色,表示该maven项目未被管理,不可用
  • 解决:在Maven Projects里点击"+",选择项目对应的pom.xml文件

四、pom.xml文件

1. 简介

​ pom:project object model 项目对象模型

​ pom.xml是Maven的核心配置文件,与项目构建相关的所有配置都在该文件中

2. 坐标

​ 用来唯一的标识每个项目,必须为项目定义坐标,且坐标必须唯一

​ Maven坐标是通过一些元素定义的:groupId、artifactId、version

xml 复制代码
<!--
    坐标:
        groupId:定义组织id,表示当前模块隶属的项目,采用"组织域名反向+项目名称"
        artifactId:定义模块id
        version:定义当前的版本
-->
<groupId>net.wanho.shop</groupId>
<artifactId>shop-product</artifactId>
<version>1.0.1</version>

3. dependency

如何查找一个依赖的坐标?

  • 方式1:在网站上查找 https://mvnrepository.com
  • 方式2:在IDEA中安装maven-search插件,Tools------>Maven Search
  • 方式3:使用uTools工具
xml 复制代码
<!-- dependency基本配置 -->
<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.12</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>fastjson</artifactId>
  <version>1.2.31</version>
  <scope>compile</scope>
</dependency>
<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>javax.servlet-api</artifactId>
  <version>4.0.1</version>
  <scope>provided</scope>
</dependency>
<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>5.1.38</version>
  <scope>runtime</scope>
</dependency>
<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <version>1.18.26</version>
  <scope>provided</scope>
</dependency>

scope表示依赖的作用域,用来配置依赖的jar包的可作用范围,即在什么地方可以使用

取值 含义 举例
compile 表示该依赖可以在整个项目中使用,参与打包部署,默认值 fastjson
test 表示该依赖只能在测试程序中使用,不参与打包和部署 junit
provided 表示编写源代码的时候需要,不参与打包部署 lombok、servlet-api(因为tomcat中已有)
runtime 表示运行时需要,编译代码时不需要 mysql-connector(通过接口反射加载)

4. properties

​ 全局属性,一般情况下用于定义全局的jar的版本

xml 复制代码
<properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <!-- 
       可以自定义标签名,然后使用 ${标签名} 获取标签中的值
       一般情况下用于定义全局的jar的版本,相当于定义全局变量
  -->
  <spring.version>5.3.27</spring.version>
</properties>

<dependencies>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>${spring.version}</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>${spring.version}</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>${spring.version}</version>
  </dependency>
</dependencies>

​ 注:快速将jar包的版本添加到properties中:右击版本号------>Refactor------>Property

5. repositories

​ 用于配置当前工程使用的远程仓库

​ 查找顺序:本地仓库、pom.xml中配置的远程仓库、maven主录下的conf/setting.xml中配置的远程仓库

xml 复制代码
<repositories>
  <!-- 有些jar包,在中央仓库中可能没有,此时可以指定其他可用的远程仓库 -->
  <repository>
    <id>springio</id>
    <url>http://repo.spring.io/milestone/</url>
  </repository>
</repositories>

6. plugins

插件是一种工具,如:

  • maven-clean-plugin插件是用来清理项目的工具
  • maven-compile-plugin插件是用来编译代码的工具

7. 案例

Web应用的开发,模块名称:shop-user

步骤:

  1. 添加依赖

    xml 复制代码
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>4.0.1</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.26</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.31</version>
        <scope>compile</scope>
    </dependency>
  2. 创建HelloServlet类

    java 复制代码
    @WebServlet("/hello")
    public class HelloServlet extends HttpServlet {
    
        @Override
        protected void service(HttpServletRequest req, HttpServletResponse resp) throws IOException {
            System.out.println("hello.............");
    
            Properties p = new Properties();
            p.load(HelloServlet.class.getClassLoader().getResourceAsStream("datasource.properties"));
            System.out.println(p);
    
            User user = new User(1, "张三", 18, "男性", 180.4, new Date());
    
            resp.setContentType("application/json;charset=utf-8");
            PrintWriter out = resp.getWriter();
            out.print(JSON.toJSONString(user));
            out.close();
        }
    }
  3. 创建User类

    java 复制代码
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class User implements Serializable {
        private Integer id;
        private String name;
        private Integer age;
        private String sex;
        private Double height;
    
        @JSONField(format = "yyyy-MM-dd")
        private Date birthday;
    }

注:控制台输出有乱码时,可以设置tomcat的VM options为-Dfile.encoding=utf8

五、Maven中的关系

1. 继承

含义:一个Maven工程继承自另一个Maven工程,分别称为子工程、父工程

场景:实际开发中一个大项目会拆分为多个子项目(子模块/子工程),多个子工程使用的技术基本都相同,即多个子工程中使用的是相同的依赖或插件等配置,此时可以把相同配置抽取到一个父工程中,进行统一管理,保持一致性,简化pom.xml配置

步骤:

  1. 创建三个工程:子工程child01和child02、父工程parent

  2. 将父项目的打包方式设置为pom

    xml 复制代码
    <!-- 
      打包方式
         jar:java项目的打包方式,默认值
         war:web项目的打包方式
         pom:父项目的打包方式
      注:将父工程打包方式设置为pom后,父工程将不会被打包,因此不要在父工程中写java代码,父工程只是用来简化POM配置
        -->
    <packaging>pom</packaging>
  3. 在子项目中引用父项目,指定父项目的坐标,并指定父项目pom.xml文件的路径

    xml 复制代码
    <!-- 引用父项目,指定父项目的坐标 -->
    <parent>
      <groupId>net.wanho.study</groupId>
      <artifactId>parent</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <!-- 指定父项目pom.xml文件的相对物理路径 -->
      <relativePath>../parent/pom.xml</relativePath>
    </parent>

    注:如果子项目的位置是在父项目所在的目录中,则可以省略不配置relativePath项

问题:有时并不是父项目的所有ja包都需要被子项目继承,但又希望能够对依赖进行统一管理,如:jar包版本的控制,怎么办?

解决:配置dependencyManagement

步骤:

  1. 在父项目中配置dependencyManagement

    此时父项目只进行jar包的管理,父项目的jar包默认并不会被子项目继承

    xml 复制代码
    <!-- dependencyManagement表示父项目只进行依赖的管理,依赖默认不会被子项目继承 -->
    <dependencyManagement>
      <dependencies>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.12</version>
          <scope>test</scope>
        </dependency>
        <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>javax.servlet-api</artifactId>
          <version>4.0.1</version>
          <scope>provided</scope>
        </dependency>
        <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          <version>5.1.38</version>
        </dependency>
      </dependencies>
    </dependencyManagement>
  2. 在子项目中引用父项目中的依赖

    如果子项目想继承父项目的jar包,需要在子项目中手动引用,且引用时只需要配置groupId和artifactId,无需指定版本version

    xml 复制代码
    <dependencies>
      <!-- 
       父项目配置dependencyManagement后默认并不会继承过来,需要手动在子项目中引用
       只需要指定groupId和artifactId,无需指定版本version
       可以指定要引用的依赖,并不一定要使用父项目中所有的依赖
       -->
      <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
      </dependency>
      <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
      </dependency>
    </dependencies>

2. 聚合

将多个子项目聚合到一个父项目中,然后通过对该父项目进行操作,从而实现对所有的聚合项目的操作

在父项目中聚合子项目:

xml 复制代码
<!-- 聚合子项目,指定子项目的根目录-->
<modules>
    <module>../child01</module>
    <module>../child02</module>
</modules>

3. 依赖

项目C ---> 项目B ---> 项目A

概念:如果项目C依赖于项目B,项目B依赖于项目A,则项目C也依赖于项目A,这叫依赖的传递

步骤:

  1. 配置依赖关系

    child03------>child02------>child01

  2. 在child01中添加依赖时,child02和child03会传递该依赖,也会出现该依赖

六、Maven综合应用

1. 分析

将项目分为多个工程,可以按层次分,也可以按模块分,或者同时按层次和模块分

以ums为例,使用Maven创建和管理项目:

  • 父工程:ums-parent
  • entity工程:ums-entity
  • dao工程:ums-dao
  • service工程:ums-service
  • web工程:ums-web

2. 步骤

2.1 创建工程
  1. 创建父工程:ums-parent

    File------>New------>Module------>Maven Archetype

    • Archetype:maven-archetype-quickstart

    • GroupId:net.wanho.ums

    • ArtifactId:ums-parent

  2. 创建子工程:ums-entity

    右键ums-parent父工程------>New------>Module

    • Archetype:maven-archetype-quickstart
    • ArtifactId:ums-entity
  3. 创建子工程:ums- dao

  4. 创建子工程:ums-service

  5. 创建子工程:ums-web

    • Archetype:maven-archetype-webapp(Web工程)
2.2 配置依赖
  1. 在父工程中配置依赖管理

    xml 复制代码
    <properties>
      <junit.version>4.12</junit.version>
      <javax.servlet-api.version>4.0.1</javax.servlet-api.version>
      <mysql.version>5.1.38</mysql.version>
      <lombok.version>1.18.26</lombok.version>
      <hutool-all.version>5.8.15</hutool-all.version>
    </properties>
    
    <dependencyManagement>
      <dependencies>
        <!-- junit -->
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>${junit.version}</version>
          <scope>test</scope>
        </dependency>
        <!-- servlet -->
        <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>javax.servlet-api</artifactId>
          <version>${javax.servlet-api.version}</version>
          <scope>provided</scope>
        </dependency>
        <!-- mysql -->
        <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          <version>${mysql.version}</version>
        </dependency>
        <!-- lombok  -->
        <dependency>
          <groupId>org.projectlombok</groupId>
          <artifactId>lombok</artifactId>
          <version>${lombok.version}</version>
          <scope>provided</scope>
        </dependency>
        <!-- hutool -->
        <dependency>
          <groupId>cn.hutool</groupId>
          <artifactId>hutool-all</artifactId>
          <version>${hutool-all.version}</version>
        </dependency>
      </dependencies>
    </dependencyManagement>
  2. 在各个子工程中引用依赖

    ums-entity

    xml 复制代码
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>

    ums-dao

    xml 复制代码
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    
    <!--依赖ums-entity-->
    <dependency>
        <groupId>net.wanho.ums</groupId>
        <artifactId>ums-entity</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>

    ums-service

    xml 复制代码
    <!-- 依赖于ums-dao -->
    <dependency>
        <groupId>net.wanho.ums</groupId>
        <artifactId>ums-dao</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>

    ums-web

    xml 复制代码
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
    <dependency>
        <groupId>cn.hutool</groupId>
        <artifactId>hutool-all</artifactId>
    </dependency>
    
    <!-- 依赖于service -->
    <dependency>
        <groupId>net.wanho.ums</groupId>
        <artifactId>ums-service</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
2.3 数据库
sql 复制代码
drop database if exists ums;
create database ums charset utf8;
use ums;
create table t_user(
	id int primary key auto_increment,
	username varchar(100),
	password varchar(100),
	age int
) engine=Innodb charset utf8;
相关推荐
武子康几秒前
大数据-212 数据挖掘 机器学习理论 - 无监督学习算法 KMeans 基本原理 簇内误差平方和
大数据·人工智能·学习·算法·机器学习·数据挖掘
CXDNW9 分钟前
【网络面试篇】HTTP(2)(笔记)——http、https、http1.1、http2.0
网络·笔记·http·面试·https·http2.0
使者大牙10 分钟前
【大语言模型学习笔记】第一篇:LLM大规模语言模型介绍
笔记·学习·语言模型
ssf-yasuo22 分钟前
SPIRE: Semantic Prompt-Driven Image Restoration 论文阅读笔记
论文阅读·笔记·prompt
As977_32 分钟前
前端学习Day12 CSS盒子的定位(相对定位篇“附练习”)
前端·css·学习
ajsbxi35 分钟前
苍穹外卖学习记录
java·笔记·后端·学习·nginx·spring·servlet
Rattenking35 分钟前
React 源码学习01 ---- React.Children.map 的实现与应用
javascript·学习·react.js
TeYiToKu1 小时前
笔记整理—linux驱动开发部分(9)framebuffer驱动框架
linux·c语言·arm开发·驱动开发·笔记·嵌入式硬件·arm
dsywws1 小时前
Linux学习笔记之时间日期和查找和解压缩指令
linux·笔记·学习
道法自然04021 小时前
Ethernet 系列(8)-- 基础学习::ARP
网络·学习·智能路由器