Maven 的简介与使用
Maven 介绍
Maven 是一个项目管理、整合的工具,它简化了工程的构建过程,并对其标准化,它无缝衔接了编译、发布、文档生产、团队合作和其他任务。
开发者可以用它来做以下任务:
- 构建
- 文档生成
- 报告
- 依赖管理
- SCMs
- 发布
- 分发
- 邮件列表
Maven 工程结构和内容被定义在一个 xml 文件中 - pom.xml(Project Object Model),此文件是整个 Maven 系统的基础组件,开发者可以用它来配置生命周期目标和工程依赖,大部分的工程管理和构建相关的任务是由 Maven 插件完成的。
Maven的生命周期和插件
一个完整的项目构建过程通常包括清理、编译、测试、打包、集成测试、验证、部署等步骤,maven 从中抽取了一套完善的、易扩展的生命周期。maven 的生命周期是抽象的,其中的具体任务都是交由相应插件完成。maven 为大多数构建任务编写并绑定了默认的插件,用户也可以自行配置或编写插件。
三套生命周期
maven 定义了三套生命周期:clean、default、site,每个生命周期包含了一些阶段(phase)。三套生命周期相互独立,但各个生命周期中的 phase 却是有顺序的,且后面的 phase 依赖于前面的 phase。执行某个 phase 时,其前面的 phase 会顺序执行,但不会触发另外两套生命周期中的任何 phase。
clean 生命周期
- pre-clean:执行清理前的工作
- clean:清理上一次构建生成的所有文件
- post-clean:执行清理后的工作
default 生命周期
default 生命周期是最核心的,它包含了构建项目时真正需要执行的所有步骤。
site 生命周期
- pre-site
- site:生成项目的站点文档
- post-site
- site-deploy:发布生成的站点文档
maven 插件
maven 的核心文件很小,主要任务都是由插件来完成的。
一个插件通常可以完成多个任务,每一个任务就叫做插件的一个目标。如执行 mvn install 命令时,调用的插件和执行的插件目标如下
每个插件有哪些目标,官方文档有更详细的说明:Maven Plugins
- 将插件绑定到生命周期
Maven的生命周期是抽象的,实际需要插件来完成任务,这一过程是通过将插件的目标(goal)绑定到生命周期的具体阶段(phase)来完成的。如:将maven-compiler-plugin插件的compile目标绑定到default生命周期的compile阶段,完成项目的源代码编译:
- 内置的绑定
maven 对一些生命周期的阶段(phase)默认绑定了插件的目标,因为不同的项目有 jar、war、pom 等不同的打包方式,因此对应的有不同的绑定关系,其中针对 default 生命周期的 jar 包打包方式的绑定关系如下
- 自定义绑定
用户可以根据需要将任何插件目标绑定到任何生命周期的阶段。如:将maven-source-plugin的jar-no-fork目标绑定到default生命周期的package阶段,这样,以后在执行mvn package命令打包项目时,在package阶段之后会执行源代码打包,生成如:ehcache-core-2.5.0-sources.jar形式的源码包。
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>attach-source</id>
<phase>package</phase><!-- 要绑定到的生命周期的阶段 -->
<goals>
<goal>jar-no-fork</goal><!-- 要绑定的插件的目标 -->
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
- 配置插件
Maven插件高度易扩展,可以方便的进行自定义配置。如:配置maven-compiler-plugin插件编译源代码的JDK版本为1.7:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
- 插件仓库
跟其他构件一样,插件也是根据坐标存储在Maven仓库中。超级POM中Maven配置的默认插件远程仓库如下:
<pluginRepositories>
<pluginRepository>
<id>central</id>
<name>Central Repository</name>
<url>http://repo.maven.apache.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<updatePolicy>never</updatePolicy>
</releases>
</pluginRepository>
</pluginRepositories>
Maven 常用命令
常用命令
- 编译源代码: mvn compile
- 编译测试代码:mvn test-compile
- 运行测试:mvn test
- 产生site:mvn site
- 打包:mvn package
- 在本地Repository中安装jar:mvn install
- 清除产生的项目:mvn clean
- 生成eclipse项目:mvn eclipse:eclipse
- 生成idea项目:mvn idea:idea
- 组合使用goal命令,如只打包不测试:mvn -Dtest package
- 编译测试的内容:mvn test-compile
- 只打jar包: mvn jar:jar
- 只测试而不编译,也不测试编译:mvn test -skipping compile -skipping test-compile
( -skipping 的灵活运用,当然也可以用于其他组合命令)
清除eclipse的一些系统设置:mvn eclipse:clean
其他命令:
- 生成项目
mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
- 测试项目打包之后的jar
java -cp target/my-app-1.0-SNAPSHOT.jar com.mycompany.app.App
- 查看项目依赖:mvn dependency:analyze
- 查看项目直接和传递依赖:mvn dependency:tree
- 查看maven构建时有效的pom:mvn help:effective-pom
Maven 继承与聚合
Maven为我们提供了项目(模块)的聚合功能,也就是说模块最终要统一到一个项目,每次打包编译,我们只需对 “总项目” 进行即可,而无需关心各个模块。
Maven同样支持继承的操作,也就是说将模块中的相同代码放到父类项目(模块)中,其他模块只需继承即可使用,同时也能很好地解决jar包版本冲突问题。
注意:聚合 标签指定的是相对的项目,而继承指定的则是相对的pom文件
示例:
bianjie-base.pom
<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.bianjie</groupId>
<artifactId>bianjie-base</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<!--指定Maven用什么编码来读取源码及文档 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!--指定Maven用什么编码来呈现站点的HTML文件 -->
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>1.5.2.RELEASE</spring-boot.version>
<junit.version>3.8.1</junit.version>
</properties>
<!-- 依赖管理:管理子 pom 中的依赖,不会被子 pom 所继承 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.bianjie</groupId>
<artifactId>bianjie-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.bianjie</groupId>
<artifactId>bianjie-util</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.bianjie</groupId>
<artifactId>bianjie-dao</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.bianjie</groupId>
<artifactId>bianjie-shiro</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>${spring-boot.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 公共依赖:会被子 pom 所继承 -->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<!-- download jars from nexus -->
<repositories>
<repository>
<id>kbm_public</id>
<name>kbm maven Repository</name>
<url>http://106.15.33.15:9081/repository/kbm_public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<!-- upload jars to nexus -->
<distributionManagement>
<repository>
<id>kbm_release</id>
<url>http://106.15.33.15:9081/repository/kbm_release/</url>
</repository>
<snapshotRepository>
<id>kbm_snapshot</id>
<url>http://106.15.33.15:9081/repository/kbm_snapshot/</url>
</snapshotRepository>
</distributionManagement>
</project>
bianjie-api-web
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.bianjie</groupId>
<artifactId>bianjie-base</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>bianjie-api-web</artifactId>
<packaging>war</packaging>
<name>bianjie-api-web Maven Webapp</name>
<build>
<finalName>bianjie-api-web</finalName>
</build>
<dependencies>
<dependency>
<groupId>com.bianjie</groupId>
<artifactId>bianjie-common</artifactId>
</dependency>
<dependency>
<groupId>com.bianjie</groupId>
<artifactId>bianjie-util</artifactId>
</dependency>
<dependency>
<groupId>com.bianjie</groupId>
<artifactId>bianjie-dao</artifactId>
</dependency>
<dependency>
<groupId>com.bianjie</groupId>
<artifactId>bianjie-shiro</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
</dependency>
</dependencies>
</project>
bianjie-modules
<?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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.bianjie</groupId>
<artifactId>bianjie-base</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>bianjie-modules</artifactId>
<packaging>pom</packaging>
<modules>
<module>bianjie-dao</module>
<module>bianjie-common</module>
<module>bianjie-util</module>
<module>bianjie-shiro</module>
</modules>
</project>
bianjie-common
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.bianjie</groupId>
<artifactId>bianjie-modules</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>bianjie-common</artifactId>
<name>bianjie-common</name>
</project>