Maven

Maven项目管理工具

一、Maven概述

1.问题引入

在这里插入图片描述

l 目前存在的问题

运用我们目前学习的技术已经可以开发一个小型的项目了,但是在实际开发中,我们的项目规模要复杂的多,遇到的问题也更多!比如:

1、jar包的管理:多个项目依赖同一个jar包,要复制多次,jar升级时又得重新复制多次,jar之间还可能有多重依赖关系,容易管理混乱

2、项目的管理:项目规模越来越大,需要拆分成多个子模块,模块之间的相互依赖关系需要统一管理,并且项目生命周期中的编译,打包,测试,运行等步骤都需要统一管理

l 如何解决?
在这里插入图片描述

开发一个工具对jar包和项目进行统一的管理,比如:

把jar包都编个坐标,记录并存放在一个地方(这个地方称作为仓库),项目中要用哪个jar就根据坐标来仓库中找就行了;

对项目生命周期和模块进行统一管理,能够自动化的执行编译,打包,测试,运行等操作。

而我们想到的这些解决方案,早就有大牛帮我们实现好了,那就是Maven!

总结:通俗的说:maven就是用来管理jar包+管理项目

注意:这些工具都是帮助/辅助我们工作的,我们最终的开发产出物都是代码

2.初识Maven

l 官网

http://maven.apache.org/

l 百科介绍

在这里插入图片描述

l 说人话

Maven是一个项目管理工具,可以对项目和jar包进行统一个管理,包括:项目的构建(执行项目的生命周期)、项目的生命周期(编译、测试、打包、部署等)、项目的模块依赖关系和jar包的依赖关系

l Jar包管理

l 自动化的项目构建

3.Maven的相关概念

(1)项目对象模型(POM)
Project Object Model:POM对象模型,其实就是一个xml文件,名字叫做pom.xml,每个Maven工程中都有一个pom.xml文件,定义工程(所依赖的jar包)、(本工程的坐标、打包(jar/war)运行方式)。

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

企业使用时,也叫做GAV坐标

Maven的坐标使用如下三个量在 Maven 的仓库中唯一的确定一个jar。

[1] groupid:公司或组织的域名倒序+[当前项目名称]

[2] artifactId:当前项目的模块名称

[3] version:当前模块的版本

例如:要引入junit的测试jar,只需要在pom.xml配置文件中配置引入junit的坐标即可

<dependency>

<groupId>junit</groupId>

<artifactId>junit</artifactId>

<version>4.12</version>

<scope>test</scope>

</dependency>
(2)生命周期

l 清理、编译、测试、报告 、打包、部署、站点生成。
在这里插入图片描述

①清理:删除以前的编译结果,为重新编译做好准备。

②编译:将Java 源程序编译为字节码文件。

③测试:针对项目中的关键点进行测试,确保项目在迭代开发过程中关键点的正确性。

④报告:在每一次测试后以标准的格式记录和展示测试结果。

⑤打包:将一个包含诸多文件的工程封装为一个压缩文件用于安装或部署。Java 工程对应 jar 包,Web工程对应 war 包。

⑥安装:在 Maven 环境下特指将打包的结果——jar 包安装到本地仓库中或把 war包安装到web容器中。

⑦部署:将打包的结果部署到远程仓库或将war包部署到服务器上运行。

(3)Maven项目标准目录结构

Maven是约定思想的体现,约定>配置>编程,maven之前有一个ant工具(告诉它你的源代码在哪个路径下,然后编译输出到哪个路径)

l Maven工程有自己标准的目录结构。

而 Maven 正是因为指定了特定目录保存文件才能够对我们的 Java 工程进行自动化构建(就是自动执行上面的生命周期)。

l 标准目录结构示例

Project

|-src

| |-main

| | |-java —— 存放项目的.java文件

| | |-resources ——存放项目资源文件,如spring, hibernate配置文件

​ |-webapp —— webapp目录是web工程的主目录

​ |-WEB-INF

​ |-web.xml

| |-test

| |-java —— 存放所有测试.java文件,如JUnit测试类

| |-resources —— 测试资源文件

|-target ——目标文件输出位置例如.class、.jar、.war文件

|-pom.xml ——maven项目核心配置文件

在这里插入图片描述

(4)Maven插件

maven 管理项目生命周期过程都是基于插件完成的,例如:开发中使用的tomcat插件。

(5)Maven仓库

在这里插入图片描述

在这里插入图片描述

仓库名称 作用
本地仓库 相当于缓存,工程第一次会从远程仓库(互联网)去下载jar 包,将jar包存在本地仓库(在程序员的电脑上)。第二次不需要从远程仓库去下载。先从本地仓库找,如果找不到才会去远程仓库找。
中央仓库(远程仓库) 是一种远程仓库,仓库中的jar包由专业团队(maven团队)统一维护。里面存放了全世界大多数流行开源软件jar包中央仓库的地址:http://mvnrepository.com/tags/maven
私服(远程仓库) 在公司内部架设一台私服,其它公司架设一台仓库,对外公开。

