Maven 项目管理构建工具


一、Maven 环境搭建


1. 安装

  1. 下载解压 apache-maven-版本-bin.zip 。

  • 添加环境变量:
  1. MAVEN_HOME:配置 Maven 的安装目录。
  2. PATH:配置 bin 目录(%MAVEN_HOME%\bin)。

  • 创建本地仓库目录:
  1. 在 Maven 解压目录下建立 repository 目录。
  2. 修改 conf/settings.xml 配置本地仓库地址。
<!--本地仓库位置, 默认`${user.home}/.m2/repository`-->
<localRepository>E:\java\maven\repository</localRepository>

  • 配置远程仓库镜像:
  1. 修改 conf/settings.xml 配置远程仓库镜像。
  2. mvnrepository
  3. 阿里云云效 Maven
  4. 阿里云云效 Maven
<mirrors>
    <!-- mirror
     | Specifies a repository mirror site to use instead of a given repository. The repository that
     | this mirror serves has an ID that matches the mirrorOf element of this mirror. IDs are used
     | for inheritance and direct lookup purposes, and must be unique across the set of mirrors.
     |
    <mirror>
      <id>mirrorId</id>
      <mirrorOf>repositoryId</mirrorOf>
      <name>Human Readable Name for this Mirror.</name>
      <url>http://my.repository.com/repo/path</url>
    </mirror>
     -->
	<mirror>
      <id>maven-default-http-blocker</id>
      <mirrorOf>external:http:*</mirrorOf>
      <name>Pseudo repository to mirror external repositories initially using HTTP.</name>
      <url>http://0.0.0.0/</url>
      <blocked>true</blocked>
    </mirror>

	<!-- maven2 -->
	<mirror>
		<id>mvnrepository</id>
		<mirrorOf>*</mirrorOf>
		<name>mvnrepository</name>
		<url>https://repo1.maven.org/maven2/</url>
	</mirror>
	
	<!-- 阿里云镜像 -->
	<mirror>
        <id>central</id>
        <mirrorOf>*</mirrorOf>
        <name>central</name>
        <url>https://maven.aliyun.com/repository/central</url>
    </mirror>
    <mirror>
        <id>public</id>
        <mirrorOf>*</mirrorOf>
        <name>public</name>
        <url>https://maven.aliyun.com/repository/public</url>
    </mirror>
	<mirror>
	    <id>gradle-plugin</id>
	    <mirrorOf>*</mirrorOf>
	    <name>gradle-plugin</name>
	    <url>https://maven.aliyun.com/repository/gradle-plugin</url>
	</mirror>
	<mirror>
	    <id>apache-snapshots</id>
	    <mirrorOf>*</mirrorOf>
	    <name>apache-snapshots</name>
	    <url>https://maven.aliyun.com/repository/apache-snapshots</url>
	</mirror>
	
	
    <mirror>
        <id>google</id>
        <mirrorOf>*</mirrorOf>
        <name>google</name>
        <url>https://maven.aliyun.com/repository/google</url>
    </mirror>
    <mirror>
        <id>spring</id>
        <mirrorOf>*</mirrorOf>
        <name>spring</name>
        <url>https://maven.aliyun.com/repository/spring</url>
    </mirror>
    <mirror>
        <id>spring-plugin</id>
        <mirrorOf>*</mirrorOf>
        <name>spring-plugin</name>
        <url>https://maven.aliyun.com/repository/spring-plugin</url>
    </mirror>
   	<mirror>
        <id>grails-core</id>
        <mirrorOf>*</mirrorOf>
        <name>grails-core</name>
        <url>https://maven.aliyun.com/repository/grails-core</url>
    </mirror>
    
	<mirror>
		<id>e-iceblue</id>
		<mirrorOf>*</mirrorOf>
		<name>e-iceblue</name>
		<url>https://repo.e-iceblue.cn/repository/maven-public/</url>
	</mirror>
</mirrors>

2. 验证

# 查看`Maven`版本
maven -v

二、Maven 项目生命周期


1. clean 清理

  1. pre-clean:准备清理。
  2. clean:真正的清理工作(将 target 目录下的 class 和 jar 文件清理)。
  3. post-clean:执行清理后的一些后续工作。

