文章目录
Maven
一、Maven简介
- Maven翻译为“专家”,“内行”
- Maven是Apache下的一个开源项目,它是一个跨平台的项目管理工具,它用于对Java项目进行项目构建、依赖管理及项目信息管理
- Maven包含了一个项目对象模型(Project Object Model),一组标准集合,一个项目生命周期(Project Lifecycle),一个依赖管理系统(Dependency Management System)和用来运行定义在生命周期阶段(phase)中插件(plugin)目标(goal)的逻辑
- 一个项目生命周期:清理、编译、测试、部署。Maven将项目生命周期抽象统一为(项目构建过程):清理(clean)–初始化(initialize)–编译(compile)–测试(test)–报告(report)–打包(package)–部署(deploy)–站点生成(site)等
- 为什么要使用Maven?
①做项目时手工操作较多,编译、测试等工作都是独立的,很难一步完成,Maven能帮你从琐碎的手工劳动中解脱出来,帮你规范整个组织的构建系统。只需输入简单的命令,Maven就会帮我们处理那些繁琐的任务
②Maven拥有约定,知道你的代码在哪里,放到哪里去
③Maven拥有一个生命周期。例如执行mvn install就可以自动执行编译、测试、打包等构建过程
④Maven只需要定义一个pom.xml,然后把源码放到默认的目录,Maven就可以帮你处理其他事情
⑤Maven拥有依赖管理和仓库管理
⑥Maven具有跨平台性
二、Maven安装与配置
1.安装Maven
①安装jdk
- 下载地址:https://www.oracle.com/java/technologies/javase-jdk15-downloads.html
- 配置环境变量:
(添加PATH变量值)
- 安装成功
②安装Maven
- 下载地址:http://maven.apache.org/download.html
- 配置环境变量
(添加PATH变量值)
- 安装成功
2.Maven安装目录分析
①bin:含有mvn运行的脚本,这些脚本用来配置 Java 命令,准备好 classpath 和相关的 Java 系统属性,然后执行 Java 命令
②boot:含有一个文件plexus-classworlds-2.5.2.jar,它是maven运行需要的类加载器,Maven 使用该框架加载自己的类库
③conf:含有settings.xml(整个Maven工具核心配置文件)。可以将其复制到~\ .m2\目录下,然后修改该文件
④lib:含有Maven运行依赖的jar包
⑤LICENSE:记录了Maven 使用的软件许可证
⑥NOTICE:记录了Maven 包含的第三方软件
⑦README.txt:记录了对Maven 的简要介绍
3.Maven约定
①-src/main/java——存放项目的.java文件
②-src/main/resources——存放项目资源文件,如spring,hibernate配置文件
③-src/test/java——存放所有测试.java文件,如junit测试类
④-src/test/resources——存放测试资源文件
⑤-target——该目录是项目编译后产生的一个目录,主要存放的是编译后的.class文件
⑥-pom.xml——Maven项目的核心配置文件
三、手工构建第一个Maven项目
①建立一个Hello项目同时建立Maven约定的目录结构
Hello
------src
----------mian
----------------java
----------------resources
----------test
---------------java
---------------resources
------pom.xml
②建立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>
<groupId>cn.rjxy.maven</groupId>
<artifactId>Hello</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Hello</name>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<defaultGoal>compile</defaultGoal>
</build>
</project>
③在src/main/java/cn/rjxy/maven目录下新建文件Hello.java
package cn.rjxy.maven;
public class Hello
{
public String sayHello(String name)
{
return "Hello "+name+"!";
}
}
④在src/test/java/cn/rjxy/maven目录下新建测试文件HelloTest.java
package cn.rjxy.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("chenjiacheng");
assertEquals("Hello chenjiacheng!",results);
}
}
⑤打开cmd命令行,进入Hello项目根目录
a)执行mvn compile命令,Hello项目里多了一个target文件夹
b)执行mvn clean命令,Hello项目里的target文件夹被清除
c)执行mvn clean compile命令,Hello项目里再次多了一个target文件夹
d)执行mvn clean test命令,target文件夹下多了一个test-classes文件夹
e)执行mvn clean package命令,target文件夹下多了一个打好的jar包以及一个maven-archiver文件夹
f)执行mvn clean install命令,在本地仓库~\ .m2\repository中会多一个cn文件夹
四、手工构建第二个Maven项目
①建立一个HelloFriend项目同时建立Maven约定的目录结构
HelloFriend
------src
----------mian
----------------java
----------------resources
----------test
---------------java
---------------resources
------pom.xml
②建立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>
<groupId>cn.rjxy.maven</groupId>
<artifactId>HelloFriend</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>HelloFriend</name>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>cn.rjxy.maven</groupId>
<artifactId>Hello</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
③在src/main/java/cn/rjxy/maven目录下新建文件HelloFriend.java
package cn.rjxy.maven;
public class HelloFriend
{
public String sayHelloToFriend(String name)
{
Hello hello = new Hello();
String str = hello.sayHello(name)+" I am "+this.getMyName();
System.out.println(str);
return str;
}
public String getMyName()
{
return "John";
}
}
④在src/test/java/cn/rjxy/maven目录下新建文件HelloFriendTest.java
package cn.rjxy.maven;
import org.junit.Test;
import static junit.framework.Assert.assertEquals;
public class HelloFriendTest
{
@Test
public void tesHelloFriend()
{
HelloFriend helloFriend = new HelloFriend();
String results = helloFriend.sayHelloToFriend("chenjiacheng");
assertEquals("Hello chenjiacheng! I am John",results);
}
}
⑤打开cmd命令行,进入HelloFriend项目根目录
执行mvn package命令
五、Maven核心概念
1.Maven坐标
Maven坐标主要组成:
①groupId:定义当前Maven项目隶属项目
②artifactId:定义实际项目中的一个Maven项目(模块)
③version:定义当前Maven项目的当前版本
④packaging:定义Maven项目的打包方式
这四个标识决定了Maven的唯一性
2.依赖管理
- 依赖声明主要包括以下元素:
- 依赖范围scope用来控制依赖在哪些classpath有效
①compile:编译依赖范围(默认)。对于编译、测试、运行三种classpath都有效
②test:测试依赖范围。只对于测试classpath有效。
③provided:已提供依赖范围。对于编译、测试classpath有效,对于运行classpath无效
④runtime:运行时提供
3.仓库管理
- Maven仓库:用来统一存储所有Maven共享构建的位置就是仓库
- Maven仓库布局:
groupId:
artifactId:
version:
artifactId-version.packaging:
- 仓库的分类:
①本地仓库: ~\ .m2\repository每个用户只有一个本地仓库,需要从中央仓库中下载资源到本地仓库
②远程仓库:
中央仓库:https://mvnrepository.com/ Maven默认的远程仓库
私服:是一种特殊的远程仓库,它是架设在局域网内的仓库
镜像:用来替代中央仓库,顺序一般比中央仓库快
4.生命周期
-
Maven生命周期就是为了对所有的构建过程进行抽象和统一
-
Maven将项目生命周期抽象统一为(项目构建过程):清理(clean)–初始化(initialize)–编译(compile)–测试(test)–报告(report)–打包(package)–部署(deploy)–站点生成等。
-
Maven三大生命周期:
①clean lifecycle:清理项目
②default lifecycle:构建项目
③site lifecycle:生成项目站点
这三套生命周期之间相互独立,也可以直接运行mvn clean install site命令运行所有这三套生命周期 -
clean生命周期包含三个阶段:
①pre-clean:执行一些需要在clean之前完成的工作
②clean:移除所有上一次构建生成的文件
③post-clean:执行一些需要在clean之后立刻完成的工作 -
defult生命周期是Maven生命周期中最重要的一个,绝大部分工作都发生在这个生命周期
validate
generate-sources
process-sources
generate-resources
process-resources
compile 编译项目的源代码
process-classes
generate-test-sources
process-test-sources
generate-test-resources
process-test-resources
test-compile 编译测试项目的源代码
process-test-classes
test 使用适当的单元测试框架运行测试
prepare-package
package 将项目打包成可发布的格式,如 JAR
pre-integration-test
integration-test
post-integration-test
verify
install 将项目安装到本地仓库
deploy 将项目部署到远程仓库 -
site生命周期包含四个阶段:
①pre-site:执行一些需要在生成站点文档之前完成的工作
②site:生成项目的站点文档
③post-site:执行一些需要在生成站点文档之后完成的工作,并且为部署做准备
④site-deploy:将生成的站点文档部署到特定的服务器上
最常用到site和site-deploy阶段,用以生成和发布Maven站点 -
运行任何一个阶段的时候,它前面的所有阶段都会被运行;Maven的插件机制是完全依赖Maven的生命周期的
5.Maven插件
- Maven的核心仅仅定义了抽象的生命周期,具体任务都是交给插件来完成
- 每个插件都能实现多个功能,每个功能就是一个插件目标
- Maven的生命周期与插件目标相互绑定,以完成某个具体的构建任务
六、Maven与Ecplise整合
1.步骤
①下载Ecplise
- 下载地址:https://www.eclipse.org/downloads/
②确保Ecplise中有Maven插件
- -window-preferences
③配置Maven
④导入Maven项目
⑤运行Maven项目
- 右键pom.xml文件-Run As-Maven命令
-
Goals中输入组合命令
⑥新建Maven项目
-
MakeFriends.java
package cn.rjxy.maven;
public class MakeFriends
{
public String makeFriends(String name)
{
HelloFriend friend = new HelloFriend();
friend.sayHelloToFriend("chenjiacheng");
String str = "Hey,"+friend.getMyName()+"make a friend,please.";
System.out.println(str);
return str;
}
}
- MakeFriendsTest.java
package cn.rjxy.maven;
import org.junit.Test;
import static junit.framework.Assert.assertEquals;
public class MakeFriendsTest
{
@Test
public void testMakeFriends()
{
MakeFriends makeFriend = new MakeFriends();
String str = makeFriend.makeFriends("chenjiacheng");
assertEquals("Hey,John make a friend please.",str);
}
}
<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>cn.rjxy.maven</groupId>
<artifactId>MakeFriends</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>MakeFriends</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>cn.rjxy.maven</groupId>
<artifactId>HelloFriend</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.4.2</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>
</build>
</project>
2.依赖管理原则
①依赖传递性原则
- junit和hamcrest是两个不同的框架,junit使用了hamcrest框架
②路径最近者优先原则
- 在Hello项目的pom.xml文件中添加log4j的依赖,版本为1.2.16
- 在HelloFriend项目的pom.xml文件中添加log4j的依赖,版本为1.2.14
- 在HelloFriendx项目中有log4j依赖,版本为1.2.14
③路径相同,第一声明者优先
3.继承
- 这三个项目中的pom.xml文件中有很多重复的代码,为了消除重复,把很多相同的配置提取出来。例如:groupId,version等
- 既然有重复的代码,而且是共性的,所以可以把共性的代码抽象出一个类,作为父类
①新建一个Maven项目Parent
②三个项目都依赖junit,所以把junit放到Parent项目的pom.xml中
③HelloFriend和MakeFriends项目都依赖Hello,添加依赖
④在Hello项目的pom.xml中添加标签
⑤Parent项目的pom.xml:将jar改为pom
⑥这样就可以消除大量的代码 - Hello项目的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>
<artifactId>Hello</artifactId>
<name>Hello</name>
<parent>
<groupId>cn.rjxy.maven</groupId>
<artifactId>Parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../Parent/pom.xml</relativePath>
</parent>
</project>
- HelloFriend项目的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>
<artifactId>HelloFriend</artifactId>
<parent>
<groupId>cn.rjxy.maven</groupId>
<artifactId>Parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../Parent/pom.xml</relativePath>
</parent>
</project>
- MakeFriends项目的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>
<artifactId>MakeFriends</artifactId>
<packaging>jar</packaging>
<parent>
<groupId>cn.rjxy.maven</groupId>
<artifactId>Parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../Parent/pom.xml</relativePath>
</parent>
<name>MakeFriends</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.4.2</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>
</build>
</project>
⑦Notes
- Hello项目中多了HelloFriend,MakeFriends,原因是Parent父项目中定义了,所以就继承了
- 要用dependencyManagement标签将dependencies包起来管理依赖,这样Maven Dependencies就空了,需要显示地指定一下,将junit依赖复制过来
- dependencyManagement中定义的依赖子module不会共享
dependencies中定义的依赖子module可以共享 - 将Parent项目的pom.xml中junit依赖中版本号和范围去掉,这样其他模块想引用该junit就不需要指定版本号,不必为版本号而烦恼
4.聚合
- 聚合:如果想一次构建多个项目模块,那就需要对多个项目模块进行聚合
- 之前建立的四个项目间有相互依赖,要执行第四个就必须把前三个pom.xml执行install命令,这与maven的高度自动化特点相违背
- 在Parent项目的pom.xml中添加配置
- 在父工程中引入了三个模块,将仓库中的cn文件夹删除,执行install命令后会自动将这些模块执行。一步构建,执行三个项目,之后在仓库中生成了项目。
- Parent项目是一个聚合工程,没有实际的代码
5.建立WEB项目
①
- 继承Parent项目并删除相同的代码
七、Maven私服
Nexus安装与使用
①下载nexus-2.14.2-01.war包
百度网盘链接:https://pan.baidu.com/s/1tC7yhBcekowZ42Sa_XpO1Q
提取码:qbh0
②启动tomcat(目录:~\apache-tomcat-8.5.59\bin\startup.bat)
③在浏览器中访问http://localhost:8080/nexus-2.14.2-01/
④点击右上角Log In,输入Username(admin)、Password(admin123)
⑤登录成功
⑥Nexus内置仓库
a.Public Repositories:该仓库组将所有策略为Release的仓库聚合并通过一致的地址提供服务
b.3rd party:这是一个策略为Release的宿主类型仓库,用来部署无法从公共仓库获得的第三方发布版本构件
c.Apache Snapshots:这是一个策略为Snapshot的代理仓库,用来代理Apache Maven仓库的快照版本构件
d.Central::这是一个策略为Snapshot的代理仓库,该仓库代理Maven中央仓库,其策略为Release,因此只会下载和缓存中央仓库中的发布版本构件
e.Releases:这是一种策略为Release的宿主类型仓库,用来部署组织内部的发布版本构件
f.Snapshots:这是一个策略为Snapshot的宿主类型仓库,用来部署组织内部的快照版本构件
⑦创建宿主目录和代理仓库
a.hosted:本地仓库,通常我们会部署自己的构件到这一类型的仓库。包括3rd仓库,Release仓库,Snapshots仓库
b.proxy:代理仓库,它们被用来代理远程的公共仓库,如Maven的中央仓库
c.group:仓库组,用来合并多个hosted/proxy仓库,通常我们配置Maven依赖仓库组
- 代理仓库一定会指明远程路径
- Releases是已发布的版本,Snapshots是未发布的版本
⑧创建仓库组
- 添加一个本地仓库
-
本地仓库已经被创建,如果这个仓库供多个部门使用,那么就应该为不同的用户分配角色和权限(CRUD:Create,Read,Update,Delete)
-
设置权限
自动新建了一些权限
添加角色
给角色开发者添加权限:view,read,update
添加用户
⑨下载Index索引并进行构件搜索(GAV搜索)
(1)
(2)
(3)
或者手动下载中心仓库最新版本的索引文件
在https://repo.maven.apache.org/maven2/.index/下载文件nexus-maven-repository-index.gz;nexus-maven-repository-index.properties(在最下面)
进入nexus安装目录\sonatype-work进入indexer目录,因为我们的代理名为central所以找到central-ctx ,将下载好的文件解压进去后。
重新启动nexus,若能在central 的browse index中看到和remote一样的索引,即代表成功完成。
(下载的过程非常非常慢TAT)
⑩配置所有构件均从私服下载
~\ .m2下的settings.xml中添加配置:
-
星号表示所有的请求都经过url向maven发起
-
url里的内容就是仓库的path值
-
url中的public代表group组。group组的好处是把多个仓库放在一个组里,这样访问一个仓库组就可以间接访问组里的每个仓库
添加配置并激活配置文件
⑪部署构建到nexus,包含Releases和Snapshots
在Hello项目的pom.xml文件中添加配置
⑫nexus访问权限控制
在~\apache-maven-3.3.9\conf\settins.xml中添加配置:
总:~.m2\settins.xml代码:
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<localRepository>C:\Users\DELL\.m2\repository</localRepository>
<mirrors>
<mirror>
<id>nexus</id>
<mirrorOf>*</mirrorOf>
<url>http://localhost:8080/nexus-2.14.2-01/content/groups/public/</url>
</mirror>
</mirrors>
<profiles>
<id>nexus</id>
<repositories>
<repository>
<id>central</id>
<url>http://central</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>central</id>
<url>http://central</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</pluginRepository>
</pluginRepositories>
<activeProfiles>
<activeProfile>nexus</activeProfile>
</activeProfiles>
</profiles>
<servers>
<server>
<id>releases</id>
<username>admin</username>
<password>admin123</password>
</server>
<server>
<id>snapshots</id>
<username>admin</username>
<password>admin123</password>
</server>
</servers>
</settings>
⑬执行mvn deploy命令(将包复制到远程的仓库,与其他项目开发人员共享)
附录(ERROR解决)
1.[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test (default-test) on project Hello: There are test failures.
在pom.xml中添加
2.访问tomcat出现java.lang.IllegalStateException No output folder错误解决方法
在浏览器中访问http://localhost:8080,可能会出现500错误,错误提示如下: localhost:8080 java.lang.IllegalStateException: No output folder
原因:tomcat目录没有被读写的权限,导致文件不能被编译到指定的工作目录中
解决办法: 找到tomcat目录,右键“属性—>安全—>编辑”,找到Users,将“完全控制”选项“允许”打钩,应用
3.运行mvn deploy命令时出现
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy (default-deploy) on project Hello
解决办法:确定在~\ .m2\settings.xml中添加了配置