4.使用Maven的好处

通过上边介绍传统项目和maven项目在项目构建及依赖管理方面的区别,maven有如下的好处:

1、自动构建(生命周期管理):maven对项目构建的过程进行标准化,通过一个命令即可完成构建过程。

2、依赖管理:maven工程不用手动导jar包,通过在pom.xml中定义坐标从maven仓库自动下载,方便且不易出错。

3、跨平台:maven命令可在window、linux上使用,命令无差别。

4、提升效率:遵循maven规范开发有利于提高大型团队的开发效率,降低项目的维护成本,大公司都会考虑使用maven来构建项目。

​ 团队>个人

二、Maven实战

1.安装配置

l 下载

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

l 安装

解压到指定软件安装目录即可

l 目录介绍

bin:存放执行脚本文件的地方

boot:存放一些扩展的地方

conf:maven的核心配置文件存放的路径

lib:maven的依赖包

l 配置环境变量

1、配置JAVA_HOME和MAVEN_HOME

wps8.jpg

2.配置path

在这里插入图片描述

l 验证

在这里插入图片描述

l 配置本地仓库

1576483429511.png

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

指定本地仓库位置(默认在 u s e r . d i r / . m 2 / r e p o s i t o r y , {user.dir}/.m2/repository, user.dir/.m2/repository{user.dir}表示windows用户目录)

​ C:\develop\repository

wps12.jpg

2.指定阿里云镜像位置(中央仓库默认不用配置,此处只是使用阿里云镜像替代中央仓库,提高jar的下载速度)

<mirror>
<id>alimaven</id>
<name>aliyunmaven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>        
</mirror>

wps13.jpg

2.Eclipse关联Maven

wps14.jpg

wps15.jpg

3.IDEA关联Maven

wps16.jpg

4.使用Maven管理项目

l 目录规范

使用maven创建的工程我们称它为maven工程,maven工程具有一定的目录规范,如下:

src/main/java —— 存放项目的.java文件

src/main/resources —— 存放项目资源文件,如spring,hibernate配置文件

src/test/java —— 存放所有单元测试.java文件,如JUnit测试类

src/test/resources —— 测试资源文件

target —— 项目输出位置,编译后的class文件会输出到此目录

pom.xml ——maven项目核心配置文件

l 项目示例

下面是一个完整的使用Maven管理的JavaWeb项目的目录结构

Project

|-src

| |-main

| | |-java —— 存放项目的.java文件

| | |-resources —— 存放项目资源文件,如spring, hibernate配置文件

​ |-webapp —— webapp目录是web工程的主目录

​ |-WEB-INF

​ |-web.xml

| |-test

| |-java ——存放所有测试.java文件,如JUnit测试类

| |-resources —— 测试资源文件

|-target —— 目标文件输出位置例如.class、.jar、.war文件

|-pom.xml ——maven项目核心配置文件

Maven骨架:其实就是maven创建不同的项目结构

wps17.jpg

wps18.jpg

(1)普通Java项目
创建项目

wps19.jpg

wps20.jpg
wps21.jpg

wps22.jpg

编写代码

wps23.jpg

编写测试

wps24.jpg

l 添加Test依赖

可以通过http://mvnrepository.com/tags/maven网址搜索jar包的坐标

<dependencies>
       <dependency>
           <groupId>junit</groupId>
           <artifactId>junit</artifactId>
           <version>4.12</version>
       </dependency>
</dependencies>

配置maven的编译级别

<!--编译插件,可以配置编译版本,因为maven默认是按照1.5进行编译的-->
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
                <encoding>utf-8</encoding>
            </configuration>
        </plugin>
    </plugins>
</build>

测试用例(Use Case):针对一个功能或者一个功能点的测试逻辑

(2)JavaWeb项目
创建项目

wps25.jpg
wps26.jpg
wps27.jpg
wps28.jpg
wps29.jpg

l 解决IntelliJ IDEA创建Maven项目速度慢问题

https://www.cnblogs.com/del88/p/6286887.html

增加属性:archetypeCatalog=internal

或者

全局属性

在maven的VM Options加上 -DarchetypeCatalog=internal 参数,如下:

wps30.jpg

wps31.jpg

完善目录

wps32.jpg

