先说一下传统开发(不使用工具管理)有哪些问题
- 模块间互相联系,手工管理关系比较繁琐
- 项目需要的jar包需要自己从网上找
- jar包有版本区别,还得找对应的版本
- jar包之间的依赖错综复杂,手动管理特别复杂
有了maven能怎样?
- 管理jar包,自动下载jar包和文档
- 管理jar包之间的依赖,假如a.jar需要b.jar,maven会自动帮你下载
- 管理你需要jar包的版本
- 帮你编译程序,将java编译为class
- 帮你测试代码是否正确
- 帮你打包文件,打成jar或者war
- 帮你部署项目
- 有了maven后只需要将精力放在写业务代码上即可
项目的构建
构建是面向过程的,是一些步骤,需要完成项目代码的编译,测试,运行,打包,部署等等
maven支持的构建包括
- 清理 把之前项目编译的东西删除掉,为新编译的代码做准备
- 编译 把java文件编译成class文件,是批量的,可以同时javac编译成千上百的java文件
- 测试 maven可以测试代码,验证功能是否正确,也是批量的
- 报告 生成测试结果的文件
- 打包 把项目中所有的class文件和配置文件等所有资源放到一个压缩文件中,这个压缩文件就是项目的结果文件,通常是jar包,对于web应用,扩展名是.war,生成在target目录下,也就是交付给客户的成果,将war文件放到tomcat服务器的webapps目录下启动就可以运行了
- 安装 把上一步生成的jar文件或war文件安装到本机仓库
- 部署 把程序安装好可以执行
maven的核心概念
- POM 一个文件,名称是pom.xml,pom翻译过来是项目对象模型,即maven把一个项目当作一个模型来使用,控制maven构建项目的过程,管理jar依赖
- 约定的目录结构 maven项目的目录和文件的位置都是规定好的
- 坐标 是一个唯一的字符串,用来表示资源
- 依赖管理 管理项目中可以使用的jar文件
- 仓库管理 资源存放的位置
- 生命周期 maven这个工具构建项目的过程
- 插件和目标 执行maven构建的时候用的工具是插件
- 继承 子可以继承父的东西
- 聚合 把好几个项目归纳到一起
安装maven
主要用到
bin目录下的mvn.cmd用来编译
conf目录下的settings.xml用来配置maven的一些设置
记得配置环境变量MAVEN_HOME和path
注意,maven的运行需要有JAVA_HOME,他需要JDK
使用mvn -v查看是否运行成功
maven的目录结构
每一个maven项目在磁盘里都是一个文件夹
Hello
|---src
|---|---main #放主程序java代码和配置文件
|---|---|---java #放程序包和包中的java文件
|---|---|---resources #放配置文件
|---|---test #放测试程序的代码和配置文件(可以没有)
|---|---|---java
|---|---|---resources
|---pom.xml #maven的核心文件
第一次在项目根目录下(pom.xml所在的位置)使用mvn compile命令编译时,会从中央仓库下载东西,因为maven工具执行的很多操作需要插件(java类),形式都是jar文件,下载到了C:\Users\pan.m2\repository这个位置(默认仓库),mvn成功后,会在项目根目录下生成target目录,maven将编译的结果,所有的class文件都放在了该目录下,后面一般会在集成开发环境里直接使用maven,命令很少用
如何修改默认仓库位置呢?
- 修改maven的配置文件,maven安装目录/conf/settings.xml,修改前先备份settings.xml文件
- 修改
<localRepository>指定自己的目录,注意不要使用中文
仓库
用来存放maven所使用的jar和我们项目所使用的jar(如sql驱动)
仓库的分类
- 本地仓库,就是在本机的文件夹
- 远程仓库,在互联网上,需要联网才能使用
- 中央仓库,最权威的,世界上所有开发者都共享使用的集中仓库,在欧洲的服务器上
- 中央仓库的镜像,就是中央仓库的备份,在各大洲和重要的城市都有
- 私服,在公司的局域网中使用,不对外
maven仓库的使用
仓库的使用不需要人为参与,maven自己选择哪个仓库,假如现在需要mysql驱动,先去查本地仓库,没有就去私服,没有再去镜像,最终会访问中央仓库
pom文件
这个pom.xml是maven的灵魂
groupId + artifactId + version = 坐标 (在互联网上是唯一的)
里面有这些东西:
- modelVersion Maven模型的版本
- groupId 组织id,一般是公司域名的倒写
- artifactId 项目名称,也是模块名称,对应groupId中项目中的子项目
- version 项目的版本号,如果项目还在开发中,是不稳定版本通常在版本后带-SNAPSHOT,version使用三位数字标识,例如1.1.0
- packaging 打包后压缩文件的扩展名,默认是jar,web应用是war,不写默认是jar
- dependencies 和 dependency 依赖,相当于java中的import,在依赖标签里写jar包的坐标
- properties 是用来定义一些配置属性的,如project.build.sourceEncoding(项目构建源码编码方式),可以设置为UTF-8,防止中文乱码,也可定义相关构建版本号,便于日后统一升级
- build build表示与构建相关的配置,例如设置编译插件的jdk版本
- parent 继承
- modules 聚合
坐标
groupId + artifactId + version = 坐标 (在互联网上是唯一的)
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
Maven的生命周期
生命周期就是maven构建项目的过程 清理,编译,测试,报告,打包,安装,部署
maven的命令:maven独立使用,通过命令,完成maven的生命周期的执行,maven可以使用命令,完成项目的清理,编译,测试等等
maven的插件:maven命令执行时,真正完成功能的是插件,插件就是一些jar文件,一些类
先了解下junit,是一个专门测试的框架,可以测试类中的方法,每一个方法都可以独立测试,不用跑整个项目,maven可以借助单元测试批量的测试你类中的大量方法是否符合预期的。
单元测试:
- 在pom.xml里加上单元测试的依赖
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
- 在src/test/java目录下,创建测试程序,想测Hello,就写个TestHello的类
1.测试类的名称是 Test + 你要测试的类名
2.测试的方法名称是 test + 方法名称
@Test
public void testSayHello(){
测试
}
其中testAdd叫做测试方法,它的定义规则
1.方法是public的,必须的
2.方法没有返回值,必须的
3.方法名称是自定义的,推荐是Test+方法名称
maven命令
mvn clean 清理(会删除原来编译和测试的目录,即target目录,但是已经install到仓库里的包不会删除)
mvn compile 编译主程序(会在当前目录下生成一个target,里边存放编译主程序之后生成的字节码文件)
mvn test-compile 编译测试程序(会在当前目录下生成一个target,里边存放编译测试程序之后生成的字节码文件)编译main/java/目录下的java为class文件,同时把class拷贝到target/classes目录下面,把main/resources目录下的所有文件都拷贝到target/classes目录下
mvn test 测试(会生成一个目录surefire-reports,保存测试结果)
mvn package 打包主程序(会编译,编译测试,测试,并且按照pom.xml配置把主程序打包生成jar包或者war包)注意,这个jar包下面只有src/main目录下的内容
mvn install 安装主程序(会把本工程打包,并且按照本工程的坐标保存到本地仓库中)
mvn deploy 部署主程序(会把本工程打包,按照本工程的坐标保存到本地库中,并且还会保存到私服仓库中,还会自动把项目部署到web容器中),这个很少用
注意,maven命令不重要,重要的是要会在IDEA中使用maven
在IDEA中配置Maven
一般不用IDEA自带的maven,使用自己安装的maven
设置-->构建执行部署-->构建工具-->Maven
- Maven主路径换成本机安装的maven
- 用户设置文件指的是conf里的settings.xml,换成自己安装的maven的settings.xml
- 本地仓库位置,设置2会自己从配置文件中解析出来,也可以自定义
设置-->构建执行部署-->构建工具-->Maven-->运行程序
- VM选项处可以填入
-DarchetypeCatalog=internal,加快创建项目的速度,因为maven项目创建时,会联网下载模板文件,填入后就禁用下载了 - JRE设置成本机JDK所在的位置
注意,在新项目设置里也得配置相同的步骤,上面只是设置了当前的项目,还都设置以后新建项目的配置
新项目设置-->构建执行部署-->构建工具-->Maven
新项目设置-->构建执行部署-->构建工具-->Maven-->运行程序
Maven在IDEA中创建Java项目
- 新建空项目
- 添加模块
- 选择左侧的生成器---->maven
- 选择模板(Archetype)----->maven-archetype-quickstart(普通Java项目)
- 高级设置:组ID填如com.alibaba,工件ID就是项目名字,版本号也可以自己改
- 创建
-
若没有resources文件夹,可以在main目录下创建resources文件夹,右键标记为资源根目录(Resources Root),用来放配置文件,同样test目录下也可以创建测试资源根目录(Test Resources Root)
-
创建类时若没有提示,则需要右键main和test里的java文件夹,标记为源代码根路径和测试代码根路径标记的话也可以在项目结构里,选项目设置--->模块--->源---->点击文件夹,选择上面要设置成的结构,项目结构里也可以导入导出模块
最右侧有Maven图标,点击可以打开,发现有生命周期,双击对应的生命周期即可运行,假如没有依赖成功,可以右键项目选择重新加载项目试试
pom.xml
<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>
<!--自己的项目坐标(gav),可以改-->
<groupId>com.alibaba</groupId>
<artifactId>test</artifactId>
<version>1.0-SNAPSHOT</version>
<!--将来打包生成的格式,web项目是war-->
<packaging>jar</packaging>
<name>test</name>
<url>http://maven.apache.org</url>
<!--设置一些属性-->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!--编译使用的jdk版本-->
<maven.compiler.source>1.8</maven.compiler.source>
<!--运行需要的jdk版本-->
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<!--依赖-->
<dependencies>
<!--默认加了个单元测试的依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Maven在IDEA中创建Web项目
- 新建空项目
- 添加模块
- 选择左侧的生成器---->maven
- 选择模板(Archetype)----->maven-archetype-webapp(web项目)
- 高级设置:组ID填如com.alibaba,工件ID就是项目名字,版本号也可以自己改
- 创建
要是没有java目录和resources目录可以手动在main目录下创建,右键分别标记为源代码根路径和资源根目录
从此web项目就不用手动去找tomcat里的servlet规范包了,在pom.xml里的依赖标签里写上坐标即可
打包后,扩展名是.war,生成在target目录下,也就是交付给客户的成果,将war文件放到tomcat服务器的webapps目录下启动就可以运行了
依赖的范围
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
依赖标签里的<scope>test</scope>表示这个依赖作用的范围,也就是在哪些阶段起作用
里面的值可以有compile,test,provided
默认是compile编译阶段
provided表示只在编译,测试阶段生效,在打包,安装,部署阶段不需要,因为别人那有这个依赖
| compile | test | provided | |
|---|---|---|---|
| 对主程序是否有效 | 是 | 否 | 是 |
| 对测试程序是否有效 | 是 | 是 | 是 |
| 是否参与打包 | 是 | 否 | 否 |
| 是否参与部署 | 是 | 否 | 否 |
Maven的常用操作
-
maven的属性设置
<!--设置一些属性--> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <!--编译使用的jdk版本--> <maven.compiler.source>1.8</maven.compiler.source> <!--运行需要的jdk版本--> <maven.compiler.target>1.8</maven.compiler.target> </properties> -
maven全局变量
-
在
<properties>通过自定义标签声明变量(标签名就是变量名)<abc>1.0.0</abc> -
在pom.xml文件中的其它位置,使用
${标签名}使用变量的值<version>${abc}</version>
自定义全局变量一般是定义依赖的版本号,当你的项目中要使用多个相同的版本号,先使用全局变量定义,再使用
${变量名} -
-
资源插件
作用:mybatis课程中会用到这个作用
- 默认没有使用resources的时候,maven执行编译代码时,会把src/main/resources目录中的文件拷贝到target/classes目录中,对于src/main/java目录下的非java文件不处理,不会拷贝到target/classes目录中
- 我们的程序有需要把一些文件放在src/main/java目录中,当我在执行java程序时,需要用到src/main/java目录中的文件,需要告诉maven在mvn compile src/main/java目录下的程序时,需要把文件一同拷贝到target/classes目录中,此时就需要在
<build>标签中加入<resources>