2. default 构建

  1. validate:验证。
  2. initialize:初始化配置。
  3. generate-sources:生成源代码编译目录。
  4. process-sources:处理项目主资源文件(复制资源文件到 outputclasspath)。
  5. generate-resources:生成资源目录。
  6. process-resources:处理资源文件。
  7. complie:编译源代码(将 java 源程序编译成 class 字节码文件)。
  8. process-classes:处理编译后文件。
  9. generate-test-sources:生成测试目录。
  10. process-test-sources:处理项目测试资源文件(复制测试资源文件到 outputclasspath)。
  11. generate-test-resources:生成测试资源文件。
  12. process-test-resources:处理测试资源文件。
  13. test-compile:编译测试代码。
  14. process-test-classes:处理测试代码。
  15. test:单元测试,自动运行测试代码(执行 src/test/java 下的类)。
  16. prepare-package:打包前的准备。
  17. package:将编译好的代码,打包成为 jar包、war包 或 ear 等。
  18. pre-integration-test:准备整体测试。
  19. integration-test:整体测试。
  20. post-integration-test:为整体测试收尾。
  21. verify:验证。
  22. install:安装到本地 Maven 仓库。
  23. deploy:将最终包部署到远程 Maven 仓库。

3. site 生成项目站点

  1. pre-site:准备生成站点。
  2. site:生成站点及文档。
  3. post-site:站点收尾。
  4. site-deploy:将生成的站点,发布到服务器上。

三、Maven 常用命令

# 查看`Maven`版本
mvn -v		

# 不调试运行			
mvn '命令名称'    
# 调试运行    		
mvnDebug '命令名称'

# 清理
mvn clean
# 编译主程序
mvn compile
# 编译测试程序
mvn test-compile
# 执行测试
mvn test
# 打包
mvn package
# 安装
mvn install

# 打包		
mvn clean package		
# 打包跳过测试
mvn clean package -D maven.test.skip=true	                 	

1. Java 命令

# 命令行运行
java -jar 'xx.jar'           
# 后台运行                 
nohup java -jar 'xx.jar' > /dev/null 2>&1 & 
  
# 查看启动`Java`服务进程
ps -ef | grep java   
# 停止进程                        
kill -9 '进程号'   

四、依赖管理


1. scope 依赖范围

依赖范围编译 ClassPath 有效测试 ClassPath 有效运行 ClassPath 有效例子
compile【默认】YYYspring-core
providedYY-servlet-api
runtime-YYJDBC 驱动
test-Y-Junit

  • compile:【默认值】
  1. jar包 会一直存在所有阶段(编译、测试、运行 都有效)。
  2. A 在 编译、测试、运行 时都依赖 B。
  3. 比如:strus-core、spring-beans 会打到 war包 或 jar包。

  • provided:
  1. 不让 Servlet容器 和 本地仓库的 jar包 冲突(编译、测试有效)。
  2. A 在 编译、测试 时需要依赖 B。
  3. 比如:servlet-api 就是 编译 和 测试 有用,在运行时不用(Tomcat 容器已提供)不会打到 war 包。

  • runtime:
  1. 运行、测试 有效。
  2. 比如:JDBC 驱动 在开发代码中,针对 Java 的 JDBC 接口开发,编译 不用。
  3. 运行、测试 时,需要通过 JDBC驱动包(MySQL 驱动)连接数据库,会打到 war 包。

  • test:
  1. 只在 测试 有效(只会在单元测试类中使用,不会随项目发布)。
  2. 比如:Junit 不会打到 war 包。

  • system: 类似 provided
  1. 需要显式提供包含依赖的 jar包。
  2. Maven 不会在 Repository 中查找它。

2. 依赖传递

直接依赖\传递依赖compileprovidedruntimetest
compilecompile-runtime-
providedprovidedprovidedprovided-
runtimeruntime-runtime-
testtest-test-

  • 纵坐标:直接依赖。
  1. A 依赖 B,B 是 A 的直接依赖。
  2. 在 A 的 pom.xml 中添加 B 的坐标。
  • 横坐标:传递依赖。
  1. B 依赖 C,C 是 A 的传递依赖。
  • 中间部分:传递依赖的范围。
  1. A 依赖 C 的范围。

