Git和Maven的学习笔记
Git
1、Git简介
Git 是一个免费的、开源的分布式版本控制系统,可以快速高效地处理从小型到大型的各种 项目。
Git 易于学习,占地面积小,性能极快。 它具有廉价的本地库,方便的暂存区域和多个工作 流分支等特性。其性能优于 Subversion、CVS、Perforce 和 ClearCase 等版本控制工具。
1.1、何为版本控制
版本控制是一种记录文件内容变化,以便将来查阅特定版本修订情况的系统。 版本控制其实最重要的是可以记录文件修改历史记录,从而让用户能够查看历史版本, 方便版本切换。
1.2、为什么需要版本控制
个人开发过渡到团队协作
1.3、版本控制工具
- 集中式版本控制工具
- CVS、SVN(Subversion)、VSS…… 集中化的版本控制系统诸如 CVS、SVN 等,都有一个单一的集中管理的服务器,保存 所有文件的修订版本,而协同工作的人们都通过客户端连到这台服务器,取出最新的文件或 者提交更新。多年以来,这已成为版本控制系统的标准做法。 这种做法带来了许多好处,每个人都可以在一定程度上看到项目中的其他人正在做些什 么。而管理员也可以轻松掌控每个开发者的权限,并且管理一个集中化的版本控制系统,要 远比在各个客户端上维护本地数据库来得轻松容易。 事分两面,有好有坏。这么做显而易见的缺点是中央服务器的单点故障。如果服务器宕 机一小时,那么在这一小时内,谁都无法提交更新,也就无法协同工作。
- 分布式版本控制工具
- Git、Mercurial、Bazaar、Darcs…… 像 Git 这种分布式版本控制工具,客户端提取的不是最新版本的文件快照,而是把代码 仓库完整地镜像下来(本地库)。这样任何一处协同工作用的文件发生故障,事后都可以用 其他客户端的本地仓库进行恢复。因为每个客户端的每一次文件提取操作,实际上都是一次 对整个文件仓库的完整备份。 分布式的版本控制系统出现之后,解决了集中式版本控制系统的缺陷: 1. 服务器断网的情况下也可以进行开发(因为版本控制是在本地进行的) 2. 每个客户端保存的也都是整个完整的项目(包含历史记录,更加安全)
1.5、Git 工作机制
1.6、Git 和代码托管中心
代码托管中心是基于网络服务器的远程代码仓库,一般我们简单称为远程库。
- 局域网
- GitLab
- 互联网
- GitHub(外网)
- Gitee 码云(国内网站)
2、安装Git
- 官网下载安装包,点击打开
到此,安装完成,鼠标右键出现菜单,打开bash终端,输入git --version,出现版本信息就说明安装成功。
3、Git常用命令
命令名称 | 作用 |
---|---|
git config --global user.name 用户名 | 设置用户名 |
git config --global user.email 邮箱 | 设置用户签名 |
git init | 初始化本地库 |
git status | 查看本地库状态 |
git add 文件名 | 添加到暂存区 |
git commit -m "日志信息" 文件名 | 提交到本地库 |
get reflog | 查看历史记录 |
git reset --head 版本号 | 版本穿梭 |
3.1、设置用户签名
说明: 签名的作用是区分不同操作者身份。用户的签名信息在每一个版本的提交信息中能够看 到,
以此确认本次提交是谁做的。Git 首次安装必须设置一下用户签名,否则无法提交代码。
※注意:这里设置用户签名和将来登录 GitHub(或其他代码托管中心)的账号没有任 何关系。
3.2、初始化本地库
在项目中打开git终端,输入命令
3.3、查看本地库状态
首次查看没有任何文件
创建一个文件,添加点内容试试
检测到未追踪的文件,也就是这个文件还在工作区
3.4、添加到暂存区
颜色变成绿色,该文件已经被添加到暂存区
3.5、从暂存区中移除
git rm --cached 文件名 可以将文件移除暂存区,取消追踪该文件
3.6、提交本地库
git commit -m "日志信息" 文件名
提交之后,查看本地库状态,提示没有文件需要提交
将文件修改之后,再次查看本地库状态
提示文件被修改过,并且变成了红色
再次添加到暂存区
3.7、历史版本
语法:
- git reflog 可以查看所有分支的所有操作记录(包括已经被删除的 commit 记录和 reset 的操作),
- git log 则不能察看已经删除了的commit记录
可以看到当前只有一个版本,再次提交,产生一个新的版本
再次查看,出现了一个新的版本
3.8、版本穿梭
基本语法:git reset --hard 版本号
先查看一下现在本地库的文件
现在回退到第一次提交的版本
再次查看文件
已经回退到第一次提交的版本
git版本切换,其实操作的就是head指针
head指向分支,分支指针指向版本
3.9、关于版本切换和head指针
git中的head指针用于记录当前工作的位置,可以指向commit版本,也可以指向分支
通常,我们工作在某一个分支上,比如 master 分支。当指向branch时commit提交后,master 指针和 HEAD 指针一起前进的,每做一次提交,这两个指针就会一起向前挪一步。
但是在某种情况下(例如 checkout 了某个commit),master 指针 和 HEAD 指针这种「绑定」的状态就被打破了,变成了分离头指针状态。下图就是处于分离头指针状态的情况:
HEAD 游离状态的利弊
好处:HEAD 处于游离状态时,开发者可以很方便地在历史版本之间互相切换,比如要回到某次提交,只需要 对应的 或者 名即可。
弊端:若在该基础上进行了提交,则会新开一个「匿名分支」;也就是说我们的提交是无法可见保存的,一旦切换到别的分支,原游离状态以后的提交就不可追溯了。
可以看到之后head指针指向了这个版本,而且有一个匿名分支
提交信息和当前文件也已经回到了这个版本的状态
切换回其他分支,此匿名分支就不见了
在head指针处于游离状态时,我们所做的add和commit都是没有意义的,切换到其他分支之后,head游离状态会消失,该分支也会消失
解决方法:在git checkout到提交的版本之后,创建一个新分支,然后我们所有操作都会保存到这个分支,之后在合并就好
另外,checkout还可以用于撤销文件修改,git checkout 文件名
该命令主要用于检出某一个指定文件。
如果不填写commit id,则默认会从暂存区检出该文件,如果暂存区为空,则该文件会回滚到最近一次的提交状态。
例如:
当暂存区为空,如果我们想要放弃对某一个文件的修改,可以用这个命令进行撤销:
3.10、关于git reset
reset有三种模式
-
--hard:重置位置的同时,直接将 working Tree工作目录、 index 暂存区及 repository 都重置成目标Reset节点的內容,所以效果看起来等同于清空暂存区和工作区。
-
--soft:重置位置的同时,保留working Tree工作目录和index暂存区的内容,只让repository中的内容和 reset 目标节点保持一致,因此原节点和reset节点之间的【差异变更集】会放入index暂存区中(Staged files)。所以效果看起来就是工作目录的内容不变,暂存区原有的内容也不变,只是原节点和Reset节点之间的所有差异都会放到暂存区中。
-
--mixed(默认):重置位置的同时,只保留Working Tree工作目录的內容,但会将 Index暂存区 和 Repository 中的內容更改和reset目标节点一致,因此原节点和Reset节点之间的【差异变更集】会放入Working Tree工作目录中。所以效果看起来就是原节点和Reset节点之间的所有差异都会放到工作目录中。
假设现在有两次提交,first commit和second commit,以下演示各自的区别
1、--hard,从second commit重置到first commit,second commit 提交记录消失,工作区和暂存区都回到first commit提交时的状态,也就是相当于first commit(第一次提交)-->直接撤销所有修改
2、--soft,从second commit重置到first commit,second commit 提交记录消失,工作区内容不变,将第二次修改的内容添加到暂存区,也就是相当于first commit(第一次提交)-->修改内容-->git add
3、--mixed(默认),从second commit重置到first commit,second commit 提交记录消失,工作区内容不变,暂存区回到没有将修改添加进暂存区的状态,也就是相当于first commit(第一次提交)-->修改内容-->
4、Git分支操作
4.1、什么是分支
在版本控制过程中,同时推进多个任务,为每个任务,我们就可以创建每个任务的单独 分支。
使用分支意味着程序员可以把自己的工作从开发主线上分离开来,开发自己分支的时 候,不会影响主线分支的运行。
对于初学者而言,分支可以简单理解为副本,一个分支就是 一个单独的副本。(分支底层其实也是指针的引用)
4.2、分支的好处
同时并行推进多个功能开发,提高开发效率。 各个分支在开发过程中,如果某一个分支开发失败,不会对其他分支有任何影响。失败 的分支删除重新开始即可。
4.3、分支的操作
命令名称 | 作用 |
---|---|
git branch 分支名 | 创建分支 |
git branch -v | 查看分支 |
git checkout 分支名 | 切换分支 |
git merge 分支名 | 把指定的分支合并到当前分支上 |
4.3.1、查看分支
4.3.2、创建分支
此时已经有两个分支(新建分分支是当前分支的副本)
在当前分支做修改,也就是master分支
再次提交到本地库
4.3.3、切换分支
git checkout -b 分支名
可以创建并切换分支
再次查看文件
可见,当前文件没有被修改
修改当前分支
切换回master分支,准备合并
4.3.4、合并分支
- 正常合并
创建一个文件,add和commit
创建一个新的分支并修改文件内容,add和commit
切换回master分支,合并新分支
可以看到文件直接修改了,并且提示信息是Fast-forward
- 合并冲突
首先创建一个文件
add和commit
创建并切换分支
在新分支里做如下修改
add和commit,切换回master分支
修改文件的同一行,add和commit
合并分支
提示合并发生冲突
查看本地库状态
打开修改的文件
手动修改之后
再次add和commit,查看本地库状态
合并之后提交必须全部一起提交,不然会报错
fatal: cannot do a partial commit during a merge.(无法在合并期间部分提交)
关于两个分支修改同一个文件,合并时产生的情况
修改同一个文件同一个区域会产生冲突
什么是文件的同一区域?
- 文件的同一行
- 文件的相邻行
演示:
master分支
新建分支修改文件
切换回master分支修改文件
合并发生冲突
打开文件
同样案例修改相隔一行:
分支修改文件
切换回master分支修改文件
合并分支
没有出现冲突,代码直接合并
5、Git团队协作机制
- 1、团队内协作
- 2、跨团队协作
6、GitHub操作
远程仓库国内可以使用gitee,访问速度更快,使用方法和github一样,这里只介绍github
注册账号,创建一个仓库
创建完成之后
上面的地址就是仓库地址
6.1、常用操作
命令名称 | 作用 |
---|---|
git remote | 查看所有远程仓库 |
git remote -v | 查看所有远程仓库详细信息 |
git remote add 别名 远程地址 | 添加远程仓库并起别名 |
git push 远程仓库(可以别名) 分支 | 推送本地分支上的内容到远程库 |
git clone 远程地址 | 将远程仓库的内容克隆到本地 |
git pull 远程仓库 远程分支名 | 将当前远程仓库对于分支最新内容拉下来与当前本地分支直接合并 |
git remote rm 远程仓库 | 远程仓库 |
6.2、推送-git push
git push 远程仓库 本地分支名:远程分支名
若当前分支和远程分支名字相同,则可以省略
git push 远程仓库 分支名
注意:
第一次提交会要求选择登陆方式,如果浏览器登陆过了直接用浏览器登陆就好
这里登陆的账户和提交代码的账户没有关系,登陆之后只是说明这台电脑再次登陆github不需要用户名密码(以及验证这个账号对该仓库的权限), 具体提交代码的用户是谁看git设置的邮箱
如果git-email和github-email不一致,则即使github-username和git-username用户名相同,用户在本地git和在github上操作也会被认为是不同的用户在操作,意味着:github-email用户创建了仓库,git-email用户从本地上传的代码
如果git-email和github-email一致,则认为是同一用户,意味着:用户在本地git上操作再push到github上,和直接在github上操作没有区别
总结:第一次上传代码输入用户名密码只是为了这台电脑可以正常访问github
git的email和github的email相同,则github认为是本人操作
git的email和github的email不相同,也可以正常push,但是显示的是另外一个人
另外,同一台可以设置不同用户名密码
优先级:local > global > system
6.3、拉取代码-git pull
git pull 远程仓库 分支
拉取远程分支到本地当前分支,并且自动合并
6.4、克隆远程仓库-git clone
克隆远程仓库不需要登陆,公开仓库读权限对所有人公开
克隆也不需要初始化仓库,直接git clone 远程仓库地址
完成了克隆
6.5、团队内协作
合作者模式:
团队内协作先要邀请开发人员,不然是无法push的,提示
remote: Permission to Z-HaiHua/GitTest.git denied to FH0524.
仓库的所有者把邀请合作者一起开发这个项目(git提交代码会用这个账号进行权限验证,具体提交的人还是看git设置里面的邮箱),需要加入项目的人需要同意
成为合作者之后,才能通过这个登陆github的账户提交代码到仓库
关于合作模式
git有两种合作模式:
- 合作者模式(collaborator)
需要仓库主人将该用户添加进合作者,邀请该用户参与开发
每个合作者新建自己部分的feature branch,在这个新分支上进行代码修改,提交合并
如果希望项目既有collaborator同时又可以限制他们的读写权利,尤其是限制其“写”的权利,可利用organization来为team成员赋予不同等级的权力。
另外,合作者在主页看不到自己合作的仓库,需要到setting下的repository部分才能看到自己合作的项目
- 贡献者模式(contributor)--跨团队协作
每个贡献者在他们fork的仓库上进行代码修改、发布自己负责的部分,再向主仓库提起pull request
6.6、跨团队协作
参加协作的人fork项目到自己的库当中,然后自己库中也会有一个和原仓库一模一样的仓库,进行修改之后,通过pull request 向原项目发送拉取请求
fork之后会出现
修改代码提交之后,点击 pull request,发送拉取请求
选择好合并的分支
再次点击pull request,打开刚才的pull request
仓库会收到pull request
打开之后
点击合并之后,可以看到仓库中代码已经改变
7、SSH免密登陆
使用命令:
ssh-keygen -t rsa -C "#”
t是加密方式
c是备注消息,便于自己记住此密钥是干嘛的,可以随便填写
之后三次回车,什么都不输入即可(第一次输入文件保存位置,默认在c盘用户目录下.ssh文件夹,第二次输入密码,第三次确认密码)
第一次使用SSH连接会提示
Are you sure you want to continue connecting (yes/no)? yes
输入yes即可,以后这台电脑连接github就不需要账号密码了
8、IDEA集成Git
8.1、配置忽略文件
在项目开发中 ,我们肯定不希望整个项目的所有文件都被git追踪,比如idea的配置文件,编译之后的class文件,这时候我们就需要配置忽略文件
1、创建忽略规则配置文件xxx.ignore(前缀随便,文件后缀必须是这个)该文件放在哪里都行
java项目中常用的ignore文件
*.class
# Eclipse
.project
.classpath
.settings/
# Intellij
*.ipr
*.iml
*.iws
.idea/
# Maven
target/
# Gradle
build
.gradle
# Log file
*.log
log/
# out
**/out/
# Mac
.DS_Store
# others
*.jar
*.war
*.zip
*.tar
*.tar.gz
*.pid
*.orig
temp/
然后配置到git当中,可以配置到系统、用户组、仓库
[core]
...
excludesfile = D:/git/GitTest01/.git/.gitignore
8.2、idea中使用Git
8.2.1、配置Git
在idea中使用git进行版本控制
点击版本控制设置
8.2.2、配置Git忽略文件
将文件或者文件夹添加进忽略名单
忽略的文件
8.2.3、基本使用
添加暂存区和提交都是鼠标右键--->Git--->.......
切换版本
在idea中打开log窗口,可以查看所有提交记录,右键选择checkout或者reset
新建分支:右键-->Git-->branch-->New Branch
切换分支:右键-->Git-->branch-->选择要切换的分支-->点击-->checkout
删除分支:当前分支不能删除,需要切换到其他分支才可以删除当前分支,右键-->Git-->branch-->选择要删除的分支-->点击-->delete
合并分支
合并冲突
9、IDEA集成GitHub
使用令牌登陆,首先创建令牌
令牌创建之后要立马复制下来,不然之后看不到了
然后到IDEA中添加账号
之后把令牌填上去就可以登陆了,登陆之后
9.1、IDEA中创建github仓库并分享项目
IDEA自带的github插件可以在idea中远程创建github仓库以及分享项目
9.2、IDEA中操作github
在idea中创建仓库必须要用账号密码登陆,其他操作可以用SSH免密登陆
添加一个SSH连接的git仓库就好
push和pull,都是右键-->Git-->push/pull
克隆项目
输入链接即可克隆项目
Maven基础
1、Maven是什么
在Javaweb开发中,需要使用大量的jar包,我们手动去导入;
如何能够让一个东西自动帮我导入和配置这个jar包。由此,Maven诞生了!
Maven的本质是一个项目管理工具,将项目开发和管理过程抽象成一个项目对象模型(POM)
Maven是用Java语言编写的。他管理的东西统统以面向对象的形式进行设计,最终它把一个项目看成一个对象,而这个对象叫做POM(project object model),即项目对象模型。
我们说一个项目就是一个对象,作为对象的行为、对象的属性都有哪些呢?
Maven说我们需要编写一个pom.xml文件,Maven通过加载这个配置文件就可以知道我们项目的相关信息了!到这里我们知道了Maven离不开一个叫pom.xml的文件。因为这个文件代表就一个项目。
提个问题大家思考,如果我们做8个项目,对应的是1个文件,还是8个文件?肯定是8个!
那Maven是如何帮我们进行项目资源管理的呢?这就需要用到Maven中的第二个东西:依赖管理。这也是它的第二个核心!
所谓依赖管理就是maven对项目所有依赖资源的一种管理,它和项目之间是一种双向关系,即当我们做项目的时候maven的依赖管理可以帮助你去管理你所需要的其他资源,当其他的项目需要依赖我们项目的时候,maven也会把我们的项目当作一种资源去进行管理,这就是一种双向关系。
那maven的依赖管理它管理的这些资源存在哪儿呢?主要有三个位置:本地仓库,私服,中央仓库
本地仓库顾名思义就是存储在本地的一种资源仓库,如果本地仓库中没有相关资源,可以去私服上获取,私服也是一个资源仓库,只不过不在本地,是一种远程仓库,如果私服上也没有相关资源,可以去中央仓库去获取,中央仓库也是一种远程仓库。
Maven除了帮我们管理项目资源之外还能帮助我们对项目进行构建,管理项目的整个生命周期,当然它的这些功能需要使用一些相关的插件来完成,当然整个生命周期过程中插件是需要配合使用的,单独一个无法完成完整的生命周期。
1.2、Maven的作用
Maven的作用我们可以分成三类:
(1)项目构建:提供标准的,跨平台的自动化构建项目的方式
(2)依赖管理:方便快捷的管理项目依赖的资源(jar包),避免资源间的版本冲突等问题
(3)统一开发结构:提供标准的,统一的项目开发结构,如下图所示:
各目录存放资源类型说明:
src/main/java:项目java源码
src/main/resources:项目的相关配置文件(比如mybatis配置,xml映射配置,自定义配置文件等)
src/main/webapp:web资源(比如html,css,js等)
src/test/java:测试代码
src/test/resources:测试相关配置文件
src/pom.xml:项目pom文件
2、下载和安装
旧版下载
解压即安装完成
各目录结构说明:
bin:可执行程序目录,
boot:maven自身的启动加载器
conf:maven配置文件的存放目录
lib:maven运行所需库的存放目录
配置环境变量
path环境变量中
输入命令
即安装成功
由于maven下载依赖默认从国外的中央仓库下载,网速会很慢,所以要配置镜像
打开conf下的settings文件
配置好镜像
<mirror>
<id>aliyunmaven</id>
<mirrorOf>central</mirrorOf>
<name>阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
由于maven默认把依赖下载到c盘,这里改一下路径
3、Maven基础概念
3.1、仓库
关于仓库,我们前面讲到了有三种:本地仓库,私服,中央仓库,其中私服和中央仓库都属于远程仓库
中央仓库:maven团队自身维护的仓库,属于开源的
私服:各公司/部门等小范围内存储资源的仓库,私服也可以从中央仓库获取资源
本地仓库:开发者自己电脑上存储资源的仓库,也可从远程仓库获取资源
私服的作用:
(1)保存具有版权的资源,包含购买或自主研发的jar
(2)一定范围内共享资源,能做到仅对内不对外开放
3.2、坐标
我们说maven的仓库里存储了各种各样的资源(jar包),那这些资源我们如何找到它们呢?我们需要知道它们具体的一个位置才能知道如何找到它们,这个就叫坐标
坐标:maven中的坐标用于描述仓库中资源的位置
maven坐标的主要组成如下:
groupId:定义当前资源隶属组织名称(通常是域名反写,如:org.mybatis;com.itheima)
artifactId:定义当前资源的名称(通常是项目或模块名称,如:crm,sms)
version:定义当前资源的版本号
packaging:定义资源的打包方式,取值一般有如下三种
-
jar:该资源打成jar包,默认是jar java工程打包为jar
-
war:该资源打成war包 web工程打包为war
-
pom:该资源是一个父资源(表明使用maven分模块管理),打包时只生成一个pom.xml不生成jar或其他包结构
<?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">
<!--指定pom的模型版本-->
<modelVersion>4.0.0</modelVersion>
<!--打包方式 web工程打包为war java工程打包为jar-->
<packaging>war</packaging>
<!--组织id-->
<groupId>com.zh</groupId>
<!--项目id-->
<artifactId>web01</artifactId>
<!--组织id release代表完成版,SNAPSHOT代表开发版-->
<version>1.0-SNAPSHOT</version>
<!--设置当前工程的所有依赖-->
<dependencies>
<!--具体的依赖-->
<dependency>
</dependency>
</dependencies>
</project>
3.3、插件
Maven 实际上是一个依赖插件执行的框架,它执行的每个任务实际上都由插件完成的。Maven 的核心发布包中并不包含任何 Maven 插件,它们以独立构件的形式存在, 只有在 Maven 需要使用某个插件时,才会去仓库中下载。
Maven 默认为一些核心的生命周期阶段绑定了插件目标,当用户调用这些阶段时,对应的插件目标就会自动执行相应的任务。
运行web项目可以添加tomcat插件
<build>
<plugins>
<!--打war包插件-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.0</version>
</plugin>
<!--Tomcat插件 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
</plugin>
</plugins>
</build>
3.4、依赖
Maven项目可以通过声明式导入所需要的资源,需要什么,写几行代码,Maven就会自动把资源下载并添加到资源库中
<!--项目依赖-->
<dependencies>
<!--具体依赖的jar包配置文件-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
</dependencies>
3.5、POM文件
pom.xml 是Maven的核心配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!--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.zh</groupId>
<artifactId>javaweb-01-maven</artifactId>
<version>1.0-SNAPSHOT</version>
<!--Package:项目的打包方式
jar:java应用
war:JavaWeb应用
-->
<packaging>war</packaging>
<!--配置-->
<properties>
<!--项目的默认构建编码-->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!--编码版本-->
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<!--项目依赖-->
<dependencies>
<!--具体依赖的jar包配置文件-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
</dependencies>
<!--项目构建用的东西-->
<build>
<plugins>
<!--打war包插件-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.0</version>
</plugin>
<!--Tomcat插件 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
</plugin>
</plugins>
</build>
</project>
4、创建Maven项目
创建一个最简单的Maven项目
这就是一个最简单的Maven项目
创建完成记得看一眼是不是用的自己的Maven仓库
5、Maven依赖管理
依赖传递:
依赖具有传递性,分两种
(1)直接依赖:在当前项目中通过依赖配置建立的依赖关系
(2)间接依赖:被依赖的资源如果依赖其他资源,则表明当前项目间接依赖其他资源
依赖传递冲突
依赖传递的冲突问题:
在依赖传递过程中产生了冲突,我们有三种优先法则
(1)路径优先:当依赖中出现相同资源时,层级越深,优先级越低,反之则越高
(2)声明优先:当资源在相同层级被依赖时,配置顺序靠前的覆盖靠后的
(3)特殊优先:当同级配置了相同资源的不同版本时,后配置的覆盖先配置的
以一个项目为根,直接依赖称为1度资源,直接依赖的直接依赖称为2度资源,直接依赖的直接依赖的直接依赖称为3度资源。
当然依赖冲突在这里我们并不需要记,后面会有如何解决此问题的办法。
可选依赖
可选依赖指的是对外隐藏当前所依赖的资源-->不透明
加一个optional属性
<dependencies>
<dependency>
<groupId>Junit</groupId>
<artifactId>Junit</artifactId>
<version>4.12</version>
<optional>true</optional>
</dependency>
</dependencies>
排除依赖
排除依赖指主动断开依赖的资源,被排除的资源无需指定版本
<dependencies>
<dependency>
<groupId>Junit</groupId>
<artifactId>Junit</artifactId>
<version>4.12</version>
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</dependency>
</dependencies>
依赖范围
依赖的jar默认情况可以在任何地方可用,可以通过scope标签设定其作用范围
这里的范围主要是指以下三种范围
(1)主程序范围有效(src/main目录范围内)
(2)测试程序范围内有效(src/test目录范围内)
(3)是否参与打包(package指令范围内)
此外:scope标签的取值有四种:
- compile
- test
- provided
- runtime
这四种取值与范围的对应情况如下:
6、Maven生命周期与插件
Maven对项目构建的生命周期划分为3套
clear:清理工作
default:核心工作,例如编译、测试、打包、部署等
site:产生报告、发布站点等
6.1、clear生命周期
clean:清理工作
pre-clean:执行一些在clean之前的工作
clean:移除上一次构建产生的所有文件
post-clean:执行一些在clean之后立刻完成的工作
6.2、default生命周期
default:核心工作,例如编译,测试,打包,部署等
对于default生命周期,每个事件在执行之前都会将之前的所有事件依次执行一遍
6.3、site生命周期
site:产生报告,发布站点等
pre-site:执行一些在生成站点文档之前的工作
site:生成项目的站点文档
post-site:执行一些在生成站点文档之后完成的工作,为部署做准备
site-deploy:将生成的站点文档部署到特定的服务器上
7、Maven资源导出问题
pom文件中加入如下配置
<!--在build中配置resources,来防止我们资源导出失败的问题-->
<!--resources下的properties、xml都可以导出-->
<!--java下的properties、xml都可以导出-->
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
Maven进阶
1、分模块开发与设计
按模块划分之后,将需要使用的模块使用引入资源的方式引入即可,注意,在引入之前,需要先将该模块安装到本地库中
2、聚合模块
作用:快速构建maven工程,处理多模块工程比较方便
使用:创建一个空模块,打包类型为pom,此模块不需要src
<packaging>pom</packaging>
定义当前模块构建时关联的其他模块名称
<modules>
<module>ssm-controller</module>
<module>ssm-service</module>
<module>ssm-dao</module>
<module>ssm-pojo</module>
</modules>
参与集合的模块构建顺序与模块间的依赖有关,与配置无关
3、继承
作用:通过继承,可以实现在子工程中沿用父工程中的配置
使用:在子工程中声明父工程坐标与对应路径
注意,继承和聚合一样,父工程中也只有一个pom文件
<parent>
<groupId>. . .</groupId>
<artifactId>. . .</artifactId>
<version>. . .</version>
<relativePath>. . .</relativePath>
</parent>
在父工程中管理依赖
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${springframework.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
插件管理
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
这里声明只是为子工程设定版本,并不是实际的去引用依赖
子工程继承之后,不在需要写完整的GAV,让父工程统一管理
<groupId>com.juvenxu.mvnbook.account</groupId>
<artifactId>account-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
只需要写
<artifactId>account-parent</artifactId>
同时,在依赖和插件中也只需要写
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
版本通过父工程继承
可继承的pom元素
- groupId:项目组ID,项目坐标的核心元素
- version: 项目版本, 项目坐标的核心元素
- description: 项目的描述信息
- organization: 项目的组织信息
- inceptionYear: 项目的创始年份
- url: 项目的URL地址
- developers: 项目开发者信息
- contributors: 项目的贡献者信息
- distributionManagement: 项目的部署配置
- issueManagement: 项目的缺陷跟踪系统信息
- ciManagement: 项目的持续集成系统信息
- scm: 项目的版本控制系统信息
- mailingLists: 项目的邮件列表信息
- properties: 自定义的maven属性
- dependencies: 项目的依赖配置
- dependencyManagement: 项目的依赖管理配置
- repositories: 项目的仓库配置
- build: 包括项目的源码目录配置、输出目录配置、插件配置、插件管理配置等
- reporting: 包括项目的报告输出目录配置、报告插件配置等
继承与聚合
- 作用
- 聚合用于快速构建项目
- 继承用于快速配置
- 相同点
- 聚合与继承的pom文件打包方式都为pom,可以将两种关系制作在同一个pom文件中
- 聚合与继承属于设计模式,并无实际的模块内容
- 不同点
- 聚合是在当前模块中配置关系,聚合可以感知到参与聚合的模块有哪些
- 继承是在子模块中配置关系,父模块无法感知哪些子模块继承了自己
4、属性
Maven中允许自定义属性,相当于变量,在需要的地方引用
<properties>
<spring.framework>4.0.4.RELEASE</spring.framework>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.framework}</version>
</dependency>
</dependencies>
此外,maven属性分为
- 内部属性
- 内置属性
- 项目属性
- setting属性
- 自定义属性
- 外部属性
- java系统属性
- 环境变量属性
具体不在这里赘述
5、版本管理
工程版本
- SNAPSHOT (快照版本)
- 项目开发过程中,为方便团队成员合作,解决模块间相互依赖和时时更新的问题,开发者对每个模块进行构建的时候,输出的临时性版本叫快照版本(测试阶段版本)
- 快照版本会随着开发的进展不断更新
- RELEASE (发布版本)
- 项目开发到进入阶段里程碑后,向团队外部发布较为稳定的版本,这种版本所对应的构件文件是稳定的,即便进行功能的后续开发,也不会改变当前发布版本内容,这种版本称为发布版本
工程版本号约定
- 约定规范:
- <主版本>.<次版本>.<增量版本>.<里程碑版本>
- 主版本:表示项目重大架构的变更,如: spring5相较 于spring4的迭代
- 次版本:表示有较大的功能增加和变化,或者全面系统地修复漏洞
- 增量版本:表示有重大漏洞的修复
- 里程碑版本:表明- -个版本的里程碑(版本内部)。这样的版本同下一-个正式版本相比,相对来说不是很稳定,有待更多的测试
- 范例:
5.1.9.RELEASE
6、资源配置
maven支持配置文件使用pom文件里面配置的属性
使用:在pom文件中定义属性和属性值,在配置文件中使用${属性} 的方式引用
<properties>
<jdbc.url>jdbc:mysql://localhost:3306/de01</jdbc.url>
</properties>
.....
配置资源文件对应的信息
<resources>
<resource>
<!-设定配置文件对应的位置目录,支持使用属性动态设定路径-->
<directory>${project.basedir}/src/main/resources</directory>
<!--开启对配置文件的资源加载过滤-->
<filtering>true</ filtering>
</resource>
</resources>
7、多环境开发配置
<!--多环境配置-->
<!--创建多环境-->
<profiles>
<!--定义具体的环境:生产环境-->
<profile>
<!--定义环境对应的唯一名称-->
<id>pro_ env</id>
<!--定义环境中专用的属性值-->
<properties>
<jdbc.ur1>jdbc:mysql://127.1.1.1:3306/ssmdb</jdbc.ur1>
</ properties>
<!--设置默认启动-->
<activation>
<activeByDefault>true</ activeByDefault>
</activation>
</profi1e>
<!--定义具体的环境:开发环境-->
<profile>
<id>dev_env</id>
....
</profi1e>
</profiles>
8、跳过测试
- 使用命令跳过测试
mvn 指令 -D skipTests
-
使用idea界面操作
-
通过配置插件
<plugin>
<artifactId>maven- surefire -plugin</artifactid>
<version>2.22. 1</version>
<configuration>
<skipTests>true</ skipTests><!--设置跳过测试-->
<includes> <!-- 包含指定的测试用例-->
<include>**/User*Test.java</include>
</includes>
<excludes><!--排除指定的测试用例-->
<exclude>**/User*TestCase.java</exclude>
</excludes>
</configuration>
</p1ugin>
9、私服
Nexus仓库类型
Nexus仓库类型有三种:
1.hosted:宿主仓库(服务器本地仓库):通常我们上传自己的依赖到这一类型的仓库,比如公司的第二方库。
2.proxy:代理仓库:它们被用来代理远程的公共仓库,如maven中央仓库
3.group:仓库组:仓库的集合,把多个仓库的依赖都整合到一个大的集合中来;用来合并多个hosted/proxy仓库,当你的项目希望在多个repository使用资源时就不需要多次引用了,只需要引用一个group即可。
安装好Nexus后,系统会预先自带几个仓库:如图:
下面说说,另外三种仓库的作用:
1.Releases: 这里存放我们自己项目中发布的构建,通常是Release版本的,已经正式发布的。
2.Snapshots:存放临时的依赖,非最终版本、非稳定版本的依赖,比如你正在开发的starter,你的同事需要引用里面的类,就可以发布到这个类型的仓库中。
3.3rd Party:存放第三方的依赖。
安装nexus
下载之后直接解压即可
启动nexus
切换到安装目录下的bin目录下的命令行
启动:./nexus start
关闭:./nexus stop
端口修改:端口可以在配置文件中修改 xxx/nexus-3.28.1-01/etc/nexus-default.properties
浏览器访问 \http://localhost:8081即是nexus登陆页面
登录
账户:admin
密码:查看 sonatype-work/nexus3/admin.password
基础操作
./nexus status 查看启动状态
./nexus stop 停止
./nexus restart重启
配置私服的镜像路径
获取资源的路径,配置仓库组,表示从仓库组中获取资源
在settings.xml 文件的 mirrors 内添加以下镜像地址
<mirror>
<id>maven-public</id>
<name>maven-public</name>
<mirrorOf>*</mirrorOf>
<url>http://localhost:8081/repository/maven-public/</url>
</mirror>
配置服务器信息
本地访问仓库的权限,用于上传资源
<!-- 服务器的账户密码配置-->
<servers>
<server>
<!-- id可以随便取 但是在pom中引用的时候需要保持一致-->
<id>maven_release</id>
<username>admin</username>
<password>admin</password>
</server>
<server>
<id>maven_snapshots</id>
<username>admin</username>
<password>admin</password>
</server>
<server>
<id>maven-central</id>
<username>admin</username>
<password>admin</password>
</server>
</servers>
配置当前项目访问私服上传资源保存位置(pom.xml)
<distributionManagement><!-- 远程部署管理信息 -->
<!-- 项目部署到私服配置 id和上面server中配置的id一致-->
<repository><!--部署项目产生的构件到远程仓库需要的信息 -->
<id>maven_release</id>
<name>maven-releases</name>
<url>http://localhost:8081/repository/maven-releases/</url>
</repository>
<snapshotRepository><!-- 如果没有配置该元素,默认部署到repository元素配置的仓库 -->
<id>maven_snapshots</id>
<name>maven-snapshots</name>
<url>http://localhost:8081/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
发补资源到私命令
mvn deploy