Maven学习
2016-09-09 本文已影响670人
MPPC
在项目中Maven用的一直比较多,以前只知道简单的配置一些依赖,所以找了时间孔浩老师Maven的学习视频学习了一下
Maven初步-手动建立 Maven 项目
- 1、新建一个简单
Maven
项目- 手动
Maven
项目:按照Maven
规范建立项目路径和pom.xml
- 手动
1、示例
maven-ch01/pom.xml
maven-ch01/src/main/java/......
maven-ch01/src/main/resources/...
maven-ch01/src/test/java/......
maven-ch01/src/test/resources/...
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 这是固定值不用修改 -->
<modelVersion>4.0.0</modelVersion>
<!-- GAV 模块唯一的坐标,groupId 一般表示项目 -->
<groupId>org.panpan.hellomaven</groupId>
<!--模块名称 -->
<artifactId>maven-ch01</artifactId>
<!-- 版本号 -->
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<!-- 这里放的是依赖的模块 -->
</dependencies>
</project>
- 2、常用的Maven 命令
mvn compile //编译
mvn test //测试
mvn package //打包
mvn install //安装到本地仓库
mvn deploy //发布到仓库中
- 3、maven 默认的中央仓库的地址
- 在
apache-maven-3.3.9\lib\maven-model-builder-3.3.9.jar\org\apache\maven\model\pom-4.0.0.xml
中
- 在
- 4、通过 Maven 自有的固定模式生成 maven 项目
- 由于maven有一些固定的生成模式,所以使用
mvn archetype:generate
可以自动完成这个骨架的建立 - 随后按照命令的指示建立好 maven 项目
- 当然我们也可以在命令中就设定好相关的参数:
mvn archetype:generate -DgroupId=<groupId> -DartifactId=<artifactId> -Dversion=<version>
- 由于maven有一些固定的生成模式,所以使用
Eclipse 建立 Maven 项目
-
1、在Eclipse中建立 Maven 项目
- 普通的Java项目选择
maven-archetype-quickstart 1.1
- 输入相关的 GAV 就可以快速建立Maven 项目
-
项目 resources 需要自己建立
新建Maven 项目 | center | center
- 普通的Java项目选择
-
小技巧:
-
Maven
骨架快速生成配置- Eclipse 或者 IDEA建立Mavan 项目时,有时候会一直处于run状态,只需要新增一个配置就可以:
Maven -> Runner -> VM Options : -DarchetypeCatalog=internal
- Eclipse 或者 IDEA建立Mavan 项目时,有时候会一直处于run状态,只需要新增一个配置就可以:
-
Maven 中的依赖特性
-
1、当存在多个模块开发时,项目之间就会存在依赖特性
- 示例:
- 存在三个模块: user-core、user-log、user-service
- user-service 依赖于 user-core 和 user-log
- 示例:
-
2、依赖的传递性
- 在模块之间互相依赖之后,可能存在包之间的传递性
- 依赖之间的传递范围是基于
<scrop>compile</scrop>
,对于依赖的传递而言,主要是针对compile
作用域传递,其他的作用域并不会传递
-
3、传递的冲突问题
- 例1-相同路径深度:
-
a-->b(1.0V)
c-->b(1.1V)
d-->a和c
,这个时候在 d模块 的pom中,哪一个依赖先写就使用先写依赖的版本。 - 对于相同路径深度的模块中的包依赖,那个模块写在pom依赖前,就依赖哪个版本
-
- 例2-不同路径深度依赖
-
a-->b(1.0V)
c-->b(1.1V)
d-->a
和c-->b(1.0V)
f-->d和c
,如果路径的长短不一致就选择最小路径f-->b1.1
-
- 精确控制依赖冲突问题:如果希望精确的控制依赖包,可以使用依赖的排除功能进行控制
- 例1-相同路径深度:
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>user-log</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!-- 排重 user-log 模块中的 commoms-logging 依赖 -->
<exclusions>
<exclusion>
<groupId>commoms-logging</groupId>
<artifactId>commoms-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
Maven 依赖范围
- 1、
test
范围指的是测试范围有效,在编译和打包时都不会使用这个依赖 - 2、
compile
范围指的是编译范围有效,在编译和打包时都会将依赖存储进去 - 3、
provided
依赖:在编译和测试的过程有效,最后生成war包时不会加入,诸如: servlet-api,因为servlet-api,tomcat等web服务器已经存在了,如果再打包会冲突 - 4、
runtime
在运行的时候依赖,在编译的时候不依赖 - 5、默认的依赖范围是
compile
, 也只有compile
范围才能进行依赖传递
<!-- 测试范围的依赖 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- 运行的时候依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
<scope>runtime</scope>
</dependency>
Maven的聚合和继承
- 1、Maven 聚合
- 在maven 模块中,如果一个项目每个模块都去单独的操作这样会很不方便,重复操作太多所以我们可以使用聚合的方法来进行 maven 项目的统一操作
- 在之前三个模块的根目录下新建一个空白的 maven 项目,主要用于管理这三个
maven
项目,并且pom.xml
需要按照下面例子来建立。
示例: 聚合和继承的路径
user-maven/pom.xml
user-maven/user-core
user-maven/user-log
user-maven/user-service
<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>org.panpan.hellomaven</groupId>
<artifactId>user-maven</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!-- 类型为pom 管理 -->
<packaging>pom</packaging>
<!-- module 聚合里面存放是项目模块的绝对路径 -->
<modules>
<module>user-dao</module>
<module>user-log</module>
<module>user-service</module>
</modules>
</project>
- 2、
Maven
的继承- 在 Maven 的每个模块项目中,一些包依赖需要重复的去添加,所以我们可以采用在一个顶级的
pom.xml
来统一管理这些模块和包之间的依赖 - 通常我们会把 聚合 和 继承统一在一个
pom.xml
文件中
- 在 Maven 的每个模块项目中,一些包依赖需要重复的去添加,所以我们可以采用在一个顶级的
user-maven 中的 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>org.panpan.hellomaven</groupId>
<artifactId>user-maven</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!-- 类型为pom 管理 -->
<packaging>pom</packaging>
<url>http://maven.apache.org</url>
<!-- module 聚合里面存放是项目模块的绝对路径 -->
<modules>
<module>user-dao</module>
<module>user-log</module>
<module>user-service</module>
</modules>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.version>4.12</junit.version>
<lombok.version>1.16.10</lombok.version>
<log4j.version>1.2.17</log4j.version>
<slf4j.version>1.5.2</slf4j.version>
<dbunit.version>2.4.5</dbunit.version>
<mysql.version>5.1.38</mysql.version>
<hibernate.version>4.3.11.Final</hibernate.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.dbunit</groupId>
<artifactId>dbunit</artifactId>
<version>${dbunit.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
在user-dao 中继承 user-maven 的 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>
<!-- 继承user-maven 的pomx.ml -->
<parent>
<groupId>org.panpan.hellomaven</groupId>
<artifactId>user-maven</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!-- 继承的绝对路径是pom的文件, 如果是在外层可以不添加这个配置 -->
<!-- 或默认继承在该模块的最外层根目录下 -->
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>org.panpan.hellomaven</groupId>
<artifactId>user-dao</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>user-dao</name>
<dependencies>
<!-- 对于继承过来的,可以不用写上版本号继承 user-maven -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
<dependency>
<groupId>org.dbunit</groupId>
<artifactId>dbunit</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
</dependency>
</dependencies>
</project>
Nexus repository
nexus 介绍和安装
- 1、Nexus 介绍
* Nexus 是Maven仓库管理器,如果你使用Maven,你可以从Maven中央仓库 下载所需要的构件(artifact),但这通常不是一个好的做法,你应该在本地架设一个Maven仓库服务器,在代理远程仓库的同时维护本地仓库,以节省带宽和时间,Nexus就可以满足这样的需要。此外,他还提供了强大的仓库管理功能,构件搜索功能,它基于REST,友好的UI是一个extjs的REST客户端,它占用较少的内存,基于简单文件系统而非数据库。这些优点使其日趋成为最流行的Maven仓库管理器。 - 2、Nexus 安装
- 你可以从http://nexus.sonatype.org/downloads/ 下载最新版本的Nexus,Nexus提供了两种安装方式,一种是内嵌Jetty的bundle,只要你有JRE就能直接运行。第二种方式是WAR,你只须简单的将其发布到web容器中即可使用。
- Bundle方式安装
- 解压nexus-webapp-1.3.0-bundle.zip 至任意目录,如D:\dev_tools ,然后打开CMD,cd至目录D:\dev_tools\nexus-webapp-1.3.0\bin\jsw\windows-x86-32 ,运行Nexus.bat 。你会看到Nexus的启动日志,当你看到“Started SelectChannelConnector@0.0.0.0:8081”之后,说明Nexus启动成功了,然后打开浏览器,访问http://127.0.0.1:8081/nexus
- 要停止Nexus,Ctrl+C即可,此外InstallNexus.bat可以用来将Nexus安装成一个windows服务,其余的脚本则对应了启动,停止,暂停,恢复,卸载Nexus服务。
- WAR方式安装
- 你需要有一个能运行的web容器,这里以Tomcat为例,加入Tomcat的安装目录位于D:\DevInstall\apache-tomcat-7.0.9,首先我们将下载的nexus-webapp-xxx.war 重命名为nexus.war ,然后复制到D:\DevInstall\apache-tomcat-7.0.9\webapps\nexus.war ,然后启动CMD,cd到D:\DevInstall\apache-tomcat-7.0.9\bin\ 目录,运行startup.bat 。一切OK,现在可以打开浏览器访问http://127.0.0.1:8080/nexus,你会得到和上图一样的界面。
nexus的配置
- 默认情况下,Maven依赖于中央仓库,这是为了能让Maven开箱即用,但仅仅这么做明显是错误的,这会造成大量的时间及带宽的浪费。既然文章的前面已经介绍了如何安装和配置Nexus,现在我们就要配置Maven来使用本地的Nexus,以节省时间和带宽资源。
- 我们可以将Repository配置到POM中,但一般来说这不是很好的做法,原因很简单,你需要为所有的Maven项目重复该配置。因此,这里我将Repository的配置放到
settings.xml
中:
<profiles>
<profile>
<id>nexusProfile</id>
<repositories>
<repository>
<id>nexus</id>
<name>Nexus Repository</name>
<url>http://127.0.0.1:8080/nexus/content/groups/public/</url>
<!-- 可以下载releases Jar 包 默认是true -->
<releases>
<enabled>true</enabled>
</releases>
<!-- 可以下载snapshots Jar包默认是false -->
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</profile>
</profiles>
<!-- 在这激活哪个profile id,哪个就生效 -->
<activeProfiles>
<activeProfile>nexusProfile</activeProfile>
</activeProfiles>
- 当然,我们还可以配置工厂的镜像,那设置工厂的查找范围。例如只能在本地服务器的工厂中查询
<mirrors>
<!-- 工厂的镜像,只要mirrorOf 中的工厂要访问,都会自动来找镜像,就不会再去重要工厂 -->
<mirror>
<!--This sends everything else to /public -->
<id>nexus</id>
<!-- 也可以配置为 * 来代替-->
<mirrorOf>nexus,central</mirrorOf>
<url>http://192.168.0.221:8081/nexus/content/groups/public</url>
</mirror>
</mirrors>
- 在配置了工厂镜像之后,在之前的
nexusProfile
的配置就没有必要配置了,但是对于想要能够依赖中央工厂中的snapshots
版本的镜像,我们可以采用覆盖maven中的默认配置方式
<profiles>
<profile>
<id>nexus</id>
<!--Enable snapshots for the built in central repo to direct -->
<!--all requests to nexus via the mirror -->
<repositories>
<!-- 表示配置中央工厂中的snapshots为true,查找地址为上面配置mirror 镜像 -->
<repository>
<id>central</id>
<url>http://central</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</repository>
</repositories>
</profile>
</profiles>
<activeProfiles>
<!--make the profile active all the time -->
<activeProfile>nexus</activeProfile>
</activeProfiles>
发布项目到nexus
中
- 更常见的用例是:团队在开发一个项目的各个模块,为了让自己开发的模块能够快速让其他人使用,你会想要将snapshot版本的构件部署到Maven仓库中,其他人只需要在POM添加一个对于你开发模块的依赖,就能随时拿到最新的snapshot。
- 以下的
pom.xml
配置和settings.xml
能让你通过Maven自动化部署构件:
<!-- pom.xml -->
<!-- 只要在parent 模块中配置,后面模块都继承就行 -->
<distributionManagement>
<repository>
<id>nexus-releases</id>
<name>Nexus Release Repository</name>
<url>http://127.0.0.1:8080/nexus/content/repositories/releases/</url>
</repository>
<snapshotRepository>
<id>nexus-snapshots</id>
<name>Nexus Snapshot Repository</name>
<url>http://127.0.0.1:8080/nexus/content/repositories/snapshots/</url>
</snapshotRepository>
</distributionManagement>
<!-- setting.xml -->
<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>
生命周期和插件
maven 的三套生命周期
-
1、
clean
生命周期-
pre-clean
执行一些需要在clean之前完成的工作 -
clean
移除所有上一次构建生成的文件 -
post-clean
执行一些需要在clean之后立刻完成的工作
-
-
2、
compile
生命周期
validate
generate-sources
process-sources
generate-resources
process-resources 复制并处理资源文件,至目标目录,准备打包。
compile 编译项目的源代码。 //到这一步完成 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 将最终的包复制到远程的仓库,以让其它开发人员与项目共享。
-
3、
site
生命周期-
pre-site
执行一些需要在生成站点文档之前完成的工作 -
site
生成项目的站点文档 -
post-site
执行一些需要在生成站点文档之后完成的工作,并且为部署做准备 -
site-deploy
将生成的站点文档部署到特定的服务器上
-
Maven 插件
Maven 插件介绍
- Maven的核心是它的生命周期,生命周期什么都不做,因此Maven的安装文件很小。所有的事情都交给了插件来完成。比如说,Maven 的default生命周期中定义了一个compile阶段,这个定义本身什么都不会做,真正编译代码的是Compiler插件,它的groupId是org.apache.maven.plugins,artifactId是maven-compiler-plugin。
- 插件是 maven 的核心,所有执行的操作都是基于插件来完成的
- 为了让一个插件中可以实现众多的类似功能,maven为插件设定了目标,一个插件中有可能有多个目标
- 其实生命周期中的重要的每个阶段都是由插件的一个具体目标来执行的
Maven 插件基础
-
phase
: 可以在插件上指定声明周期的哪一步后面执行这个插件 -
executions
-execution
: 执行什么操作 -
goals
-goal
: 在绑定phase
之后,需要指定插件执行的目标,可以执行多个 -
configuration
: 配置插件中类的注解参数,这样可以给插件注明一些参数的值
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java_source_version>1.8</java_source_version>
<java_target_version>1.8</java_target_version>
<maven_compiler_plugin_version>3.3</maven_compiler_plugin_version>
<maven_source_plugin_version>2.4</maven_source_plugin_version>
<maven_jar_plugin_version>2.5</maven_jar_plugin_version>
<maven_war_plugin_version>2.5</maven_war_plugin_version>
<maven_deploy_plugin_version>2.8.2</maven_deploy_plugin_version>
<spring.version>4.2.1.RELEASE</spring.version>
</properties>
<build>
<plugins>
......
<!--示例—1: 指定编译的JDK 版本号 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven_compiler_plugin_version}</version>
<configuration>
<source>${java_source_version}</source>
<target>${java_target_version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<!--示例-2:生成的Java源文件的Jar包 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>${maven_source_plugin_version}</version>
<executions>
<execution>
<id>attach-sources</id>
<!-- 指定插件的目标 -->
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
<configuration>
<attach>true</attach>
</configuration>
</plugin>
<!-- 示例-3: 生成Maven War包-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>${maven_war_plugin_version}</version>
<configuration>
<archive>
<addMavenDescriptor>true</addMavenDescriptor>
</archive>
</configuration>
</plugin>
<!-- 示例-4: Build a JAR from the current project. -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>${maven_jar_plugin_version}</version>
<configuration>
<archive>
<addMavenDescriptor>true</addMavenDescriptor>
</archive>
</configuration>
</plugin>
......
</plugins>
</build>