Maven项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的项目管理工具软件。 Maven 除了以程序构建能力为特色之外,还提供高级项目管理工具。由于 Maven 的缺省构建规则有较高的 可重用性,所以常常用两三行 Maven 构建脚本就可以构建简单的项目。由于 Maven 的面向项目的方法, 许多 Apache Jakarta 项目发文时使用 Maven,而且公司项目采用 Maven 的比例在持续增长。Maven这个 单词来自于意第绪语(犹太语),意为知识的积累,最初在Jakata Turbine项目中用来简化构建过程。当时 有一些项目(有各自Ant build文件),仅有细微的差别,而JAR文件都由CVS来维护。于是希望有一种标准 化的方式构建项目,一个清晰的方式定义项目的组成,一个容易的方式发布项目的信息,以及一种简单的方式 在多个项目中共享JARs。 Maven是一个项目管理工具,它包含了一个项目对象模型 (Project Object Model),一组标准集合,一个 项目生命周期(Project Lifecycle),一个依赖管理系统(Dependency Management System),和用来运行 定义在生命周期阶段(phase)中插件(plugin)目标(goal)的逻辑。当你使用Maven的时候,你用一个明确定 义的项目对象模型来描述你的项目,然后Maven可以应用横切的逻辑,这些逻辑来自一组共享的(或者自定义 的)插件。 Maven 有一个生命周期,当你运行 mvn install 的时候被调用。这条命令告诉 Maven 执行一系列的有 序的步骤,直到到达你指定的生命周期。遍历生命周期旅途中的一个影响就是,Maven 运行了许多默认的 插件目标,这些目标完成了像编译和创建一个 JAR 文件这样的工作。此外,Maven能够很方便的帮你管理 项目报告,生成站点,管理JAR文件,等等。
maven官网:https://maven.apache.org/ maven下载地址:https://maven.apache.org/download.cgi
如图:
选择其中一个下载 下载完成之后解压 可以看到如下目录: bin: 该目录包含maven脚本。包含了mvn运行的脚本,在此目录下输入任意一条命令就是调用这些脚本 boot: 该目录只有一个plexus-classworlds-2.5.2.jar,该jar是maven的类加载框架用来加载自己的类 库,相对于默认的java类加载器,提供了更丰富的语法及配置 config: 该目录包含maven配置文件,可以全局定制maven行为。通常,settings.xml复制到~/.m2/目录下, 在用户范围内定制maven行为。编译工具会优先去~/.m2目录下读取settings.xml文件,如果没有 读取到才会去maven的安装目录下读取settings.xml文件。 lib: 该目录包含了maven运行时需要的java类库。其中注意的一点是:可以在lib包下找到maven内置的超 级POM,一般存放在名叫maven-model-builder的jar包里面
如果想在cmd上直接运行,需要设置环境变量中的path。这里就不一一说明了。
修改maven目录下的config的setting.xml把<localRepository>打开,标签里面设置本地仓库的地址, 那么之后所有项目的jar包都装放在这个目录下 如: <localRepository>D:/Inkstone/maven/repository</localRepository>
先创建 一个根目录,如果d:/example 在d:/example目录下运行mvn archetype:generate 然后会在这个目录下生成一个项目的骨架
如图 :
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.sutpc.ioc</groupId> <artifactId>ioc_diciflow</artifactId> <version>SNAPSHOT-0.0.1</version> <dependencies> <dependency> <groupId>com.sutpc</groupId> <artifactId>framework-core</artifactId> <version>2.1.1</version> </dependency> <dependencies> </project> 项目的坐标 groupId: 表示项目的名称 artifactId:表示项目的模块名称,建议使用项目的名称-模块名称来表示 version:表示这个项目的版本名称 dependencies:项目的依赖
源代码应该放置到src/main/java中 源代码的资源文件应该放置在src/main/resources文件夹中 测试代码应该放置到src/test/java中 测试代码的资源文件应该放置在src/test/resources文件夹中
mvn clean -->表示运行清理操作(会默认把target文件夹中的数据清理) mvn clean compile-->表示先运行清理之后运行编译,会见代码编译到target文件夹中 mvn clean test-->运行清理和测试 mvn clean package-->运行清理和打包 mvn clean install-->运行清理和安装,会将打好的包安装到本地仓库中,以便其他的项目可以调用 mvn clean deploy-->运行清理和发布(发布到私服上面)
mvn help:describe : 参数: 1. -Dplugin=pluginName 2. -Dgoal(或-Dmojo)=goalName:与-Dplugin一起使用,它会列出某个插件的goal信息 这个命令会告诉你某个插入有哪些goal及其相关的参数如果觉得不够详细,同样可以加 -Ddetail. 注:一个插件goal也被认为是一个 “Mojo”) mvn archetype:generate: 创建maven项目,之前是使用mvn archetype:create -DarchetypeArtifactId= maven-archetype-quickstart -DgroupId=com.ryanote -Dartifact=common, 命令太冗长了,现在只需输入archetype:generate,剩下的就是做”选择题”了 mvn tomcat:run:在对应目录下运行mvn tomat:run命令,就可以在浏览器里运行查看了 参数: 1. -Dmaven.test.skip(=true) 跳过测试 2. -Dmaven.tomcat.port=9090 指定端口 3. -Dmaven.test.failure.ignore=true 忽略测试失败 如何使用这个命令: 先在pom文件添加依赖: <!-- tomcat7插件 maven 命令 tomcat7:run 启动项目--> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> <configuration> <port>8080</port> <path>/${project.artifactId}</path> <uriEncoding>${project.build.sourceEncoding}</uriEncoding> </configuration> </plugin> 告诉pom项目的resourse目录 <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> <include>**/*.sql</include> <include>**/*.ftl</include> </includes> <filtering>false</filtering> </resource> <resource> <directory>src/main/resources</directory> </resource> </resources> 然后直接运行mvn tomcat:run,记得把 packaging改成war mvnDebug tomcat:run:主要用来远程测试,它会监听远程测试用的8000端口,在eclipse里打开远程测试后,它 就会跑起来了,设断点,调试,一切都是这么简单.上面提到的那几个参数在这里同样适用. 参数: 1. -Dmaven.test.skip(=true) 跳过测试 2. -Dmaven.tomcat.port=9090 指定端口 3. -Dmaven.test.failure.ignore=true 忽略测试失败 mvn dependency:sources:运行一下,你项目里所依赖的jar包的源码就都有了 mvn archetype:create -DgroupId=packageName -DartifactId=projectName:创建mavne项目 mvn compile: 编译源代码 mvn test-compile: 编译测试代码 mvn test: 运行测试 mvn site:生成项目相关信息的网站 mvn package: 生成target目录,编译、测试代码,生成测试报告,生成jar/war文件 mvn install:在本地Repository中安装jar mvn clean:清除产生的项目 mvn eclipse:eclipse:生成eclipse项目 mvn idea:idea:生成idea项目 mvn -Dtest package:组合使用goal命令,如只打包不测试 mvn test-compile: 编译测试的内容 mvn jar:jar:只打jar包 mvn test -skipping compile -skipping test-compile:只测试而不编译,也不测试编译 mvn eclipse:clean:清除eclipse的一些系统设置 mvn -Dwtpversion=1.0 eclipse:eclipse 生成Wtp插件的Web项目 mvn -Dwtpversion=1.0 eclipse:clean 清除Eclipse项目的配置信息(Web项目) mvn eclipse:eclipse: 将项目转化为Eclipse项目 mvn -e: 显示详细错误 信息. mvn validate: 验证工程是否正确,所有需要的资源是否可用。 mvn test-compile: 编译项目测试代码。 。 mvn integration-test: 在集成测试可以运行的环境中处理和发布包。 mvn verify: 运行任何检查,验证包是否有效且达到质量标准。 mvn generate-sources: 产生应用需要的任何额外的源代码,如xdoclet。 同时发布第三方jar到本地库和远程库: mvn deploy:deploy-file -DgroupId=com -DartifactId=client -Dversion=0.1.0 -Dpackaging=jar -Dfile=d:/client-0.1.0.jar -DrepositoryId=maven-repository-inner -Durl=ftp://xxxxxxx/opt/maven/repository/ 发布第三方Jar到本地库中: mvn install:install-file -DgroupId=com -DartifactId=client -Dversion=0.1.0 -Dpackaging=jar -Dfile=d:/client-0.1.0.jar
mvn clean package依次执行了clean、resources、compile、testResources、testCompile、test、jar(打包)等7个阶段。 mvn clean install依次执行了clean、resources、compile、testResources、testCompile、test、jar(打包)、install等8个阶段。 mvn clean deploy依次执行了clean、resources、compile、testResources、testCompile、test、jar(打包)、install、deploy等9个阶段。 也就是说: package: 命令完成了项目编译、单元测试、打包功能,但没有把打好的可执行jar包(war包或其它形式 的包)布署到本地maven仓库和远程maven私服仓库 install: 命令完成了项目编译、单元测试、打包功能,同时把打好的可执行jar包(war包或其它形式的 包)布署到本地maven仓库,但没有布署到远程maven私服仓库 deploy: 命令完成了项目编译、单元测试、打包功能,同时把打好的可执行jar包(war包或其它形式的 包)布署到本地maven仓库和远程maven私服仓库
1. 所有的依赖都是通过坐标来进行存储的(GAV-->groupId、artifactId、version) 2. 有一些网上的仓库提供了坐标的查询(http://mvnrepository.com) 3. 通过<dependencies>设置依赖 maven是如何搜索依赖的? maven首先会在本地仓库查询, 如果本地仓库没有,就去中央仓库查询
依赖的范围指的就是<scope>标签的可选配置:compile、test、provided、runtime、system、import
1. compile: 默认值,无须显示指定。对于编译、测试、运行三种classpath都有效,如spring-core无论是在编译,测试, 还是运行都会被用到,因此spring-core必须是编译范围 2. test: 只对测试classpath有效,在编译主代码和项目运行时,都将无法使用该依赖,最典型的例子就是 Junit, 构件 在测试时才需要,所以它的依赖范围是测试,因此它的依赖范围需要显示指定为<scope>test</scope> ,当然 不显示指定依赖范围也不会报错,但是该依赖会被加入到编译和运行的 classpath中。对于资源来说是一种浪费。 3. provided: 只对编译和测试的classpath有效,对运行的classpath无效,典型的就是servlet-api, 编译和测试该 项目的时候需要该依赖,但是在运行时,web容器已经提供的该依赖,所以运行时就不再需要此依赖,如果 不显示指定该依赖范围,并且容器依赖的版本和maven依赖的版本不一致的话,可能会引起版本冲突 4. runtime: 只对测试和运行的classpath有效,对编译的classpath无效,典型例子就是JDBC的驱动实现,项目主代码 编译的时候只需要JDK提供的JDBC接口,只有在测试和运行的时候才需要实现上述接口的具体JDBC驱动 5. system: 与classpath的关系与 provided依赖范围完全一致,但是系统依赖范围必须通过配置systemPath元素来显 示指定依赖文件的路径,此类依赖不是由maven仓库解析的,而且往往与本机系统绑定,可能造成构件的不可 移植,因此谨慎使用,systemPath元素可以引用环境变量: <dependency> <groupId>javax.sql</groupId> <artifactId>jdbc-stext</artifactId> <version>2.0</version> <scope>system</scope> <systemPath>${java.home}/lib/rt.jar</systemPath> </dependency> 6. import: 不会对三种classpath产生影响,该依赖范围只能与dependencyManagement元素配合使用,其功能为将目标 pom文件中dependencyManagement的配置导入合并到当前pom的dependencyManagement中 如:有一个父项目为a,现在有一个项目c要使用a项目,可以这样 <dependencyManagement> <dependencies> <!-- 此处继承了a 和 b 两个项目,type为pom,scope 为 import --> <dependency> <groupId>com.cbm.stu</groupId> <artifactId>maven-parent-a</artifactId> <version>1.0.0</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>com.cbm.stu</groupId> <artifactId>maven-parent-b</artifactId> <version>1.0.0</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <!-- 从继承的父项目中继承依赖 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> </dependencies>
现在有maven项目A,项目B依赖A,项目C依赖B.这时如果执行项目C时,会自动把A、B依赖都下载到c项目的jar包文件夹。 这就依赖的传递性 如果现在不想执行C把A下载过来,使用<exclusions>标签 <dependencies> <dependency> <groupId>B</groupId> <artifactId>B</artifactId> <version>0.0.1</version> <exclusions> <exclusion> <!--被排除的依赖包坐标--> <groupId>A</groupId> <artifactId>A</artifactId> <version>0.0.1</version> </exclusion> </exclusions> </dependency> </dependencies>
依赖冲突:有一个项目A,通过不同依赖传递路径依赖于D,如果在不同路径下传递过来的D版本不同,那么应该导入哪个版本下 的包? 1. 如果依赖的路径长度不现,则“短路优先”: A -> B -> C -> D(version 0.0.1) A -> F -> D(version 0.0.2) 则A依赖于D(version 0.0.2) 2. 依赖如果长度相同,则“先声明优先” A -> B -> D(version 0.0.1) A -> F -> D(version 0.0.2) 在项目A中的<dependencies>中,b,f 哪个先则A依赖那个路径的D
如上图所示:
通过module聚合项目. 注意:如果聚合的项目和其它的项目在同级模块中,需要使用../xx文件夹名来设置 对于依赖的继承而言,都需要通过</dependencyManagement>来完成管理,如果不管理子类会全部继承,这种可能会导致一些 模块存在不需要的依赖
< 主版本 >.< 次版本 >.< 增量版本 >-< 里程碑版本 > 主版本:表示框架的变动,如Maven2 和 Maven1 相去甚远; Struts1 和 Struts2 采用了不同的架构。 次版本:表示较大范围的功能增加和变化,及 Bug 修复。例如 Nexus 1.5 较 1.4 添加了 LDAP 的支持,并且修复了 很多 Bug, 但是从总体架构来说,没有什么变化。 小版本号:在分支版本上面进行bug的修复 里程碑:SNAPSHOT-->alpha-->beta-->release-->GA
maven项目使用的仓库一共有如下几种方式:
1. 中央仓库,这是默认的仓库 2. 镜像仓库,通过 sttings.xml 中的 settings.mirrors.mirror 配置 3. 全局profile仓库,通过 settings.xml 中的 settings.repositories.repository 配置 4. 项目仓库,通过 pom.xml 中的 project.repositories.repository 配置 5. 项目profile仓库,通过 pom.xml 中的 project.profiles.profile.repositories.repository 配置 6. 本地仓库
通过设置maven目录下config中的setting.config <localRepository>D:/Inkstone/maven/repository</localRepository>
maven目录下config中的setting.config,内容如下:
<settings> <mirrors> <mirror> <id>settings_mirror</id> <url>https://maven.aliyun.com/repository/public</url> <mirrorOf>central</mirrorOf> </mirror> </mirrors> </settings>
maven目录下config中的setting.config中的setting的节点内增加
<profiles> <profile> <id>s_profile</id> <repositories> <repository> <id>settings_profile_repo</id> <name>netease</name> <url>http://mirrors.163.com/maven/repository/maven-public/</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </repository> /repositories> </profile> </profiles>
在project中增加如下配置:
<repositories> <repository> <id>pom_repositories</id> <name>local</name> <url>http://localhost:8081/nexus/content/groups/public/</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </repository> </repositories>
<profiles> <profile> <id>p_profile</id> <repositories> <repository> <id>pom_profile_repo</id> <name>local</name> <url>http://10.18.29.128/nexus/content/groups/public/</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </repository> </repositories> </profile> </profiles>
即:local_repo > settings_profile_repo > pom_profile_repo > pom_repositories > settings_mirror > central
项目中依赖的搜索顺序: https://my.oschina.net/polly/...
关于这个安装,我在官网找到了安装包,但不知道为什么就是下载不了,无论是最新的还是老版本的。 解决方案:百度 百度结果:找到一个百度云的链接,不过版本有点老。 nexus-2.12.0-01-bundle 链接:https://pan.baidu.com/s/1yVUJG4Yb9F0mY5GcSQj5YA 密码:8j5n 如果失效,加入我们qq群:709571289 下载完成后解压 nexus-2.12.0-01-bundle/nexus-2.12.0-01/bin/jsw到了这个目录就看你是什么系统了,点击相应的系统启动脚本 就ok了。
### 3.6.2 仓库
如上图所示:
host仓库:表示内部项目的发布仓库
proxy的仓库,从远程中央仓库中寻找数据的仓库
1. 配置镜像 <mirrors> <mirror> <id>central</id> <mirrorOf>*</mirrorOf> <name>Human Readable Name for this Mirror.</name> <url>http://localhost:8081/nexus/content/groups/public/</url> </mirror> </mirrors> *: 表示所有仓库的信息都从这里获取,还可以使用nexus.central,这个表示id为nexus和central的仓库才走镜像 2. 配置仓库 <profiles> <profile> <id>central-repos</id> <repositories> <repository> <id>central</id> <name>Central</name> <url>http://central</url> <releases><enable>true</enable></releases> <snapshots> <enabled>true</enabled> </snapshots> </repository> </repositories> </profile> url: 配置了这个镜像之后,这个url就没有意义了 release:打开对release的依赖。默认打开 snapshots: 打开快照的依赖,默认没有打开
1.设定release工厂和snapshots工厂 <distributionManagement> <snapshotRepository> <id>example-snapshots</id> <name>example Project SNAPSHOTS</name> <url>http://192.168.0.199:8081/nexus/content/repositories/MyUserReposSnapshots/</url> </snapshotRepository> <repository> <id>example-releases</id> <name>example Project Release</name> <url>http://192.168.0.199:8081/nexus/content/repositories/MyUserReposRelease/</url> </repository> </distributionManagement> 2.设置访问的权限 <servers> <server> <id>example-snapshots</id> <username>kh</username> <password>123456</password> </server> <server> <id>example-releases</id> <username>kh</username> <password>123456</password> </server>
1、创建两个工厂:release和policy的
2、配置权限
3、创建角色并且分配权限
4、创建用户
5、创建发布的工厂
1. clean pre-clean 执行一些需要在clean之前完成的工作 clean 移除所有上一次构建生成的文件 post-clean 执行一些需要在clean之后立刻完成的工作 2. compile validate 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 将最终的包复制到远程的仓库,以让其它开发人员与项目共享。 3. site pre-site 执行一些需要在生成站点文档之前完成的工作 site 生成项目的站点文档 post-site 执行一些需要在生成站点文档之后完成的工作,并且为部署做准备 site-deploy 将生成的站点文档部署到特定的服务器上
插件是maven的核心,所有执行的操作都是基于插件来完成的,为了让一个插件中可以实现众多的类似功能,maven为插件设定 了目标,一个插件中有可能有多个目标,其实生命周期中的重要的每个阶段都是由插件的一个具体目标来执行的。 插件是有周期的,maven规定了插件的步骤。做完了某个动作之后,下一个动作是什么,每一个动作是由相应的插件来执行的。 apache插件存放在maven本地仓库中的org/apache/maven目录下。
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <mainClass>${start-class}</mainClass> </configuration> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
如上所示:如何快速上手插件?
方法二: 查看api文档,比如apache的插件:
http://maven.apache.org/plugins/ 文档中说的很详细,插件的参数,参数的用例等等,对于文档不是很详细的可以看源码
老版本
新版本
在上面两个类中,maven一执行compile就会执行execute()方法。
每一个目标都是一个类:如下图可知这个插件有两个目标,分别为compile和testCompile,在新版本中,参数都用@Parameter 注解来说明了,老版本用的是注释
<plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <version>2.1.2</version> <executions> <execution> <phase>package</phase> <goals> <goal>jar-no-fork</goal> </goals> </execution> </executions> </plugin> </plugins> phase: 绑定的阶段 goal: 要运行的目标 具体的参数可以查看文档或者是源码