添加依赖
<?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.bigdata</groupId>
   <artifactId>maven_02</artifactId>
   <version>1.0-SNAPSHOT</version>
   <packaging>war</packaging>

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

   <dependencies>
       <dependency>
           <groupId>junit</groupId>
           <artifactId>junit</artifactId>
           <version>4.12</version>
           <scope>test</scope>
       </dependency>
       <!-- Servlet -->
       <dependency>
           <groupId>javax.servlet</groupId>
           <artifactId>javax.servlet-api</artifactId>
           <version>3.1.0</version>
           <!--只需编译无需打包,tomcat自带-->
           <scope>provided</scope>
       </dependency>
       <!-- JSP -->
       <dependency>
           <groupId>javax.servlet.jsp</groupId>
           <artifactId>jsp-api</artifactId>
           <version>2.2</version>
           <!--只需编译无需打包,tomcat自带-->
           <scope>provided</scope>
       </dependency>
       <!-- JSTL -->
       <dependency>
           <groupId>javax.servlet</groupId>
           <artifactId>jstl</artifactId>
           <version>1.2</version>
           <!--只是运行时依赖-->
           <scope>runtime</scope>
       </dependency>
   </dependencies>

   <build>
        <plugins>
           <!--配置编译级别-->
           <plugin>
               <groupId>org.apache.maven.plugins</groupId>
               <artifactId>maven-compiler-plugin</artifactId>
               <version>3.1</version>
               <configuration>
                   <source>1.8</source>
                   <target>1.8</target>
               </configuration>
           </plugin>
           <!--打包跳过单元测试-->
           <plugin>
               <groupId>org.apache.maven.plugins</groupId>
               <artifactId>maven-surefire-plugin</artifactId>
               <version>2.18.1</version>
               <configuration>
                   <skipTests>true</skipTests>
               </configuration>
           </plugin>
           <!-- Tomcat -->
           <plugin>
               <groupId>org.apache.tomcat.maven</groupId>
               <artifactId>tomcat7-maven-plugin</artifactId>
               <version>2.2</version>
               <configuration>
                   <path>/${project.artifactId}</path>
                   <port>8080</port>
               </configuration>
           </plugin>
       </plugins>
   </build>

</project>
编写代码

wps33.jpg

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
   
   @Override
   protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
   
       doPost(req, resp);
   }

   @Override
   protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
   
       resp.getWriter().write(new Date().toString());
   }
}
部署运行

l 添加到外置Tomcat运行

wps34.jpg
wps35.jpg
wps36.jpg
wps37.jpg

http://localhost:8080/hello

l 使用Tomcat插件运行
wps38.jpg

或手动指定命令

wps39.jpg

5.常见Maven命令

(1)clean

clean是maven工程的清理命令,执行 clean会删除整个target目录及内容。

(2)compile

compile是maven工程的编译命令,作用是将src/main/java下的文件编译为class文件输出到target目录下。

(3)test

test是maven工程的测试命令,会执行src/test/java下的单元测试类。

注意:

1、需要注掉pom.xml中打包跳过测试那一段

2、Maven要求测试类放在src/test/java目录下,且测试方法的

类名以Test结尾、方法名以test开头

(4)package

package是maven工程的打包命令,对于java工程执行package打成jar包,对于web工程打成war包。

(5)install

install是maven工程的安装命令,执行install将项目打成jar包或war包发布到本地仓库。

三、Maven扩展

1.Maven的生命周期

l 何为生命周期?

• Maven生命周期就是为了对所有的构建过程进行抽象和统一

• 包括项目清理,初始化,编译,打包,测试,部署等几乎所有构建步骤

l Maven三大生命周期

生命周期Maven有三套相互独立的生命周期,

• clean:在进行真正的构建之前进行一些清理工作

• default:构建的核心部分,编译,测试,打包,部署等等

• site:生成项目报告,站点,发布站点

它们是相互独立的,你可以仅仅调用clean来清理工作目录,仅仅调用site来生成站点。当然你也可以直接运行 mvn clean install site 运行所有这三套生命周期。

wps40.jpg

(1)clean生命周期

clean生命周期每套生命周期都由一组阶段(Phase)组成,我们平时在命令行输入的命令总会对应于一个特定的阶段。比如,运行mvn clean ,这个的clean是Clean生命周期的一个阶段。有Clean生命周期,也有clean阶段。Clean生命周期一共包含了三个阶段:

l pre-clean 执行一些需要在clean之前完成的工作

l clean 移除所有上一次构建生成的文件

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

mvn clean 中的clean就是上面的clean,在一个生命周期中,运行某个阶段的时候,它之前的所有阶段都会被运行,也就是说,mvn clean 等同于 mvn pre-clean clean ,如果我们运行 mvn post-clean ,那么 pre-clean,clean 都会被运行。这是Maven很重要的一个规则,可以大大简化命令行的输入。

(2)site生命周期

l pre-site 执行一些需要在生成站点文档之前完成的工作

l site 生成项目的站点文档

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

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

这里经常用到的是site阶段和site-deploy阶段,用以生成和发布Maven站点,这可是Maven相当强大的功能,Manager比较喜欢,文档及统计数据自动生成,很好看。

