一、前言

由于软件创新实验室讲课要求,所以我写下这篇博文。一方面是为了自己讲课方便,另一方面是为了听课的同学更有目的、更有效率的去听讲。

此篇博客讲的是maven的基础知识以及我在写maven项目时的一些经验和理解。

二、为什么要用maven

相信大家都会经历一个阶段,就是把第三方的jar包导入到自己的项目中。
就比如几天前大家学的jdbc,我们就需要把相应数据库的jar包导入到自己项目里,想想我们是怎么做的——从官网下载jar包(也挺慢的是吧),然后再在项目里创建一个包专门来存储导入的jar包,然后把其设置为项目依赖。
是不是挺烦的?
有人可能又会觉得这其实还能接受。
那你有没有想过用完之后呢?下次还要到官网下?还是自己找个文件夹存起来?
那万一版本变了呢?你要不要重新下载最新版本呢?
那要导入的jar包多了呢?你真的要去官网,去GitHub上把每个都下载起来?
别以为这种情况不多,事实上,一个项目通常有十多个jar包依赖,比如我最近写的个人博客系统

针对这种情况,maven这个jar包管理工具因运而生!

三、什么是Maven

Maven是Apache下的顶级的开源项目(顶级就是指Apache下的项目都是以此为基础开发的),项目管理工具,管理java项目。

作用:
1)管理项目构建生命周期
2)管理项目中jar包
3) 管理项目基础信息(文档管理,测试报告)

特点:
1、项目对象模型 (Project Object Model)

POM对象模型,每个maven工程中都有一个pom.xml文件,定义工程所依赖的jar包、本工程的坐标、打包运行方式。。

2、依赖管理系统(基础核心 )

maven通过坐标对项目工程所依赖的jar包统一规范管理。

3、maven定义一套项目生命周期

清理、初始化、编译、测试、报告 、打包、部署、站点生成

4、一组标准集合

强调:maven工程有自己标准的工程目录结构、定义坐标有标准。

5、maven 管理项目生命周期过程都是基于插件完成的

四、Maven原理(Maven仓库)

1.中央仓库

就是远程仓库,全世界只有一个,仓库中jar包由专业团队(maven团队)统一维护。而它的服务器就在我们的“脚下”,地球的另一端——英国。

中央仓库的地址:http://repo1.maven.org/maven2/

2.***

局域网中的仓库,一般是在公司内部架设一台***,其它公司架设一台仓库,对外公开。

3.本地仓库

本地的仓库,它会存储你曾经从maven仓库中获取的所有jar包依赖,相当于缓存。
maven第一次会从远程仓库(互联网)去下载jar 包,将jar包存在本地仓库(在程序员的电脑上)。第二次不需要从远程仓库去下载。先从本地仓库找,如果找不到才会去远程仓库找。

4.镜像

由于中央仓库服务器离我们太远,再加上访问量大,所以直接重中央仓库下载往往会很慢,甚至下载失败。所以镜像就随之而生,所谓镜像,其实就是中央仓库的复制版,一般选择国内的镜像,这样会使jar下载速率大大提升。
比如阿里的镜像仓库http://maven.aliyun.com/nexus/content/repositories/central/。

5.运行机制

当你项目需要添加依赖时,
maven首先会去你的本地仓库找jar包,如果没有则去局域网中的***仓库找,如果还没有,那就***仓库或者镜像中下载(至于去哪个要看你的配置,具体配置后面会讲)

五、Maven环境搭建

1.Maven下载

可以到maven的官网下载

http://maven.apache.org/download.cgi

我们将下载的压缩包解压到你想要存储的目录下(推荐C盘或者D盘),该根目录会有下面的文件夹apache-maven-3.3.9(具体版本看你下载的文件)

如果不想下载的,也可一下在idea中下载maven插件,这样idea就内置了一个maven

2.本地仓库配置

(1) 创建本地仓库

在你想要存储的地方创建文件夹repository表示本地仓库位置(推荐D盘或者E盘,一般不选C盘)

(2)配置本地仓库

打开maven的安装目录中conf/ settings.xml文件,在这里配置本地仓库:

<localRepository>D:\repository</localRepository>

这里的意思是配置本地仓库的目录为D:\repository

如果你不想下载jar包太慢或者下载失败的话你最好找到

<mirrors></mirrors>

这个标签,在里面加上

<!-- 阿里云镜像 -->
	 <mirror> 
	 <id>alimaven</id> 
	 <name>aliyun maven</name> 
	 <url>http://maven.aliyun.com/nexus/content/repositories/central/</url> 
	 <mirrorOf>central</mirrorOf> 
	 </mirror>
	 
	 <!-- maven官方镜像 -->
	 <mirror>
	 <id>mirrorId</id>
	 <mirrorOf>central</mirrorOf>
	 <name>Human Readable Name </name>
	 <url>http://repo1.maven.org/maven2/</url>
	 </mirror>
	 
	 <!-- junit镜像地址 -->
	 <mirror> 
	 <id>junit</id> 
	 <name>junit Address/</name> 
	 <url>http://jcenter.bintray.com/</url> 
	 <mirrorOf>central</mirrorOf> 
	 </mirror>