3. 依赖调节原则

  • 项目 A 依赖于项目 B,项目 B 依赖于项目 C(v1)。
  • 项目 A 依赖于项目 D,项目 D 依赖于项目 E,项目 E 依赖于 C(v2)。
# v1
A -> B -> C
# v2
A -> D -> E -> C

  • 分析:项目 A 隐形依赖了两个版本的 C,那到底采用哪个版本呢?
  1. 依赖调解第一原则:路径优先
  1. 很明显,第一种路径深度是 3。
  2. 第二种路径深度是 4。
  3. 所以,Maven 会采用 C(v1)。
  1. 依赖调解第二原则:声明优先
    假设路径深度相等,那么声明在前的会被引用。

4. 版本锁定 dependencyManagement

  • 在 Maven 中 dependencyManagement 的作用,其实相当于一个对所依赖 jar 包进行版本管理的管理器。

4.1 pom.xml 文件中,jar 的版本判断的两种途径
  • 如果 dependencies 里的 dependency,自己没有声明 version 元素。
  1. 那么 Maven 就会到 dependencyManagement 里面去找,有没有对该 groupId.artifactId 进行过版本声明。
  2. 如果有就继承它,如果没有就会报错,告诉你必须为 dependency 声明一个 version。
  • 如果 dependencies 中的 dependency,声明了 version 元素。
    那么无论 dependencyManagement 中有无对该 jar 的 version 声明,都以 dependency 里的 version 为准。
<!-- 版本管理 -->
<dependencyManagement>
  <dependencies>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>5.0.7.Final</version>
    </dependency>
  </dependencies>
</dependencyManagement>

5. exclusions 排除依赖

  • 观察 Maven Dependencies 下的 jar 包,会发现存在了两个 javassist 包。
  1. 一个是 javassist-3.18.1-GA
  2. 另一个是 javassist-3.11.0-GA
  • 这是因为引入三大框架的 jar 包。
  1. hibernate 依赖 javassist-3.18.1-GA,而 struts 依赖 javassist-3.11.0-GA,这就是 jar包版本冲突
  2. 如果这两个 jar 包同时存在,会导致后续某些操作存在问题(比如:openSessionInView 失效)。
  3. 所以需要 排除低版本的 jar 包
<dependency>
    <groupId>org.apache.struts</groupId>
  	<artifactId>struts2-core</artifactId>
  	<version>2.3.24</version>
  	
  	<!-- 排除 struts 中依赖低版本的 javassist 的jar包 -->
  	<exclusions>
  		<exclusion>
  			<groupId>javassist</groupId>
  			<artifactId>javassist</artifactId>
  		</exclusion>
  	</exclusions>
</dependency>

6. junit 单元测试

<dependency>
  	<groupId>junit</groupId>
  	<artifactId>junit</artifactId>
  	<version>4.9</version>
    <scope>test</scope>
</dependency>
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:applicationContext_dao.xml","classpath:applicationContext_datasource.xml"})
@Test
ApplicationContext appContext = new ClassPathXmlApplicationContext("classpath:META-INF/spring/applicationContext-common.xml");
ProjectServiceFacade projectServiceFacade = (ProjectServiceFacade) appContext.getBean("projectServiceFacade");

五、Maven 聚合

  • 顾名思义,就是把多个 模块 或 项目 聚合到一起,建立一个专门负责聚合工作的 Maven 工程。
  1. 聚合模块本身也做为一个 Maven 项目,它必须有自己的 pom.xml
  2. 它的打包方式必须为 pom
  3. 引入了新的元素 <modules><module> xxx </module></modules>
  4. 版本:聚合模块的版本,和被聚合模块版本一致。
  5. 相对目录:每个 module 的值都是一个当前 pom 的相对目录。
  6. 目录名称:
  1. 为了方便的快速定位内容,模块所处的目录应当与其 artifactId 一致(Maven 约定而不是硬性要求)。
  2. 总之,模块所处的目录必须和 <module> 模块,所处的目录 </module> 相一致。
  1. 习惯约定:
  1. 为了方便构建,通常将聚合模块放在项目目录层的最顶层,其它模块作为子目录存在。
  2. 这样打开项目的时候,第一个看到的就是聚合模块的 pom
  1. 聚合模块减少的内容:
  1. 聚合模块的内容仅仅是一个 pom.xml 文件,它不包含 src/main/Javasrc/test/java 等目录。
  2. 因为它只是用来帮助其它模块构建的工具,本身并没有实质的内容。
  1. 聚合模块和子模块的目录:
  1. 可以是 父子类,也可以是 平行结构
  2. 当然如果使用平行结构,那么聚合模块的 pom 也需要做出相应的更改。