(3)default生命周期

l Default生命周期

Default生命周期是Maven生命周期中最重要的一个,绝大部分工作都发生在这个生命周期中。这里,只解释一些比较重要和常用的阶段:

l validate

l generate-sources

l process-sources

l generate-resources

l process-resources 复制并处理资源文件,至目标目录,准备打包。

l compile 编译项目的源代码。

l process-classes

l generate-test-sources

l process-test-sources

l generate-test-resources

l process-test-resources 复制并处理资源文件,至目标测试目录。

l test-compile 编译测试源代码。

l process-test-classes

l test 使用合适的单元测试框架运行测试。这些测试代码不会被打包或部署。

l prepare-package

l package 接受编译好的代码,打包成可发布的格式,如 JAR 。

l pre-integration-test

l integration-test

l post-integration-test

l verify

l install 将包安装至本地仓库,以让其它项目依赖。

l deploy 将最终的包复制到远程的仓库,以让其它开发人员与项目共享。

运行任何一个阶段的时候,它前面的所有阶段都会被运行

这也就是为什么我们运行mvn install 命令的时候,代码会被编译,测试,打包。

注意:default生命周期中不包含clean,开发中如果修改代码后打包运行没有更改的效果,需要重新执行clean命令

2.Maven依赖范围

依赖:项目需要依靠一个jar

依赖范围:依赖一个jar,并不一定是在项目整个生命周期都需要它,可能只是在某一个阶段需要,那么依赖范围就是在定义在哪些阶段依赖这个jar

A依赖B,需要在A的pom.xml文件中添加B的坐标,大家注意到我们之前添加坐标时还有写了一个scope ,这是依赖的范围。

scope有几个可选值, 如:

1、compile: 默认值,表示编译依赖范围。即编译、测试、运行时都需要,会被打包。(默认值compile表明该jar一直全程存在/需要)

2、test:表示测试依赖范围。即测试时需要,编译和运行时不需要,不会被打包。比如:junit。

3、provided:表示已提供依赖范围。即编译、测试时需要,运行时不需要,不会被打包。比如:servlet-api和jsp-api被tomcat容器提供。

服务器本身会提供这些jar,避免和服务器上的这些包冲突

4、runtime:表示运行时提供依赖范围。即编译时不需要,运行和测试时需要,会被打包。比如:jstl、jdbc驱动。

5、system:system范围依赖与provided类似,但是你必须显式的提供一个对于本地系统中JAR文件的路径,需要指定systemPath磁盘路径,system依赖不推荐使用。

wps41.jpg

l 测试各个scope

package打war观察jsp-api和servlet-api是否在war中存在?不在

package打war观察mysql-connctor-java是否在war中存在?在

<dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>4.12</version>
   <scope>test</scope>
</dependency>
<!-- Servlet -->
<dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>javax.servlet-api</artifactId>
   <version>3.1.0</version>
   <!--只需编译无需打包,tomcat自带-->
   <scope>provided</scope>
</dependency>
<!-- JSP -->
<dependency>
   <groupId>javax.servlet.jsp</groupId>
   <artifactId>jsp-api</artifactId>
   <version>2.2</version>
   <!--只需编译无需打包,tomcat自带-->
   <scope>provided</scope>
</dependency>
<!-- JSTL -->
<dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>jstl</artifactId>
   <version>1.2</version>
   <!--只是运行时依赖-->
   <scope>runtime</scope>
</dependency>
<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <version>5.1.40</version>
   <scope>runtime</scope>
</dependency>

l 测试总结:

ü 默认引入 的jar包 —compile 【默认范围 可以不写】(编译、测试、运行 都有效 )

ü servlet-api 、jsp-api —provided (编译、测试 有效, 运行时无效 防止和tomcat下jar冲突)

ü jdbc驱动jar包 —runtime (测试、运行 有效 )

ü junit —test (测试有效)

依赖范围由强到弱的顺序是:compile>provided>runtime>test

总结:

开发中一般使用默认compile即可,如果有错误再进行修改,修改的原则也很简单记住常用的几个provided:servlet和jsp

3.Maven的插件(增强功能)

l Maven的核心仅仅定义了抽象的生命周期,具体的任务都是交由插件完成的,每个插件都能实现多个功能,每个功能就是一个插件目标

l maven插件可以完成一些特定的功能。例如,集成jdk插件可以方便的修改项目的编译环境;集成tomcat插件后,无需安装tomcat服务器就可以运行tomcat进行项目的发布与测试。

l 在pom.xml中通过plugin标签引入maven的功能插件。

<plugins>
  <!-- Compile -->
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.3</version>
    <configuration>
      <source>1.8</source>
      <target>1.8</target>
      <encoding>UTF-8</encoding>
    </configuration>
  </plugin>
  <!-- 打包跳过Test -->
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值