原创文章,欢迎转载。转载请注明:转载自IT人故事会,谢谢!
原文链接地址:『互联网架构』软件架构-环境搭建maven(三)
maven所有java开发标准的构建工具,之前才入行的时候听过ant来进行构建,但是现在基本不存在了 ,maven是一个体系结构的管理,也是个编译方式的管理。源码:https://github.com/limingios/netFuture 文件夹Nexus
maven 历史
Maven最初设计,是以简化Jakarta Turbine项目的建设。在几个项目,每个项目包含了不同的Ant构建文件。 JAR检查到CVS。 Apache组织开发Maven可以建立多个项目,发布项目信息,项目部署,在几个项目中JAR文件提供团队合作和帮助。
maven是什么?
Maven是基于项目对象模型(POM project object model),可以通过一小段描述信息(配置)来管理项目的构建,报告和文档的软件项目管理工具,简单的说就是用来管理项目所需要的依赖且管理项目构建的工具。Maven现在越来越流行,已经逐步取代Ant。它比Ant单一的批处理功能提供更多实用服务。
maven用之前
在没有Maven之前,我们开发一个项目,需要自行导入各种不同的jar包。当依赖包数量多起来,就很难管理了。而且,如果团队开发时,一个人提交的项目所使用的IDE版本与另一个人的不一致,那么所提及的项目就可能不能正常地在别人的IDE中编译、运行。总的来说,大概有以下几类问题:
- jar包太多,需要手动下载、导入,比较麻烦。
- jar包有依赖冲突时,需要自行排查。
- 使用ant脚本构建项目时,需要写很多重复的任务。
- 项目拷贝给别人时,不仅源代码,还需要拷贝大量jar包。
- 测试项目时,需要一个个运行测试。
- 使用svn或者cvs每次都需要将jar包放入配置库中,每次下载一个项目都需要下载几百兆。
maven做什么?
- 依赖管理:通过一个xml文件,统一管理项目中所以jar包。开发项目时,需要用到的jar包只需在配置文件中配置好几个相关信息,Maven就会自动下载、导入到项目中,并且如果该jar包有依赖包,也会自动一并下载、导入。如果项目有jar包依赖冲突,只需通过Maven的 mvn -X compile dependency:tree -Dverbose 指令即可自动排查出冲突的jar包信息。
- 项目构建:这一步类似Ant,可以通过Maven的配置脚本批处理项目的编译、测试、打包、部署、发布等操作.
- 信息管理:管理项目的相关信息,比如版本信息、开发者信息等。
maven的目录结构
- 根目录必须有src和pom.xml文件,target目录。
- target目录可选主要存放注解和一些class文件。
- src下必须有main。
- main下有java包,resources资源包,webapp包。
pom的组成
POM 文件介绍与基本组成
说明:全称是Project Object Model,通俗点的话说就是要对构建的项目进行建模。组成的基本元素:
元素 | 可选值 | 描述 |
---|---|---|
groupId | 分组ID | |
artifactId | 模块ID | |
version | 版本 | |
packaging | 打包类型:pom、jar、war | |
modelVersion | 对应的超级pom 版本 | |
dependencies | 项目依懒包 |
maven jar包的流程
- maven jar先在本地找,查找本地
- 本地找不到去远程仓库找
- 有的公司有自己的私服,本地找不到先找自己的私服
- 私服找不到去远程仓库中找,远程找到后会把jar包丢到私服里面
远程仓库的配置
maven的安装路径下,有个lib,lib里面有个maven-model-build.jar,里面有个pom文件。里面写明白了,我们的jar包去哪里找。
maven repository 与镜像地址
https://repo.maven.apache.org/maven2 这个地址是国际的远程仓库,因为国内网络不太稳定,除非科学上网,但是感觉还是没有国内的仓库方便。
1.国内一般使用阿里云仓库
2.oschina的仓库
http://mvnrepository.com maven 仓库用于查找所需要pom项目
http://repo1.maven.org/maven2/ 全球总仓库1
http://repo2.maven.org/maven2/ 全球总仓库2
http://maven.aliyun.com/nexus/content/groups/public/ 阿里云镜像仓库
http://maven.oschina.net/content/groups/public/ oschina 镜像仓库
镜像配置
修改settings.xml 文件
<mirrors>
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
<!-- 中央仓库1 -->
<mirror>
<id>repo1</id>
<mirrorOf>central</mirrorOf>
<name>Human Readable Name for this Mirror.</name>
<url>http://repo1.maven.org/maven2/</url>
</mirror>
<!-- 中央仓库2 -->
<mirror>
<id>repo2</id>
<mirrorOf>central</mirrorOf>
<name>Human Readable Name for this Mirror.</name>
<url>http://repo2.maven.org/maven2/</url>
</mirror>
<!-- 阿里仓库镜像 -->
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>*</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
<!-- OSchina仓库镜像 -->
<mirror>
<id>CN</id>
<name>OSChina Central</name>
<url>http://maven.oschina.net/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
maven的基本命令
mvn 基本命令
mvn clean // 清理
mvn compile // 编译
mvn test // 测试
mvn package // 打包
mvn install // 打包并上传到本地仓库
mvn depeloy // 上传到远程仓库
mvn -Dmaven.test.skip=true // 跳过测试
scope
scope的默认值是compile,那么scope还能有哪些选项呢?
-
compile:默认值 他表示被依赖项目需要参与当前项目的编译,还有后续的测试,运行周期也参与其中,是一个比较强的依赖。打包的时候通常需要包含进去
-
test:依赖项目仅仅参与测试相关的工作,包括测试代码的编译和执行,不会被打包,例如:junit
-
runtime:表示被依赖项目无需参与项目的编译,不过后期的测试和运行周期需要其参与。与compile相比,跳过了编译而已。例如mysql-JDBC驱动,适用运行和测试阶段。
-
provided:打包的时候可以不用包进去,别的设施会提供。事实上该依赖理论上可以参与编译,测试,运行等周期。相当于compile,但是打包阶段做了exclude操作,例如sevlet,在运行的时候用,其实在打包的时候并不需要打进去,tomcat里面自带的有servlet。
-
system:从参与度来说,和provided相同,不过被依赖项不会从maven仓库下载,而是从本地文件系统拿。需要添加systemPath的属性来定义路径
maven的项目类型
- 聚合项目
假设有项目A和项目B,我们想一次性构建两个项目,而不是到两个模块的目录下分别执行mvn命令。maven聚合解决了该问题。
这时候我们要创建另外一个项目ALL,然后通过该模块构建整个项目的所有模块。ALL作为一个maven项目,必须拥有自己的pom文件。 如果有idea打开maven的展示的时候对于多项目总会有个root
- 继承项目
子项目A,B需要继承项目ALL中的POM配置,那么就需要使用到继承,java项目service模块依赖dao模块,dao模块依赖mapper模块。parent元素中的属性对应的都是父项目中的内容。在parent元素中还有一个属性relativePath,maven会通过这个路径去查找父项目的pom.xml,如果找不到会从本地仓库中查找。relativePath的默认值是../pom.xml,也就是默认父POM在上一层目录下。
- 依赖项目
子项目都会继承父项目的依赖关系,如果子项目不需要父项目的依赖关系,maven提供的dependencyManagement元素能让子模块继承到父模块的依赖配置,有能保证子模块的灵活性。dependencyManagement元素下的依赖声明不会引入实际的依赖,能约束dependencies下的依赖使用。父项目中使用该元素声明的依赖既不会给父项目引入依赖也不会给子项目引入依赖,但是该配置会被继承。如果子项目中不声明经过父项目dependencyManagement修饰的依赖,那么子项目就不会引入该依赖。
私服的搭建和使用Nexus
学过上边的内容其实就够了,但是如果你的定位不是小兵,而是一名技术的经理的话,不仅需要了解和掌握上边的知识基本的命令,还需要搭建整个私服的maven环境。
- 历史Nexus
Nexus是Maven仓库管理器,也可以叫Maven的私服。Nexus是一个强大的Maven仓库管理器,它极大地简化了自己内部仓库的维护和外部仓库的访问。利用Nexus你可以只在一个地方就能够完全控制访问和部署在你所维护仓库中的每个Artifact。Nexus是一套“开箱即用”的系统不需要数据库,它使用文件系统加Lucene来组织数据。
Nexus不是Maven的核心概念,它仅仅是一种衍生出来的特殊的Maven仓库。对于Maven来说,仓库只有两种:本地仓库和远程仓库。
- Nexus私服的搭建
本次的安装Nexus,我直接使用docker的方式,去除了很多复杂的配置。
通过源码生成1个虚拟机,准备工作。vagrant已经安装了 对应的docker。
用docker安装nexus就是为了避免环境变量,用户赋权等复杂的操作。对于vagrant的如何安装不用的系统不一样可以参看
mac 安装vgarant :https://idig8.com/2018/07/29/docker-zhongji-07/
window安装vgaranthttps://idig8.com/2018/07/29/docker-zhongji-08/
系统类型 | IP地址 | 节点角色 | CPU | Memory | Hostname |
---|---|---|---|---|---|
Centos7 | 192.168.66.100 | Nexus | 2 | 2G | Nexus |
(1). 虚拟机vagrant讲述安装的步骤
(2).机器window/mac开通远程登录root用户下
su -
# 密码
vagrant
#设置 PasswordAuthentication yes
vi /etc/ssh/sshd_config
sudo systemctl restart sshd
(3). 安装nexus
通过shell脚本的方式运行https://hub.docker.com/r/sonatype/nexus/
mkdir nexus
cd nexus
mkdir data
chown -R 200 data
pwd
ll
vi start.sh
start.sh
#!/bin/bash
cur_dir=`pwd`
docker stop nexus
docker rm nexus
docker run -d -p 8081:8081 \
--name nexus \
-v ${cur_dir}/data:/sonatype-work \
sonatype/nexus
运行shell脚本
sh start.sh
访问获取地址http://192.168.66.100:8081/nexus
默认的用户名密码:admin / admin123
- 仓库的类型
- goup(分组仓库)
- hosted (私有仓库,我们自己内部生成的jar文件)
3rd party 就是在公网没有,其他人给你的jar放这里的仓库
Snapshots 本地开发某个模块的快照仓库
Releases 本地开发某个模块的正式版本仓库
- proxy(公网发布的jar文件)
Apache Snapshots apache的快照仓库
Central 重要仓库
对于maven的仓库和镜像的概念一定要理解,仓库是存放mavenjar的地方,镜像是我们下载的时候需要下载的地址。阿里云,码云的maven都是镜像而非仓库的概念。
- 如何本地的项目访问私服,上传jar包
maven 私服的setting.xml配置,注入如果是特定的仓库修改mirrorOf 换成对应的repository id
mirrorOf * 的含义,就是所有的jar包下载都必须走私服,不能走其他的镜像和仓库
<?xml version="1.0" encoding="UTF-8"?>
<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">
<pluginGroups></pluginGroups>
<proxies></proxies>
<servers>
<server>
<id>nexus-releases</id>
<username>admin</username>
<password>admin123</password>
</server>
<server>
<id>nexus-snapshots</id>
<username>admin</username>
<password>admin123</password>
</server>
</servers>
<mirrors>
<mirror>
<id>nexus-releases</id>
<mirrorOf>*</mirrorOf>
<url>http://192.168.66.100:8081/nexus/content/groups/public</url>
</mirror>
<mirror>
<id>nexus-snapshots</id>
<mirrorOf>*</mirrorOf>
<url>http://192.168.66.100:8081/nexus/content/groups/public-snapshots</url>
</mirror>
</mirrors>
<profiles>
<profile>
<id>nexus</id>
<repositories>
<repository>
<id>nexus-releases</id>
<url>http://nexus-releases</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</repository>
<repository>
<id>nexus-snapshots</id>
<url>http://nexus-snapshots</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>nexus-releases</id>
<url>http://nexus-releases</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</pluginRepository>
<pluginRepository>
<id>nexus-snapshots</id>
<url>http://nexus-snapshots</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>nexus</activeProfile>
</activeProfiles>
</settings>
pom的配置
<distributionManagement>
<!-- 两个ID必须与 setting.xml中的<server><id>nexus-releases</id></server>保持一致-->
<repository>
<id>nexus-releases</id>
<name>Nexus Release Repository</name>
<url>http://192.168.66.100:8081/nexus/content/repositories/releases</url>
</repository>
<snapshotRepository>
<id>nexus-snapshots</id>
<name>Nexus Snapshot Repository</name>
<url>http://192.168.66.100:8081/nexus/content/repositories/snapshots</url>
</snapshotRepository>
</distributionManagement>
maven插件的使用
- 官网
-
随便找一个maven的插件,看它如何使用
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<id>attach-sources</id>
<phase>verify</phase> <!--什么时间?生命周期的阶段-->
<goals>
<goal>jar-no-fork</goal><!--干什么事情?目标是什么-->
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
maven生命周期
官方介绍http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html ,生命周期都是按照顺序执行的,从上到下。插件的运行就是生命周期来完成的,某个插件什么时间,执行什么事情,所以使用插件的时候一定要了解生命周期。
clean lifecycle : 构建前的清理工作
• pre-clean 执行一些需要在clean之前完成的工作
• clean 移除所有上一次构建生成的文件
• post-clean 执行一些需要在clean之后立刻完成的工作
Default lifecycle: 构建的核心部分,编译、打包、部署、上传
• validate<里程碑> 项目及所必须的环境验证
• initialize 初始化构建状态,例如设置属性或创建目录。
• 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 lifecycle:项目报告生成,站点文档生成
• pre-site 执行一些需要在生成站点文档之前完成的工作
• site 生成项目的站点文档
• post-site 执行一些需要在生成站点文档之后完成的工作,并且为部署做准备
• site-deploy 将生成的站点文档部署到特定的服务器上
PS:百度太多了maven的安装,也没必要在这里说了,重点是maven私服的搭建,还有maven插件和生命周期,插件和生命周期的配合才能合理化的使用maven进行构建,通过对maven的理解可以很深入的了解。项目高度自动化构建,依赖管理(这是使用Maven最大的好处),仓库管理。
网友评论