Maven是什么
Maven是一款服务于Java平台的自动化构建工具
- Make->Ant->Maven->Gradle
(妹文, 麦文)
- 构建
-
- [1]概念:以 “java源文件”,”框架配置文件”,”jsp”,”HTML”,”图片” 等资源为”原材料” 去 “生产” 一个可以运行的项目的过程.
-
编译 部署 搭建
-
-
- [2]编译: Java源文件[User.java]->编译->Class字节码文件[User.class]->JVM执行
- [3]部署:一个BS项目最终运行的并不是动态Web工程本身,而是这个动态Web工程”编译的结果”。
-
Tips:运行时环境:JRE System Library, Apache Tomcat v6.0[xx];其实是一组Jar包的引用
- 构建过程中的各个环节:
- 清理
将以前编译得到的旧的class字节码文件删除,为下一次编译做准备
- 编译
将Java源文件编译成class字节码文件
- 测试
自动测试,自动调用junit程序
- 报告
测试程序中执行的结果
- 打包
动态Web工程打war包,Java工程打jar包
- 安装
Maven特定的概念---将打包的到的文件复制到仓库中制定的位置
- 部署
将动态Web工程生成的war包复制到servlet容器的指定目录下,使其可以运行
按照Maven核心程序
- 检查JAVA_HOME 环境变量
- 解压Maven核心程序的压缩包,解压到非中文,无空格的路径下
- 配置Maven的环境变量
MAVEN_HOME 或 M2_HOME
path
配置成功后:
C:\Users\任志江>mvn -v
Apache Maven 3.2.2 (45f7c06d68e745d05611f7fd14efb6594181933e; 2014-06-17T21:51:42+08:00)
Maven home: D:\using\DEV-INSTALL\apache-maven-3.2.2
Java version: 1.8.0_101, vendor: Oracle Corporation
Java home: D:\Java\jdk1.8.0_101\jre
Default locale: zh_CN, platform encoding: GBK
OS name: "windows 10", version: "10.0", arch: "amd64", family: "dos"
Maven的核心概念
约定的目录结构
POM
坐标
依赖
仓库
生命周期/插件/目标
继承
聚合
第一个Maven工程
创建约定的目录结构
Hello
|---src
|---|---main
|---|---|---java
|---|---|---resources
|---|---test
|---|---|---java
|---|---|---resources
|---pom.xml
根目录:工程名称
src目录:源码
main目录:存放主程序
test目录:存放测试程序
java:存放java源文件
resource目录:存放框架或其他工具的配置文件
为什么要遵守约定的目录结构:Maven要负责自动化构建的过程;如果我们自定义的东西想要让框架或工具知道,有两种:1.配置2.约定
常用命令
mvn clean:清理
mvn compile:编译主程序
mvn test-compile:编译测试程序
mvn test:执行测试
mvn package:打包
mvn install :安装我们编写的Maven工程到本地仓库
mvn site :生成站点
※注意:运行Maven命令时一定要进入pom.xml文件所在的目录!
关于联网的问题
1.Maven的核心程序中仅仅定义了抽象的生命周期,但是具体的工作必须由特定的插件来完成。而插件本身并不包含在Maven的核心程序中。
2.当我们执行的Maven命令需要用到某些插件时,Maven核心程序会首先到本地仓库中查找。
3.本地仓库的默认位置:[系统中当前用户的家目录]\.m2\repository
4.Maven核心程序如果在本地仓库中找不到需要的插件,它会自动连接到外网到中央仓库下载,如果此时无法连接到外网,则构建失败
5.修改默认本地仓库的位置,可以让Maven核心程序到我们事先准备好的目录下查找插件
1.找到Maven解压目录下的\conf\settings.xml
2.<localRepository>/path/to/local/repo</localRepository>
3.修改即可
POM
含义:Project Object Model 项目对象模型
DOM 文档对象模型
pom.xml 对于Maven对于Maven工程是核心的配置文件,与构建相关的一切设置都在这个文件中进行设置。重要程度相当于web.xml 对于动态web工程
坐标
- 数学中的坐标
1.1在平面上使用X,Y两个向量可以唯一定位平面中的任何一个点,在空间中使用XYZ三个向量可以定位空间中的任何一个点。
1.2Maven 使用三个向量在仓库中定位一个Maven工程(G A V)
[1]groupid :公司或组织域名倒叙+项目名
<groupid>com.atguigu.maven</groupid>
[2]artifactid:模块的名称
<artifactid>Hello</artifactid>
[3]version:版本ID
<version>1.0.0</version>
- Maven工程中的坐标与仓库中路径的对应关系
<groupid>org.springframework</groupid>
<artifactid>spring-core</artifactid>
<version>4.0.0.RELEASE</version>
org/springframework/spring-core/4.0.0.RELEASE/spring-core-4.0.0.RELEASE.jar
仓库
- 本地仓库:当前电脑上部署的仓库目录,为当前电脑上所有Maven工程服务
- 远程仓库:
- 私服
私服是搭建在局域网内,为当前局域网范围内的所有Maven工程服务。(Nexus)
-
- 中央仓库 :架设在Internet上,为全世界所有的Maven工程服务
- 中央仓库的镜像:假设在各个大洲,为中央仓库分担流量。减轻中央仓库的压力,同时更快响应用户请求
- 仓库中保存的内容:Maven工程
[1]Maven自身需要的插件
[2]第三方框架或工具的jar包(第一方:jdk, 第二方:我们)
[3]我们自己开发的Maven工程
依赖
Maven解析依赖信息时会去本地仓库中查找
对于我们自己开发的Maven工程,使用mvn install命令安装到本地仓库
main |
依赖的范围:
Maven程序 |
test |
compile范围的依赖 |
test范围的依赖 |
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.atguigu.maven</groupId>
<artifactId>Hello</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
- compile
对主程序是否有效: 有效
对测试程序是否有效:有效
是否参与打包:参与
- test
对主程序是否有效: 无效
对测试程序是否有效:有效
是否参与打包:不参与 (junit)
- provided
对主程序是否有效: 有效
对测试程序是否有效: 有效
是否参与打包:不参与,不参与部署: servlet-api.jar
部署 |
忽略 |
开发 |
部署 |
运行 |
compile范围的依赖 |
运行 |
由Servlet容器提供 |
开发 |
provided范围的依赖 |
依赖的传递性
HelloFriend依赖Hello
Hello 中导入了spring的依赖
HelloFriend自动有了spring的依赖
好处:可以传递的依赖不需要在每个模块工程中都重复声明,在”最下面”的工程中依赖一次即可
注意:非compile范围的依赖不能传递
依赖的排除
在某个dependency内
<exclusions>
<exclusion>
<artifactId>el-api</artifactId>
<groupId>javax.el</groupId>
</exclusion>
</exclusions>
即排除了相关的依赖
依赖的原则
[1]作用:解决模块工程之间的jar包冲突问题
路径最短者优先原则:
MakeFriends |
HelloFriends |
Hello |
log4j.1.2.14
|
log4j.1.2.14
|
log4j.1.2.17 |
上面三个项目展现一个依赖关系
路径:MakeFriends到log4j.1.2.14的路径比到log4j.1.2.17短
Hello依赖log4j.1.2.17
HelloFriends依赖log4j.1.2.14
MakeFriends 依赖HelloFriends,所以MakeFriends自动附加依赖log4j.1.2.14
(如果MakeFriends就需要log4j.1.2.17,直接声明即可)
路径相同时,先声明者优先
先声明指的是:dependency标签的申明顺序
MakeFriends |
HelloFriends |
log4j.1.2.14 |
OurFriends
|
log4j.1.2.17 |
在MakeFriends 的pom.xml文件中,那个依赖项在前面,就用哪个的log4j
统一管理依赖的版本号
这里对spring的各个jar包的依赖版本都是4.0.0 如果统一升级4.1.1 ,如何做?
- 使用properties 标签使用自定义标签统一声明版本号.
<properties> <atguigu.spring.version>4.0.0.RELEASE</atguigu.spring.version> </properties> |
- 在需要统一的版本号的位置,使用${自定义名称} 引用声明的版本号
<version>${atguigu.spring.version}</version> |
- 其实properties标签配合自定义标签声明还能配置其他东西
<properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties> |
生命周期
各个构建环节执行的顺序:不能打乱循序,必须按照既定的正确的顺序来执行。
Maven的核心程序中定义了抽象的生命周期,生命周期中各个阶段的具体任务是由插件来完成的。
Maven核心程序为了更好的实现自动化构建,按照这一的特点执行生命周期的各个阶段:无论现在要执行生命周期中的哪一个阶段,都是从这个生命周期的最初的位置开始执行
- Clean Lifecycle
- pre-clean 执行一些在clean之前完成的工作
- clean 移除所有上一次构建生成的文件
- post-clean 执行一些需要在clean之后立刻完成的工作
- Default Lifecycle
Default 生命周期是Maven生命周期中最重要的一个,绝大部分工作都发生在这个生命周期中。这里,只解释一些比较重要和常用的阶段
validate
generate-sources
process-sources
generate-resources
process-resources 复制并处理资源文件,至目标目录,准备打包
compile 编译项目的源代码
process-classes
generate-test-sources
process-test-sources
generate-test-resource
process-test-resources复制并处理资源文件,至目标测试目录
test-compile 编译测试源代码
process-test-classes
test 使用合适的单元测试框架运行测试。这些测试代码不会被打包或部署。
prepare-package
package 接受编译好的代码,打包成可发布的格式,如jar
pre-integration-test
integration-test
post-integeration-test
verify
install 将包安装至本地仓库,以让其他项目依赖
deploy 将最终的包复制到远程的仓库,以让其他开发人员与项目共享或部署到服务器上运行。
- Site Lifecycle
- pre-site 执行一些需要在生成站点之前完成的工作
- site生成项目的站点文档
- post-site 执行一些需要在生成站点文档后完成的工作,并为部署做准备
- site-deploy 将生成的站点文档发布,Manager比较喜欢,文档及统计数据自动生成,很好看。
插件和目标
生命周期的各个阶段仅仅定义了要执行的任务是什么
各个阶段的目标和插件的目标是对应的。
相似的目标由特定的插件来完成
生命周期的阶段 | 插件目标 | 插件 |
compile | compile | maven-compiler-plugin |
test-compile | testCompile | maven-compiler-plugin |
可以将目标看作 “调用插件的命令”
继承
现状:Hello依赖的junit:4.0 HelloFriend依赖的junit:4.0
MakeFriends依赖的junit:4.9
由于junit是test 范围的,它无法传递.所以容易造成junit版本的不一致
将junit依赖版本统一提取到父工程中,在子工程中声明junit依赖时,不指定版本.这样在子工程中junit版本就与父工程中junit版本一致.
[1]创建一个Maven工程作为父工程,打包的方式是 pom
[2]在子工程中声明对父工程的引用
<parent>
<artifactId>Parent</artifactId>
<groupId>com.atguigu.maven</groupId>
<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>../Hello</module>
<module>../HelloFriend</module>
</modules>
这样配置后,install 父项目就会安装所有的子项目
发布到服务器
Web工程自动部署 <build> <finalName>AtguiguWeb</finalName> <!--配置项目构建过程中需要使用的插件--> <plugins> <plugin> <!--cargo 是一家专门从启动Servlet容器的组织--> <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>23232</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> |
eclipse
配置
- Maven中的Installations 指定Maven核心程序中的位置(和M2_HOME一致)
- UserSettings :指定conf/settings.xml的位置,进而获取本地仓库的位置
设置通过Maven创建的工程的JDK版本——一劳永逸
[1]打开settings.xml文件
[2]找到profiles标签
[3]加入如下配置
<profile>
<id>jdk-1.7</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.7</jdk>
</activation>
<properties>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
<maven.compiler.compilerVersion>1.7</maven.compiler.compilerVersion>
</properties>
</profile>
创建Maven版的Java工程
勾选Create a simple project(skip archetype selection)
创建Maven版的Web工程
勾选Create a simple project(skip archetype selection)
war包(打包方式区分Java和Web结构)
生成项目后: Project Facets 去掉 Dy..Web 在勾选 Dy..Web之后点那个链接,设置content directory为src/main/webapp
执行Maven命令