maven
eclipse配置:
- 切换镜像:在windows--preference--maven--user setting里面,导入全局或用户的settings.xml,才能够切换镜像。
功能说明:专门为java项目打造的管理和构建工具
- 提供一套标准化的项目结构。
- 提供一套标准化的构建流程(编译、测试、打包、发布...)
- 提供一套依赖管理机制
maven管理的java项目,目录结构默认为:
a-maven-project
├── pom.xml
├── src
│ ├── main
│ │ ├── java
│ │ └── resources
│ └── test
│ ├── java
│ └── resources
└── target
项目的根目录a-maven-project
是项目名,它有一个项目描述文件pom.xml
,存放Java源码的目录是src/main/java
,存放资源文件的目录是src/main/resources
,存放测试源码的目录是src/test/java
,存放测试资源的目录是src/test/resources
,最后,所有编译、打包生成的文件都放在target
目录里。这些就是一个Maven项目的标准目录结构。
pom.xml文件:(POM,Project Object Model,项目对象模型)
- 项目依赖
- 插件
- 执行目标
- 项目构建 profile
- 项目版本
- 项目开发者列表
- 相关邮件列表信息
父(Super) POM是Maven默认的POM,所有的POM都继承 子一个父POM(无论是否显式)。Maven使用effective POM(Super pom加上项目自己的配置)来执行,帮助开发者少在pom.xml中设置配置。
- 查看Super POM默认配置(可重写):
mvn help:effective-pom
<project ...>
<modelVersion>4.0.0</modelVersion>
<groupId>com.itranswarp.learnjava</groupId>
<artifactId>hello</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<properties>
...
</properties>
<dependencies>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
</project>
其中,groupId
类似于Java的包名,通常是公司或组织名称,artifactId
类似于Java的类名,通常是项目名称,再加上version
,一个Maven工程就是由groupId
,artifactId
和version
作为唯一标识。
注意:我们在引用其他第三方库的时候,也是通过这3个变量确定。例如,依赖commons-logging
:
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
使用<dependency>
声明一个依赖后,Maven就会自动下载这个依赖包并把它放到classpath中。
中央仓库:maven是如何知道从哪下载依赖的呢?其通过维护一个中央仓库(repo1.maven.org),其他第三方库将自己的jar包及相关信息传入其仓库,maven就可以从中央仓库把所需的依赖下载下来。
- 第一次编译时(对于compile类型依赖),需要下载所以耗时比较长,但之后maven会将其缓存在directory/.m2/中,以后的每次编译运行则不会再从仓库下载。
安装maven
在官网下载,然后按照readme安装即可。
POM标签大全详解
名词说明:
- SCM:Source Control Management。主要供Maven web和其他插件使用。
maven功能介绍:
仓库
maven仓库帮我们储存、管理构件(任何一个依赖、插件、或项目构建的输出都可称构件),构件主要是JAR文件(WAR、ZIP、POM等等)。
三大类:
-
本地库:当第一个执行maven命令是,会创建本地库,默认目录在%USER_HOME%/.m2/repository/;可以在%M2_HOME%/conf/settings.xml中定义其他路径
... <settings ....> <localRepository>newPath</localRepository> </settings> ...
-
中央库:使用这个url:http://search.maven.org/#browse可以浏览需要的构建
概念:
- 由Maven社区管理。
- 不需要配置
- 包含了绝大多数流行的开源java构建,及其相关信息(源码、作者、许可证等等)
-
远程库:由开发者自定义仓库,里面也是包含了jar构建。通常为大公司的镜像,如阿里云。
远程库声明:在pom中,项目里添加:
<project ....> ... <dependency> //该依赖无法从中央仓库获取,只能从下方定义的仓库 ... </dependency> ... <repositories> //对应于上面已经有了的dependency。 <repository> <id>RepoName</id> <url>url</url> </repository> </repositories> ... </project>
镜像声明:
<project ....> ... <mirror> <id>alimaven</id> <name>aliyun maven</name> <url>http://maven.aliyun.com/nexus/content/groups/public/</url> <mirrorOf>central</mirrorOf> </mirror> ... </project>
依赖搜索顺序
- 本地仓库搜索,如果未找到,往下
- 中央仓库搜索:
- 如果未找到,并且已经设置了远程仓库,则去远程仓库中搜索依赖文件,当找不到依赖时,抛出异常。
- 如果没有设置远程仓库,则抛出错误。
说明:当从中央仓库(repo1.maven.org)下载很慢时,可以选择镜像仓库。镜像仓库定期从中央仓库同步。
中国区:可使用aliyun的maven镜像仓库:
依赖管理
说明:当项目需要引入其他API jar包时,不用手动到他们官网下载,并下载其所依赖项,然后放到classpath里。直接用maven的pom.xml导入直接依赖的包,Maven会查看其的pom.xml,并沿着依赖关系向上,自动下载该包所依赖的包。
如:我们的项目依赖abc
,abc
又依赖xyz
,我们只需要导入abc
即可,maven自动下载xyz
。
例:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.4.2.RELEASE</version>
</dependency>
当我们声明该依赖时,maven自动解析并判断最终需要的其他二三十个依赖。
spring-boot-starter-web
spring-boot-starter
spring-boot
sprint-boot-autoconfigure
spring-boot-starter-logging
logback-classic
logback-core
slf4j-api
jcl-over-slf4j
slf4j-api
jul-to-slf4j
slf4j-api
log4j-over-slf4j
slf4j-api
spring-core
snakeyaml
spring-boot-starter-tomcat
tomcat-embed-core
tomcat-embed-el
tomcat-embed-websocket
tomcat-embed-core
jackson-databind
...
手动管理费时费力且易出错,maven来管理非常好。
依赖管理技巧
当项目很复杂很多时,可以设置一个公共依赖:父pom,作为所有顶层包的pom所直接依赖对象。其<package>
类型为pom
,仅做生成pom用。其包含了所有的依赖项,好统一管理。
依赖关系
分类:四种依赖关系:complie
、test
、runtime
、provided
:
scope | 说明 | 示例 |
---|---|---|
compile | 编译时需要用到该jar包(默认) | commons-logging |
test | 编译Test时需要用到该jar包 | junit |
runtime | 编译时不需要,但运行时需要用到 | mysql |
provided | 编译时需要用到,但运行时由JDK或某个服务器提供 | servlet-api |
其中,默认的compile
是最常用的,Maven会把这种类型的依赖直接放入classpath。
test
依赖表示仅在测试时使用,正常运行时并不需要。最常用的test
依赖就是JUnit:
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.3.2</version>
<scope>test</scope>
</dependency>
runtime
依赖表示编译时不需要,但运行时需要。最典型的runtime
依赖是JDBC驱动,例如MySQL驱动:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
<scope>runtime</scope>
</dependency>
provided
依赖表示编译时需要,但运行时不需要。最典型的provided
依赖是Servlet API,编译的时候需要,但是运行时,Servlet服务器内置了相关的jar,所以运行期不需要:
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.0</version>
<scope>provided</scope>
</dependency>
唯一ID
对于某个依赖,maven需要3个变量即可确定该依赖:
- groupId:属于组织的名字——类似于java的包名。
- artifactId:该jar包的名字——类似于java的类名
- version:该jar包版本。
IDE中使用Maven
几乎所有IDE都支持maven,如Eclipse中可直接创建或导入Maven项目。如果有错,右键项目,选择Maven-Update Project更新。
构建流程
说明:maven不仅有标准化的项目结构,还有标准化的构建流程,自动实现编译、打包、发布等。
maven使用lifecycle、phase、goal来实现标准的构建流程。按phase区分大体来说生命周期分为default、clean、site(项目站点文档创建)。
名词说明:
-
lifecycle(生命周期):maven的生命周期,由一系列的阶段构成。
内置的生命周期
default
,包含以下phase:- 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
- pre-integration-test
- integration-test
- post-integration-test
- verify
- install :开发环境中,用于构建、安装工程到本地仓库。
- deploy
-
phase(阶段):(具体实现由具体插件完成)
大多数phase在执行过程中什么都不做,因为我们通常没有在pom.xml中配置相关的设置。
经常用到的phase其实只有几个:
- clean:清理
- compile:编译
- test:运行测试
- package:打包
-
Goal:
执行一个phase会自动触发一个或多个goal,不用特定指定goal,如:
执行的Phase 对应执行的Goal compile compiler:compile test compiler:testCompile surefile:test
类比一下就明白了:
- lifecycle相当于Java的package,它包含一个或多个phase;
- phase相当于Java的class,它包含一个或多个goal;
- goal相当于class的method,它其实才是真正干活的。(goal是最小任务单元)
常用生命周期:
-
lifecycle--
mvn package
,Maven会执行default
生命周期直到package这个phase为止。- validate
- .......
- package
lifecycle--
mvn complie
,Maven会执行default
生命周期知道complie这个phase为止。-
lifecycle--
post-clean
,他会执行3个phase:(clean执行前两个)- pre-clean:执行一些需要在clean之前完成的工作
- clean(注意这个clean不是lifecycle,不是嵌套,而是phase)移除所有上一次构建生成的文件
- post-clean:执行一些需要在clean之后立刻完成的工作
-
lifecycle--
site
,会与创建新的报告文档、部署站点等。pre-site:执行一些需要在生成站点文件之前完成的工作
site:生成项目的站点文档
post-site:执行一些需要在生成站点文档后完成的工作
-
site-deploy:将生成的站点文档部署到特定的服务器上
ERROR:当出现缺少goal error时,可以尝试在build里加入plugin:maven-project-info-reports-plugin 和 maven-site-plugin
通用:使用
mvn
后面加一个phase
,其之前的phase
若没被执行则会被先执行,若已执行,则单独执行这个phase。指定多个phase:如:
mvn clean package
先运行clean的生命周期到clean(phase)然后再从validate到package。-
实际开发常用命令:
mvn clean
:清理所有生成的class和jar;mvn clean compile
:先清理,再执行到compile
;mvn clean test
:先清理,再执行到test
,因为执行test
前必须执行compile
,所以这里不必指定compile
;mvn clean package
:先清理,再执行到package
。
说明:大多数情况下,我们只能指定phase,然后默认执行这个(些)phase指定的goal,不能单独使用goal,不过也有列外:mvn tomcat:run
,用于启动tomcat服务器,他们是未绑定的goal,可以在生命周期外执行。
插件
通用语法:
mvn {plugin-name}:{goal-name}
如,java工程可以使用maven-compiler-plugin 的 compile-goal 实现编译:
mvn maven-compiler-plugin:compile-goal
插件类型:
- Build plugins:构建时执行,需在pom.xml中配置。
- Reporting plugins:在网站生成过程中执行,也需要在pom.xml配置。
常用插件:
插件 | 描述 |
---|---|
clean | 构建之后清理目标文件。删除目标目录。 |
compiler | 编译 Java 源文件。 |
surefile | 运行 JUnit 单元测试。创建测试报告。 |
jar | 从当前工程中构建 JAR 文件。 |
war | 从当前工程中构建 WAR 文件。 |
javadoc | 为工程生成 Javadoc。 |
antrun | 从构建过程的任意一个阶段中运行一个 ant 任务的集合。 |
构建配置文件
构建配置文件的类型
大体上分三类:
类型 | 在哪定义 |
---|---|
项目级(Per Project) | 定义在项目的POM文件pom.xml中 |
用户级 (Per User) | 定义在Maven的设置xml文件中 (%USER_HOME%/.m2/settings.xml) |
全局(Global) | 定义在 Maven 全局的设置 xml 文件中 (%M2_HOME%/conf/settings.xml) |
激活方式:
可用多种方式激活Maven的构造配置文件。
使用命令控制台输入显式激活:通过在
<profiles><profile><id>id<id>中的id确定。如:
mvn test -Pid`-
通过maven设置:在%USER_HOMT%/.m2/目录下的setting.xml,在里面添加
<activeProfiles><activeProfile>id</activeProfile></activeProfiles>
即可设置,此时:mvn test
即可。也可以在%M2_HOME%/conf/settings.xml中配置,效果一样。
基于环境变量(用户或者系统变量):通过加入
<activation><property>
——<profile><activation><property><name>env</name><value>test</value></property></activation>...
,然后命令行使用:mvn test -Denv=test
即可。-D是发送到环境变量。操作系统设置(如windows、linux):通过加入
<activation><os>
——...<os><name>Windows 7</name><family>Windows</family><arch>x86</arch><version>5.1.2600</version></os>...
,然后命令行使用:mvn test
即可,当在上述<os>
描述的机器上运行时,会触发该配置文件。文件的存在或缺失:通过加入
<activation><file>
——...<file><missing>path/to/file</missing></file>...
,然后命令行:mvn test
,当缺失该文件时,会触发该profile。
Maven构建java项目
创建java项目
实例——在目录下创建一个简单的java应用项目:(利用maven-archetype-quickstart插件)
mvn archetype:generate -DgroupId=com.myProject -DartifactId=myProject -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
其会生成一个完整的java项目,包含main和test。
可以直接其生成的.java文件中修改填入源码。轻松简单。
构建java项目(package)
实例——在上述建好的项目根目录中:
mvn clean package
error:出现了一个错误:不再支持源选项 5。请使用 7 或更高版本。
-
解决方式:通过在pom.xml的项目里加入:
<properties> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties>
结果:项目里多出target文件夹:包含了各种构建后的信息:jar包、class文件、测试文件等。
说明:
- 测试报告存放在 consumerBanking\target\surefire-reports 文件夹中。
- Maven 编译源码文件,以及测试源码文件。
- 接着 Maven 运行测试用例。
- 最后 Maven 创建项目包。
- 引入外部java:正常引入或创建,放在源码目录即可。
引入外部依赖
说明:当需要第三方库时,需要两步:
①下载第三方库的jar包,到Porject/src/lib (自己新建文件夹、其与main、test在同一目录下)。
-
②在pom.xml中添加依赖:如:
... <dependency> <groupId>..库名称,可以自定义.</group> <artifactId>..同上..</artifactId> <version>..</version> <scope>system</scope> <!-- 作用域 --> <systemPath>${basedir}\src\lib\name.jar</systemPath> <!-- 文件所在系统路径 --> </dependency> ...
Maven模板:
archetype:原型。是一个maven插件,但准确说其提供了maven模板功能,按照该模板生成项目。用法如上述。
site lifecycle 说明
Maven使用一个名叫Doxia的文档处理引擎来创建文档,其可将多种格式的源码(文件)读取成统一的文档模型,其支持的一般文档模型:
格式名 | 描述 | 参考 |
---|---|---|
Apt | 纯文本文档格式 | http://maven.apache.org/doxia/references/apt-format.html |
Xdoc | Maven 1.x 的一种文档格式 | http://jakarta.apache.org/site/jakarta-site2.html |
FML | FAQ 文档适用 | http://maven.apache.org/doxia/references/fml-format.html |
XHTML | 可扩展的 HTML 文档 | http://en.wikipedia.org/wiki/XHTML |
Maven 快照 snapshot
说明:多用于开发团队间,在并没有升级版本,但却频繁有修改提交时,提供快照自动下载,而不用经常互相提醒等。(如果远程仓库是普通版本,当对其有依赖时,不会下载同一个版本的jar。如都是v1.0,但请求依赖者,可以在dependency中将请求版本设置为v1.0-snapshot,即可在项目构建时自动下载最新版)
Maven快照工作:其在日常工作中会自动获取最新的快照,但也可以手动强制使用最新的快照构建:
mvn clean package -U
自动化构建
说明:使用Maven的依赖管理,实现在依赖树中父节点构建后,自动化的更新子节点。(依赖管理实现在pom.xml)
持续集成CI
说明:使用如Hudson的持续集成服务器,来自动管理构建自动化。
Maven自动化部署
项目实际开发过程中,部署的过程包含以下步骤:
- 将所有项目代码提交到代码库如 git、svn,并打上标签。
- 从代码库下载完整的源代码。
- 构建应用
- 储存构建输出的WAR 或 EAR 文件到一个常用的网络位置下。
- 从网络上获取文件并且部署文件到生产站点上。
- 更新文档并更新应用的版本号。
问题:以上开发过程可能涉及多个团队,有可能会因为多团队环境的原因,导致某个步骤出错。
解决方法:
通过结合以下方案来实现自动化部署:
- 使用Maven构建和发布项目
- 使用代码库来管理源代码
- 使用远程仓库管理软件(Jfrog、Nexus)来管理项目二进制文件。(感觉好像Git一个就可以了)
我们会使用Maven中的插件,来创建一个自动化发布过程。
配置pom.xml的重要元素:由于runoob上是用svn,所以我没继续看,不过也就很短,以后看官网吧。