六、Maven 继承

  • 在项目开发的过程中,可能多个模块独立开发,但是多个模块可能依赖相同的元素。
  • 比如:每个模块都需要 Junit
  1. 使用 Spring 的时候,其核心 jar 也必须都被引入,在编译的时候,maven-compiler-plugin 插件也要被引入。
  2. 这时我们采用继承,就不用在每个子模块分别定义了。

  • 如何配置继承。
  1. 继承肯定是一个父子结构,那么在父工程中来创建一个 parent project
  2. <packaging>:作为父模块的 pom,其打包类型也必须为 pom
  3. 结构:父模块只是为了帮助我们消除重复,所以它也不需要 src/main/javasrc/test/java 等目录。
  4. 新的元素:<parent> , 它是被用在子模块中的。
  5. <parent> 元素的属性:
  1. <relativePath>:表示父模块 pom 的相对路径。
  2. 在构建的时候,Maven 会先根据 relativePath 检查父 pom,如果找不到,再从本地仓库查找。
  1. relativePath 的默认值: ../pom.xml
  2. 子模块省略 groupId 和 version:
  1. 使用了继承的子模块中,可以不声明 groupId 和 version。
  2. 子模块将隐式的继承父模块的这两个元素。

七、聚合 与 继承区别

  • 聚合 和 继承通常是结合使用的,但是其作用是不同的。
  1. 聚合 是将多个模块的工程,汇聚到一起。
  2. 而 继承 则是指明某个模块工程要 继承 另一个模块功能。
    在这里插入图片描述

八、nexus 私服


1. nexus 安装

  1. nexus-2.12.0-01-bundle.zip 解压。
  2. dos 进入 bin 目录,nexus.bat 目录,敲入命令。
  3. 访问:http://localhost:8081/nexusadmin/admin123
# 安装
nexus install   	
# 卸载
nexus uninstall		

2. 构建索引

  • 安装好的 nexus 是无法直接搜索到 jar 包的,必须下载索引才可以正常使用。
  • 我们到 中央仓库 下载以下两个索引压缩文件(这两个文件一般在此页面的最后的位置)。
  • 还需要在网上下载一个名为 indexer-cli-5.1.1.jar 的 jar 包。
nexus-maven-repository-index.gz

nexus-maven-repository-index.properties 
  • 将三个文件放入一个文件夹,cmd 执行下面命令。
  • 执行后生成 indexer 目录下的文件是索引文件。
java -jar indexer-cli-5.1.1.jar -u nexus-maven-repository-index.gz -d indexer
  • nexus-2.12.0-01-bundle\sonatype-work\nexus\indexer\central-ctx 目录下的文件删除。
    将上边的索引文件拷贝到此目录下。
  • 拷贝后重新启动 nexus,然后进入 nexus 搜索 jar 包发现可以进行搜索了。

3. 仓库类型

  1. hosted:宿主仓库,自己项目的 jar 要放到 hosted 类型的仓库中。
  2. proxy:代理仓库,代理中央仓库。
  3. virtual:虚拟仓库,存储了 Maven1 的构件,一般不用。
  4. group:仓库组,将一些仓库组成一个组,自己项目连接仓库组去下载 jar 包。
    平常开发中都去连接仓库组(仓库组中包括:hosted、proxy 等)。

4. 镜像配置

  • nexus 安装好,要开始使用它了。现在需要在 Maven 的配置文件 settings.xml 中配置镜像。
  • 让 Maven 找私服,而不是直接到中央仓库下载。
  • 打开 Maven 的配置文件 settings.xml,添加如下配置。