这样我们就可以优先重镜像仓库中下载!

六、Maven项目结构

首先我们来创建maven项目

我们选择maven模板,原型选择看你的需求,比如你要创建一个web项目,可以选择

当然我们也可以不选择从原型中创建,这里为了演示,项目结构,我们选择自己创建,点击next,输入你要创建项目的名称

创建完成后我们会看到

.idea是idea中的配置,不用管它,与maven项目无关。

接下来这些才是maven的项目

1.src.main.java

该目录下一般存储源码文件

2.src.main.resources

该目录下存储静态资源,包括图片,各类配置文件(xml、properties、yml等等)

3.src.test

该目录下存储测试时用到的文件,其下一般也有java和resources两个目录,功能跟上面类似。

4.pom.xml

这是maven项目的核心配置文件,位于项目根目录下,配置需要maven相关的配置。

刚创建项目项目时是这样的:

为了便于讲解,我拿我另一个项目——图书信息管理系统的pom.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/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.example</groupId>
  <artifactId>library</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>图书信息管理系统 Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.4</version>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.18</version>
    </dependency>
  </dependencies>

  <build>
    <finalName>图书信息管理系统</finalName>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
      <plugins>
          <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-compiler-plugin</artifactId>
              <configuration>
                  <source>8</source>
                  <target>8</target>
              </configuration>
          </plugin>
      </plugins>

      <resources>
      <resource>
        <directory>src/main/java</directory>
        <includes>
          <include>**/*.xml</include>
          <include>**/*.properties</include>
        </includes>
      </resource>
      <resource>
        <directory>src/main/resources</directory>
        <includes>
          <include>**/*.xml</include>
          <include>**/*.properties</include>
        </includes>
      </resource>
    </resources>
  </build>
</project>

(1)模板版本


modelVersion表示maven模板的版本

(2)项目坐标和打包方式

这里是我这个项目的具体坐标和打包方式

如果要讲清项目坐标,就要岔开去讲一下jar包的项目坐标。

所谓项目坐标,实际上就是定位不同jar包的而制定的一套规则(组织名称+项目名称+版本号),根据这套规则给项目制 定的一个地址,就好像网址一样,比如

这里groupId表示项目团队的名称,一般由org或者com+名称组成,
artifactId表示项目名称,这里我以library作为项目名称,
version表示项目的版本,
packaging表示项目打包方式,你可以打成jar包,也可以打成war包(可以在tomcat容器中运行)

(3)properties属性配置


properties中配置的是项目属性,比如这里我把项目编码设置成utf-8,把编译的版本改成1.7

(4)dependencies依赖配置


这是maven最核心功能,在里面输入相应的坐标就可以导入相应的依赖。

(5)build构建配置

这里配置的是一些构建的信息,可以配置plugins来导入一些插件,也可以配置resources导入一些静态资源。

5.target目录

该目录存储的是项目编译后class文件,项目运行结果以这个为准

七、写Maven项目要注意的几个点

1.静态资源编译

maven项目有个机制,就是静态资源只会加载resources目录下的文件,而且并不是所有文件就可以编译。据我所知,properties、yml格式的配置文件就不能加载进入target目录,这样的话就会造成你明明写了配置文件,可就是找不到的问题(这个问题也困扰我好久,不过经过我多方查找资料最终解决)。

而以后学到的mybatis框架中xml要和mapper文件放在一起,也就是xml要放在src.java下,这就和maven规定冲突,怎么办呢?

解决思路就是要再pom.xml文件中配置resources,将你需要加载进来的文件格式统统配置上,为了方便起见我一般会这么配置

这里我把java目录下的xml文件以及resources目录下的所有格式的文件都编译进来,这样就不怕静态资源无法编译进target目录的问题了!

2.idea中maven插件的使用

当我们maven项目中的pom.xml文件有所更改时
点击这个刷新按钮,它会解决你pom.xml配置的更改,相当于重新读取该配置文件,解决相关的修改(毕竟配置文件是静态的,加载进程序要重新读取)。

然后我简单介绍一下几个常用插件的功能

(1)clean

清除你编译完成的target目录,这时候你会发现target目录不见了

(2)compiler

编译你的项目,这时你会发现你的target目录又出现了

(3)deploy

用于把Maven自动构建生成的版本发布到中央代理仓库如Nexus服务器上,也能把第三方依赖库(如Jar包)或一个独立的Jar包直接发布到中央代理仓库供大家共享使用

(4)install

将一个以linux结尾的文件作为本项目artifact的classifier安装到仓库。

其实用的最多的就是clean和compiler,一般我们重新编译项目都会采取clean+compiler的方式

八、总结

maven其实是一个应用很广的项目管理工具,其出现规范我们项目的结构,使项目本身具有很好的可读性和拓展性。

后面很多框架都是围绕maven来展开的,比如大家后面会学的SpringBoot框架,其结构就是在maven结构的基础上形成的。

所以说学好maven是开发项目的基础!
加油吧!少年!以后的路还很长呢QAQ

愿我们都能以梦为马,不负青春韶华!
与君共勉!

写于2020年8月5日
软件工程1902 金昊霖