Maven
一.简介
1.什么是Maven
Make--》Ant--》Maven--》Gradle
是一个自动化的构建工具专注于服务Java平台项目的构建以及依赖的管理
传统项目存在的问题:
一个项目就是一个工程。
- 如果项目非常庞大,那就不适合用package来划分模块,最好一个模块对应一个工程。
借助于maven将一个项目拆分成多个工程。
jar包需要手动加入
- 同样的jar包会重复出现在不同的工程中。
- 借助maven可以将jar包仅仅保存在仓库中。需要使用的工程引用这个文件,并不需要真的把jar包复制过来。
jar包需要手动下载
- 借助maven可以以一种正规的方式去下载。因为所有知名框架或第三方工具的jar包已经按照统一的规范存在了maven的中央仓库中。
- jar包依赖需要自己管理
2.什么是构建
构建并不是创建一个新的工程而是以Java源文件、配置文件、资源文件等作为原料
去生产一个能够真正运行起来的项目的过程
编译:java源文件--编译--class字节码文件--jvm执行
部署:一个web项目最终运行的并不是web工程本身,而是这个动态web工程“翻译的结果”
搭建
能帮我们清理代码 编译代码 打包项目 部署代码 搭建网页 引入jar包
3.构建的环节
清理clean
- 清除原有的编译结果
- 为重新编译做准备工作
编译compile
- 将一个Java源文件转换成一个字节码文件
测试test
- 针对项目中的每一个功能点进行测试
- 确保项目开发过程中的准确性
报告report
- 生成测试报告
- 每一个功能点的测试完成之后都将生成与之对应的测试报告
打包package
- 对于项目进行打包,用于安装与部署
- java项目打jar包
- web项目打war包
安装install
- 在Maven环境中将你所打的包安装到对应的Maven仓库中
- 便于他人使用
部署deploy
- 将war包部署到对应的服务器(比如tomcat)中
4.Maven优势
获取第三方jar包
- 在我们开发过程中需要使用各种各样的jar包
- 如果一个个的去下载将会非常的麻烦
- 使用Maven之后可以自动帮我们下载
jar包的依赖
- 很多jar包在使用时依赖于其他jar包
- 当项目中jar包比较多,其依赖的jar包也将非常的多
- 此时一个个的下载将会非常的麻烦
- 使用Maven之后可以自动帮我们下载所需要依赖的一切jar包
jar包的管理
- 在我们开发过程中,很多jar包的使用率非常的高
- 因此如果每次都去下载一次比较麻烦
- 可以将这些jar包存放到指定的一个目录中
- 在使用的时候调用该目录下的jar包
- . 该方式Maven已经帮我们实现
项目规模
- 在开发中,有些项目比较庞大,可能一个项目由几百人共同完成
- 此时可以将一个项目分成多个模块
- 通过Maven可以实现这些模块之间的调用与访问
二.配置Maven
1.本地配置
下载对应版本的Maven
windows
xxx.zip
- 将压缩包解压到一个非中文无空格的目录中
配置环境变量
- M2_HOME:maven安装目录
- JAVA_HOME 必须要有
- path
- 配置完成之后通过命令
mvn -version
检查是否配置成功
三.第一个Maven工程
1.定义一个约定的目录结构
|---hello------------------------------------------项目根目录
|-----|------src-----------------------------------源码目录
|-----|-------|--------main------------------------主程序目录,必备目录
|-----|-------|----------|------java---------------主程序的源码目录,必备目录
|-----|-------|----------|------resources----------主程序配置文件目录,可选目录
|-----|-------|--------test------------------------测试程序目录,可选目录
|-----|-------|----------|------java---------------测试程序的源码目录
|-----|-------|----------|------resources----------测试程序的配置文件目录
|-----|------pom.xml-------------------------------Maven核心配置文件
为什么要遵守约定的目录结构?
- maven要负责项目的自动化构建,以编译为例,maven要自动进行编译,必须要知道java源文件保存在哪里。
如果我们自定义的东西要想让工具或者框架知道,以两种方法
- 以明确的配置让框架之道
- 遵守框架内部存在的约定
- 约定大于配置,配置大于编码
2.HelloMaven
package com.itany.maven;
public class HelloMaven{
public String sayHello(){
return "Hello Maven";
}
}
3.TestHello
package com.itany.maven;
import org.junit.Test;
import static org.junit.Assert.*;
public class TestHello{
@Test
public void test(){
HelloMaven hm = new HelloMaven();
String result = hm.sayHello();
assertEquals("Hello Maven",result);
}
}
4.pom.xml
POM--Project Object Model 项目对象模型POM是整个Maven的核心
与Maven相关的一切都在pom.xml中
有了它你就有了一切
与Maven构建相关的配置都在pom中进行
<?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.hy.maven</groupId>
<artifactId>hello</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
5.坐标
坐标是一个Maven工程的核心配置项
每一个Maven工程都必须存在坐标的配置
通过一个坐标可以指定某一个具体的Maven项目
Maven提供了三个坐标向量
groupId
- 组织机构,可以随便写,具有唯一性
- 一般要求使用当前的包名,即域名.[企业名].[产品名].项目名
artifactId
- 模块名称,可以随便写,具有唯一性
- 一般要求使用模块名
version
- 版本号
gav
6.常用命令
通过Maven命令执行对应的工程Maven命令与构建的环节是有对应关系的
在使用与执行构建相关Maven命令的时候,必须进入到Maven工程
pom.xml
文件所在的位置去执行
mvn clean
- 执行清理操作
- 清除原有的编译结果
mvn compile
- 编译主程序代码
- 生成一个classes目录
- 用于存放主程序编译后的字节码文件
mvn test-compile
- 编译测试程序代码
- 生成一个test-classes目录
- 用于存放测试程序编译后的字节码文件
mvn test
- 执行测试
- 生成
surefire-reports
目录,用于存放测试报告
mvn package
- 打包
- 生成对应的jar包或者war包
mvn install
- 安装
- 将对应的maven工程安装到本地仓库
如果没有配置本地仓库,会存放到默认的地址中
- windows:
C:\Users\User\.m2\repository
- linux:
/home/soft/.m2
- windows:
mvn site
- 生成站点
- 生成site目录,该目录中存放文档信息
- 该命令直接使用可能会报错,使用时需要配置对应的插件
- 在对应的Maven工程的pom.xml中进行配置
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-project-info-reports-plugin</artifactId> <version>2.7</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-site-plugin</artifactId> <version>3.3</version> <configuration> <locales>zh_CN</locales> </configuration> </plugin> </plugins> </build>
7.生命周期
在Maven中存在三套完全独立的生命周期
clean (了解)
- 在真正构建之前使用
- 做清理操作
- 只有一个clean命令
default
- 构建的核心部分
- compile、test-compile、test、package、install
- 这套生命周期是存在先后顺序的
- 必须先执行前面的才能执行后面的
- 如果直接执行后面的命令,默认会自动在执行前将该命令之前的所有环节自动执行
site (仅了解)
- 在构建完成之后使用,生成对应的站点
- 主要用于生成对应的API文档信息
- 可以单独使用,与其他命令没有先后顺序
插件和目标:
各个阶段插件和目标是对应的
四.Maven仓库
1.仓库的分类
本地仓库
- 在当前计算机上部署一个仓库目录
- 为当前计算机中所有的Maven工程服务
- 如果Maven工程需要依赖,会优先在本地仓库中查找对应的依赖
如果在本地仓库中找不到了,则会进入远程仓库进行查找
- 找到后会将对应的依赖下载到本地仓库中进行引用
- 当没有对本地仓库进行配置的时候
其默认地址为:
- windows:
C:\Users\当前登录的用户名\\.m2
`
- windows:
远程仓库
私服 Nexus
- 搭建在局域网范围内的Maven仓库
- 一般用于公司内部使用
- 私服为局域网范围内的所有的Maven工程服务
中央仓库
- 搭建在互联网上,为全世界所有的Maven工程服务
maven.apache.org
maven.org
- 由于中央仓库负载太高,开发中一般不建议使用
镜像仓库
- 本质上仍然是中央仓库的内容
- 但是由于中央仓库的负载过高
- 为了分担中央仓库的访问压力,提高用户的访问效率
- 建立了很多的中央仓库的镜像
- 专门用于访问
2.配置本地仓库
在Maven安装目录下的conf目录中存在一个settings.xml文件该文件是Maven的核心配置文件
在该文件中可以对Maven进行全局的配置
localRepository
标签用于配置本地仓库其标签体的值即为本地仓库的地址
如果不指定地址,会使用默认的地址
当指定了地址之后,会使用指定的路径作为本地仓库目录
<!-- 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>本地仓库所在的目录</localRepository>
案例:
<localRepository>D:\maven_repository</localRepository>
3.配置远程仓库
当没有配置远程仓库的时候,默认访问的是maven.apache.org
中央仓库的http://repo.maven.org
由于该中央仓库访问效率较低,可以手动修改默认访问的地址
可以使用效率较高的镜像仓库或者私服
打开settings.xml文件,找到
mirrors
标签该标签用于配置所有的远程仓库
3-1 配置镜像仓库
<mirror>
<id>repo1</id>
<mirrorOf>central</mirrorOf>
<name>Central Repository</name>
<url>https://repo1.maven.org/maven2/</url>
</mirror>
3-2 配置阿里云私服
阿里云私服主页: https://maven.aliyun.com/mvn/view进入主页之后选择右上角的使用指南
找到想要使用的仓库进行配置
<mirror>
<id>alimaven</id>
<mirrorOf>central</mirrorOf>
<name>aliyun maven</name>
<url>https://maven.aliyun.com/repository/central</url>
</mirror>
五.第二个Maven工程
通过Maven命令自动创建约定的目录结构
1.创建工程
进入到存放Maven工程的工作空间中
- 该工作空间必须是一个目录,不能是一个Maven项目
- 当前目录中不能存在pom.xml文件
在该目录下的终端中执行命令构建Maven工程
mvn archetype:generate
命令执行完成之后会出现许多的选项
- 不同的远程仓库出现的选项的序号是不一样的
- 这些选项表示的是各种Maven的骨架模型
- 每一种选项都会提供一个默认,直接回车即表示选择使用默认值
- 根据默认值创建出来的是一个Java工程
- 其骨架模型为:
maven-archetype-quickstart
选择对应的骨架模型之后,会要求用户输入一些必备信息
- groupId:需要用户主动指定
- artifactId:需要用户主动指定
- version:可以主动指定,也可以使用提供的默认
- package:指定当前工程中的包结构,默认使用的与groupId一致
当所有选项输入完毕之后,会需要确认这些信息是否正确
- 如果确定了,输入Y即可
2.调用其他Maven工程
2-1 HelloFriend
package com.itany.maven;
public class HelloFriend{
public String sayHelloToFriend(String name){
HelloMaven hm = new HelloMaven();
String result = hm.sayHello()+",I am "+name;
return result;
}
}
2-2 TestFriend
package com.itany.maven;
import org.junit.Test;
import static org.junit.Assert.*;
public class TestFriend{
@Test
public void test(){
HelloFriend hf = new HelloFriend();
String result = hf.sayHelloToFriend("admin");
assertEquals("Hello Maven, I am admin",result);
}
}
2-3 pom.xml
当调用另一个Maven工程的时候会根据配置中的依赖去本地仓库进行查找
如果没有找到,会去远程仓库进行查询
如果本地仓库与远程仓库均没有找到,将会报错
因此,如果需要调用对应的Maven工程
必须将对应的Maven工程安装到仓库中才能被调用
<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.itany.maven</groupId>
<artifactId>HelloFriend</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.itany.maven</groupId>
<artifactId>hello</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
六.依赖(重点)
1.什么是依赖
在使用Maven工程的时候,工程中会存在一些依赖关系相当于IDEA中的dependencies配置
可能依赖的是第三方jar包,也可能依赖的是另一个Maven工程
我们需要对这些依赖进行配置
根据配置找到对应的资源
查找顺序:本地仓库-->远程仓库
2.依赖的配置
依赖在pom.xml中进行配置
dependencies
标签- 所有依赖配置的父标签
- 配置当前工程中所需要的的所有的依赖
dependency
标签- 配置当前Maven工程所需要的某一个依赖
- 一个
dependency
标签对应一个依赖的配置 其存在一些子标签
groupId
:组织机构artifactId
:模块名称version
:版本号scope
:作用范围
3.scope值
scope标签表示当前依赖的作用范围,其值有五种
compile
- 默认值,当没有配置scope的时候,默认使用compile
- 表示当前依赖对整个项目都生效
- 在编译、运行、测试时均有效
test junit
- 测试作用域
- 表示当前依赖只对测试程序有效
- 测试程序即为test目录中的程序 比如说junit.jar
provided 一般是web项目中,比如说servlet-api.jar,jsp-api.jar包
- 表示当前依赖对整个项目都生效
- 但是该作用范围中的依赖不参与打包与部署
- 在编译、测试时有效,但是在运行时无效
runtime(了解)
- 运行时所依赖
- 在运行、测试时生效,但是在编译时无效
system(了解)
- 在编译、测试时有效,但是在运行时无效
与provided的区别在于
- 使用system范围的依赖必须通过systemPath指定依赖文件的路径
- 由于这种类型的依赖不是通过Maven仓库解析的,而是与本机系统绑定
- 可能造成构建的不可移植
- 因此,该方式不建议使用
<scope>system</scope> <systemPath>${java.home}/lib/rt.jar</systemPath>
4.依赖的特性
依赖的传递性
- 当前Maven工程的依赖如果存在其他依赖
- 会在当前工程中自动下载其对应的依赖
- 如果依赖的范围是test,则不需要下载
- 如果当前工程中本身就有该依赖,则也不需要下载,一般不建议出现
最短距离依赖
- 当当前工程与依赖的工程均包含某个依赖的时候
- 则不会再去下载依赖的工程的某个依赖
- 而是直接使用当前工程的依赖
如果存在多种依赖管理
- 例如:HelloFriend依赖于Hello,HelloThree依赖于HelloFriend
- 此时Hello中存在junit4.11,HelloFriend中存在junit4.12
- 由于HelloFriend距离HelloThree最近,因此选择HelloFriend中的junit4.12
若距离相同,则先声明者优先
依赖的排除
<dependency> <groupId>com.hy.maven</groupId> <artifactId>hellomaven</artifactId> <version>1.0-SNAPSHOT</version> <exclusions> <exclusion> <groupId>dom4j</groupId> <artifactId>dom4j</artifactId> </exclusion> </exclusions> </dependency>
只有scope是compile范围的才能传递
七.IDEA中使用Maven
1.配置Maven
File-->settings-->搜索Maven-->找到Maven对Maven进行配置
Maven Home directory
- Maven安装目录
- 选择本地安装的,不要使用自带的
User settings file
- 用户的Maven的settings配置
- 通过Override选择本地配置好的
Local repository
- 用户的本地仓库
- 通过Override选择本地配置好的
2.创建Maven工程
New --> Module --> 选择对应的Maven骨架与JDK选择完成之后根据提示输入对应的坐标信息,完成创建
3.运行Maven命令
在IDEA窗口的最右边有一个叫做Maven Project的视图打开它可以看到当前所有的Maven工程
通过Lifecycle中运行对应的Maven命令
4.properties标签
全局属性,一般情况下用于同一管理jar包的版本该标签中可以有无数个子标签
每一个子标签都是自定义标签
在pom中其他配置项的位置通过
${标签名}
读取这些自定义标签所对应的标签体的内容
<properties>
<!--servlet.version:自定义-->
<servlet.version>3.1.0</servlet.version>
</properties>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${servlet.version}</version>
<scope>provided</scope>
</dependency>
5.配置当前工程的JDK版本
在工程所对应的pom.xml中配置当前工程的JDK版本如果不配置,将使用maven中配置的全局JDK
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<build>
<plugins>
<!-- 配置JDK -->
<!-- https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-compiler-plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<!-- 配置源代码的开发版本 -->
<source>${maven.compiler.source}</source>
<!-- 配置需要生成的class文件的编译版本 -->
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
</plugins>
</build>
八.web工程
1.创建web工程
New --> Module --> Maven选择对应的web骨架
org.apache.mavem.archetypes:maven-archetype-webapp
在IDEA中创建的web骨架存在一些问题
工程创建完成之后并没有生成对应的约定的目录
- 手动创建两个目录
java
和resources
- 此时创建成功的只是一个普通目录
需要将其设置为功能目录
- 将java目录设置为源码目录
- 将resources目录设置为配置目录
设置方式
- 右键目录选择Make Directory as
- Source Root:源码目录
- Resources Root:配置目录
- 手动创建两个目录
web.xml约束存在问题
- 通过IDEA创建成功的是dtd约束
- 而我们需要将dtd约束改为对应的Schema约束
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> </web-app>
2.工程类型
在pom.xml中,存在一个packaging标签该标签配置当前工程的类型
其值有三种
jar
- 默认值,可以省略
- 表示当前工程是一个Java工程
war
- 表示当前工程是一个web工程
pom
- 表示当前工程是一个父工程
3.J2EE环境依赖
当在开发中需要使用某个依赖的时候可以在对应的远程仓库的网站中进行查找
提供搜索支持的网站:
https://mvnrepository.com/
<!-- J2EE 环境依赖 begin -->
<!-- servlet-api 与jsp-api其scope必须设置为provided -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- J2EE 环境依赖 end -->
4.tomcat插件
<build>
<!-- 配置当前Maven工程中所使用到的插件 -->
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<!-- 配置应用名,在Maven开发中,一般配置空就行 -->
<path>/</path>
<!-- 配置端口号 -->
<port>8080</port>
</configuration>
</plugin>
</plugins>
</build>
5.数据库设计
create database ums;
use ums;
create table t_user(
id int primary key auto_increment,
username varchar(20),
password varchar(50),
phone varchar(20),
address varchar(100)
)engine=Innodb default charset=utf8;
6.数据库依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
7.启动工程
执行maven命令进行打包然后在Maven Project视图中找到对应的Maven工程
在该工程中选择plugins找到tomcat7
找到对应的
tomcat7:run
可以双击直接运行,也可以右键选择运行方式
可以选择正常启动,也可以选择debug模式启动
此时不会直接帮助我们打开浏览器
九.继承与聚合
1.继承
现状:test范围内的依赖不能传递,所以必然会分散在各个模块工程中。很容易造成版本不一致。
需求:同意管理各模块的junit版本
思路:将junit版本依赖提取到“父”工程中,在子工程中声明junit依赖时不指定版本。
继承只存在于父子关系的工程中在Maven,可以定义父子关系的工程
一个父工程可以有无数个子工程
父工程的packaging属性配置为pom
通过父工程可以对子工程进行统一的管理
父工程的创建与创建一个普通的Maven工程方式一致
可以右键父工程创建出对应的子工程
当某个工程存在子工程之后会自动在父工程中配置packaging
- 父工程pom片段
<groupId>com.itany.maven</groupId>
<artifactId>parent</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
子工程pom片段
- 子工程会继承父工程的相关信息
- groupId、version
- 这些标签的值可以重写,但是不建议
<parent>
<artifactId>parent</artifactId>
<groupId>com.hy.maven</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>son1</artifactId>
当在父工程配置了对应的依赖对应的所有的子工程将会自动继承这些依赖
但是有些时候,有些子工程并不需要某些依赖
可以通过
dependencyManagement
标签对依赖的版本进行统一的管理
dependencyManagement标签
- 该标签只能存在于父工程中
- 用于统一管理当前父工程中所有子工程依赖的版本
- 使用该标签,则该标签中所配置的所有依赖不会自动继承到对应的子工程中
只有在子工程中配置了与父工程一致的依赖的时候才会继承
- 此时继承的只是版本号
- 子工程配置依赖的时候不需要设置版本号
2.聚合
一键安装聚合只存在于父工程中
当父工程中存在许多的子工程
这些子工程之间存在依赖关系
在运行时需要按照顺序将这些子工程一一的安装到仓库仓库
当子工程数量较多的时候,安装的时候找顺序比较麻烦
因此,可以在父工程中设置聚合属性
通过聚合可以将聚合属性中所包含的所有工程自动安装
由程序自动获取对应的顺序
系统会自动进行一键安装的操作
聚合可以将父工程与所有的子工程一次性全部安装到仓库中
使用聚合必须在父工程中进行install
<modules>
<module>son1</module>
<module>son2</module>
<module>son3</module>
</modules>
十、nexus搭建私服
1.环境搭建
- 安装服务:
进入D:\学习\框架资源\maven\nexus-2.14.2-01-bundle\nexus-2.14.2-01\bin\jsw\windows-x86-64目录中,双击install-nexus.bat安装服务,注意并不是开启服务
- 启动服务:
start-nexus.bat
stop-nexus.bat--停止
- 测试是否正常
localhost:8081/nexus
- 登录私服
用户名密码:admin,admin123
2.给私服添加代理仓库
1.点repositories-->中上方的add-->proxy repository-->输入id和name,输入aliyun的地址https://maven.aliyun.com/repository/central-->save
2.把上面代理添加到public组内
public repositories-->configuration-->refresh-->把下方aliyun添加到左边,并向上托动
3.把第三方jar包放入私服中
repositories-->3rd party-->artifact upload-->gav中选择agv parameters-->指定groupid,artifactid,version-->packaging选择jar-->select artifact to upload-->找到本地的jar包-->add artifact-->upload artifact