<mirrors>    
	<mirror>
      <id>nexus</id>
      <!-- `*`代表私服里所有仓库 -->
      <mirrorOf>*</mirrorOf>
      <!-- 私服地址,所以仓库配置仓库组地址 -->
      <url>http://localhost:8081/nexus/content/groups/public/</url>
    </mirror>
</mirrors>
<!-- `mirrors`为镜像组,可以配置多个`mirror`(镜像),这里配置的是`nexus`中的中央代理仓库 -->

5. 发布自己的工程 jarnexus


5.1 pom.xml 中添加配置信息
<distributionManagement>
  <repository>
  	<!-- 私服仓库`Id`和私服`Url` -->
    <id>releases</id>
    <url>http://localhost:8081/nexus/content/repositories/releases/</url>
  </repository> 
  <snapshotRepository>
  	<id>snapshots</id>	
    <url>http://localhost:8081/nexus/content/repositories/snapshots/</url>
  </snapshotRepository> 
</distributionManagement>

5.2 Mavensettings.xml 中配置信息
<servers>	
  <server>
    <id>releases</id><!-- 和pom.xml<id>对应 -->
    <username>admin</username>
    <password>admin123</password>
  </server>	
  <server>
    <id>snapshots</id>
    <username>admin</username>
    <password>admin123</password>
  </server>
</servers>

5.3 执行命令:deploy

6. 发布第三方的工程 jarnexus

  • 有很多 jar 包由于版权等问题,并不会出现在中央仓库中。
  • 比如:Oracle 的驱动,那如何将这类 jar 包放在 nexus 中呢?
  • 我们看下列操作步骤:
  1. 选择左侧菜单的 Repositories,在 Repositories 窗口中选择 3rd party。
  2. 在 3rd party 窗口中选择 Artifact Upload。
  3. 在 Artifact Upload 选项卡中填写坐标,并上传 jar 包。

九、其他


1. 引入本地jar包—打jar包

<dependency>
    <groupId>com.microsoft.sqlserver</groupId>
    <artifactId>sqljdbc4</artifactId>
    <scope>system</scope>
    <version>1.0</version>
    <systemPath>${project.basedir}/src/main/resources/lib/sqljdbc4-4.2-6.jar</systemPath>
</dependency>

<build>
	<plugins>
	
		<plugin>
	 		<groupId>org.springframework.boot</groupId>
	       	<artifactId>spring-boot-maven-plugin</artifactId>
	        <configuration>
	        	<!-- `true`:把`本地`的`system作用域`的`jar包`也打包进来。-->
				<includeSystemScope>true</includeSystemScope>-->
	        </configuration>
	    </plugin>
 	
 	</plugins>

	<!-- 选配。-->
   	<!-- 正常启动需注释以下代码,否则会包Shiro错误,打包部署放开以下注释。-->
	<resources>
		<resource>
       		<directory>${project.basedir}/../lib</directory>
	  		<targetPath>/BOOT-INF/lib/</targetPath>
	       	<includes>
	            <include>**/*.jar</include>
	        </includes>
	    </resource>
	    <resource>
	        <directory>src/main/resources</directory>
	        <targetPath>BOOT-INF/classes/</targetPath>
	    </resource>
	</resources>
</build>

2. 引入本地jar包—打war包

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>system</scope>
    <version>8.0.19-SNAPSHOT</version>
    <systemPath>${project.basedir}/src/main/resources/lib/mysql-connector-java-8.0.19-SNAPSHOT.jar</systemPath>
</dependency>

<build>
	<plugins>
	
		<plugin>
    		<groupId>org.apache.maven.plugins</groupId>
         	<artifactId>maven-war-plugin</artifactId>
          	<configuration>
           		<failOnMissingWebXml>false</failOnMissingWebXml>
               	<webResources>
               		<resource>
               			<!-- 本地jar包路径。-->
                   		<directory>src/main/resources/lib</directory>
                   		<!-- 打包到指定目录。-->
                      	<targetPath>WEB-INF/lib</targetPath>
                      	<filtering>false</filtering>
                  	</resource>
           		</webResources>
     		</configuration>
    	</plugin>
	
	</plugins>
</build>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

骑士梦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值