Maven的使用
1.为什么要使用Maven
1.一个项目就是一个工程
- 带来的问题是如果项目非常大,就不适合继续使用package来划分模块,最好是每一个模块对应一个工程,利于分工协作
- Maven的解决:Maven就可以把一个项目分成多个工程
2.项目中需要的jar包必须手动“复制”,“粘贴”到WEB-INF/lib目录下
- 带来的问题是:同样的jar包文件重复出现在不同的项目工程中,一方面浪费存储空间,另外也让工程比较臃肿
- Maven的解决:借助Maven,可以将jar包仅仅保存在“仓库”中,有需要使用的工程引用这个文件接口,并不需要真的把jar包复制过来
3.jar包需要别人替我们准备好,或者到官网下载
- 带来的问题:如果是以不规范的方式下载的jar包,那么其中的内容很可能也是不规范的
- Maven的解决:借助Maven可以以一种规范的方式下载jar包,因为所有知名框架或第三方工具的jar包已经按照统一的规范存放在Maven的中央仓库中
4.一个jar包依赖的其他jar包需要自己手动加入到项目中
- 带来的问题:如果所有jar包之间的依赖关系都需要程序员自己非常清楚的了解,那么就会极大的增加学习成本
- Maven的解决:Maven会自动将被依赖的jar包导入进来
2.Maven是什么
概述:Maven是一款服务于平台上的自动化构建工具
什么是构建
概述:以“java源文件”,“框架配置文件”,“HTML”,“图片”等资源为“原材料”,去生产一个可以运行的项目的过程,一个可以运行的项目包括三个步骤,编译、部署和搭建,需要注意的是一个BS项目最终运行的并不是动态Web工程本身,而是这个动态web工程“编译的结果”
构建过程中的各个环节
- 清理:将以前编译得到的旧的class字节码文件删除,为下一次编译做准备
- 编译:将java源程序编译成class字节码文件
- 测试:自动测试,自动调用Junit程序
- 报告:测试程序执行的结果
- 打包:动态Web工程打war包,java工程打jar包
- 安装:Maven特定的概念--将打包得到的文件复制到“仓库”中的指定位置
- 部署:将动态web工程生成的war包复制到Servlet容器的指定目录下,使其可以运行
3.Maven的下载与安装
Maven的下载官网:https://maven.apache.org/
安装:
- 解压从官网下载的Maven
- 配置Maven相关的环境变量
- MAVEN_HOME(bin目录的上一层目录)
- path(需要到bin目录)
4.Maven的核心理念
- 约定的目录结构
- POM
- 坐标
- 依赖
- 仓库
- 生命周期/插件/目标
- 继承
- 聚合
5.第一个Maven工程
1.创建约定的目录结构:
Hello
|--src
|--|--main
|--|--|--java
|--|--|--resources
|--|--test
|--|--|--java
|--|--|--resources
|--pom.xml
路径说明:
- 根路径:工程名
- src目录:源码
- pom.xml文件:Maven工程的核心配置文件
- main目录:存放主程序
- test目录:存放测试程序
- java目录:存放java源文件
- resources目录:存放框架或其他工具的配置文件
2.为什么要遵守约定的目录结构?
- Maven要负责我们这个项目的自动化构建,以编译为例,Maven想要自动进行编译,那么它必须知道java源文件保存在哪里,而Maven内部的约定就告诉了他这件事情
- 如果我们自己自定义的东西想要让框架或工具知道,有两种办法:以配置文件明确告诉框架、遵守框架内部已经存在的约定;我们需要学习到的是,当我们有框架内部已经存在的约定,我们优先选择使用这个约定,如果没有,再用配置文件,最后才选择直接编码的方式;
3.环境部署
按目录结构建完目录;
pom.xml里写:
<?xml version="1.0" ?>
<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.luyi.maven</groupId>
<artifactId>Hello</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Hello</name>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.0</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
在Hello\src\main\java\com\luyi\maven\新建一个Hello.java文件:
package com.luyi.maven;
public class Hello {
public String sayHello(String name){
return "Hello "+name+"!";
}
}
在Hello\src\test\java\com\luyi\maven\新建一个HelloTest.java文件:
package com.luyi.maven;
import org.junit.Test;
import static junit.framework.Assert.*;
public class HelloTest {
@Test
public void testHello(){
Hello hello = new Hello();
String results = hello.sayHello("litingwei");
assertEquals("Hello litingwei!",results);
}
}
4.运行几个基本的Maven命令:
- mvn compile 编译主程序
- mvn test-compile 编译测试程序
- mvn clean 清理
- mvn test 测试
- mvn package 打包
- mvn install 安装
- mvn site:生成站点
- mvn deploy:部署
注意:运行Maven命令时一定要进入pom.xml文件所在的目录!
关于Maven联网下载的问题
1.Maven的核心程序中仅仅定义了抽象的生命周期,但是具体的工作必须由特定的插件来完成,而擦肩本身并不包含在Maven的核心程序中
2.当我们执行的Maven命令需要用到某些插件时,Maven核心程序会首先到本地仓库中查找
3.本地仓库的默认位置:C:\User[登录当前系统的用户]\.m2\repository
4.Maven核心程序如果在本地仓库中找不到需要的插件,那么它会自动连接外网,到中央仓库下载
5.如果无法连接外网,则构建失败
6.修改默认本地仓库的位置,可以让Maven核心程序到我们事先准备好的目录下去找这些插件
- 找到Maven解压目录\conf\settings.xml
- 在settings.xml文件中找到localRepository标签
- 将 <localRepository>/path/to/local/repo</localRepository>从注释中取出来
- 将标签体内容修改为我们已经准备好的Maven仓库目录
6.Maven的核心理念的解读
约定的目录结构
概述:也就是我们前面说的那个目录结构
POM
概述:POM就是Project Object Model:项目对象模型,而我们的pom.xml文件是我们Maven工程的核心配置文件,与构建过程相关的一切设置都在这个文件中进行配置,重要程度相当于web.xml对于动态web工程
坐标
概述:Maven的坐标就是使用下面三个向量在仓库中唯一定位一个Maven工程
- groupid:公司或组织域名倒序+项目名
- artifactid:模块名称
- version:版本
代码示例:
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.0.0.RELEASE</version>
根据这个坐标,去仓库里面找到对应的jar包:以上这个代码例子所对应的仓库的jar包为:org/springframework/spring-core/4.0.0.RELEASE/spring-core.4.0.0.RELEASE.jar
仓库
仓库的分类:
- 本地仓库:当前电脑上部署的仓库目录,为当前电脑上所有Maven工程服务
- 远程仓库
- 私服:搭建在局域网环境中,为局域网范围内的所有Maven工程服务
- 中央仓库:架设在Internet上,为全世界所有Maven工程服务
- 中央仓库镜像,为了分担中央仓库的流量,提升用户访问速度
依赖
概述:Maven解析依赖信息时会到本地仓库中查找被依赖的jar包,对于我们自己开发的Maven工程,使用mvn install命令安装后就可以进入仓库
依赖范围:
- compile
- 对主程序有效
- 对测试程序有效
- 参与打包
- 参与部署
- test
- 对主程序无效
- 对测试程序有效
- 不参与打包
- 不参与部署
- 典型例子:junit
- provided
- 对主程序有效
- 对测试程序有效
- 不参与打包
- 不参与部署
- 典型例子:servlet-api.jar
代码示例:
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<!--依赖范围-->
<scope>provided</scope>
</dependency>
</dependencies>
生命周期
概述:各个构建环节执行的顺序就是生命周期,它的构建环节是不能打乱的,必须按照既定的正确顺序执行,我们执行的mvn命令他都会从头开始执行,如执行测试前,他会先执行编译,执行编译前先执行清理,他都是从头开始执行的;
插件和目标:
概述:生命周期的各个阶段仅仅定义了要执行的任务是什么,各个阶段和插件的目标是对应的,相似的目标由特定的插件来完成
依赖【高级】
依赖的传递性:
依赖的传递性的好处:可以传递的依赖不必在每一个模块工程中都重复声明,在依赖关系里“最下面”的工程中依赖一次即可
注意:非compile范围的依赖不能传递,所以在各个工程模块中,如果有需要就得重复声明依赖
依赖的排除:
概述:当我们依赖了不稳定的jar包,想排除掉它时,就可以使用依赖的排除排除掉它
依赖排除的设置:
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
依赖的原则:
作用:解决模块之间的jar包冲突问题
原则1:路径最短在优先原则
原则2:路径相同时,先声明者优先(先声明者就是dependency标签靠前jar包)
统一管理依赖的版本号,字符集等
1.写一个proerties标签配合自定义标签声明数据:
<properties>
<!-- 设置统一的依赖版本号 -->
<luyi.spring.version>4.1.1.RELEASE</luyi.spring.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
2.在需要统一某个东西的地方,使用${自定义标签}引用声明的版本号
<version>${luyi.spring.version}</version>
继承
问题:当我们各个工程依赖的Junit包不一样时,由于test范围的依赖不能传递,所以必然会分散在各个模块中,很容易造成版本不一致
需求:统一管理各个模块工程中对junit依赖的版本
解决思路:将junit依赖统一提取到“父”工程中,在子工程中声明依赖时不指定版本,以父工程中统一设定的为准,同时也便于修改
操作步骤:
1.创建一个Maven工程作为父工程,注意:打包的方式为pom
<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.luyi.maven</groupId>
<artifactId>Parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
</project>
2.在子工程中声明对父工程的引用
<!-- 声明对父工程的引用 -->
<parent>
<groupId>com.luyi.maven</groupId>
<artifactId>Parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!-- 以当前工程的pom.xml文件为基准的父工程pom.xml文件的相对路径 -->
<relativePath>../Parent/pom.xml</relativePath>
</parent>
3.将子工程的坐标与父工程的坐标中重复的内容删除(会有黄线提示删除)
4.在父工程中统一junit依赖
<!-- 配置依赖的管理 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.0</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
5.在子工程中删除junit依赖的版本号部分(有黄线提示)
注意:配置继承后,想要安装子工程时,必须先安装父工程
聚合
作用:一键安装各个模块工程
配置方式:在一个“总的聚合工程”中配置各个参与聚合的模块( )
<!-- 配置聚合 -->
<modules>
<module>../webProject01</module>
<module>../Good</module>
</modules>
使用方式:在聚合工程的pom.xml上点右键-》run as-》maven install,即可把配置在聚合里的工程一键安装
7.在Eclise中使用Maven
Maven插件的设置
Maven插件:Eclise已经内置有这个插件了
Maven插件在eclise的一些设置(window--preferences--Maven中进行设置):
- installations:指定Maven核心程序的位置,不建议使用插件自带的Maven程序,而应该使用我们自己下载解压的那个
- user settings:指定Maven下载路径下的conf/settings.xml的位置,进而获取本地仓库的位置
Maven在eclise的基本操作
- 创建Maven版的java工程
- 创建Maven版的web工程
- 执行Maven命令(右键pom.xml文件后Run as,选择你要执行的mvn命令)
注意:在我们新建一个jsp文件时,会报错,这是由于缺少了servlet-api包导致的,在opm.xml文件中加入这个依赖包即可消除这个报错
8.Web工程的自动部署
概述:部署Maven工程时可以通过打包工程再复制到tomcat的webapps目录下进行部署,也可以通过配置文件进行自动部署
自动部署的步骤:
1.配置自动部署:设置在要自动部署的工程的pom.xml中:
<build>
<finalName>AtguiguWeb</finalName>
<plugins>
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>1.2.3</version>
<configuration>
<container>
<containerId>tomcat6x</containerId>
<home>D:\DevInstall\apache-tomcat-6.0.39</home>
</container>
<configuration>
<type>existing</type>
<home>D:\DevInstall\apache-tomcat-6.0.39</home>
<!-- 如果Tomcat端口为默认值8080则不必设置该属性 -->
<properties>
<cargo.servlet.port>8989</cargo.servlet.port>
</properties>
</configuration>
</configuration>
<executions>
<execution>
<id>cargo-run</id>
<phase>install</phase>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
2.在eclise中右键pom.xml-》Run As-》Maven Build-》depoly(在Goals输入depoly)
注意:在eclise中自动部署到tomcat时,只管开启,是不管关闭的,而且提示信息打印在控制台有乱码,因此自动部署比较适合用cmd命令(进入到工程目录中运行mvn depoly进行部署)
9.Maven酷站
在http://mvnrepository.com/搜索需要的jar包的依赖信息
作者:卢一
出处:http://www.cnblogs.com/luyi001/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。