java框架复习——maven

概述

如今我们构建一个项目需要用到很多第三方的类库,如写一个使用Spring的Web项目就需要引入大量的jar包。

一个项目Jar包的数量之多往往让我们瞠目结舌,并且Jar包之间的关系错综复杂,一个Jar包往往又会引用其他Jar包,缺少任何一个Jar包都会导致项目编译失败。

以往开发项目时,程序员往往需要花较多的精力在引用Jar包搭建项目环境上,而这一项工作尤为艰难,少一个Jar包、多一个Jar包往往会报一些让人摸不着头脑的异常。

而Maven就是一款帮助程序员构建项目的工具,我们只需要告诉Maven需要哪些Jar 包,它会帮助我们下载所有的Jar,极大提升开发效率。
在这里插入图片描述
在这里插入图片描述

maven目录结构

作为maven项目必须要实现的目录结构
在这里插入图片描述

maven的安装和配置

eclipse4.3安装maven
Idea与maven整合

maven命令

maven命令大全

maven的常用命令

  1. 创建Maven的普通java项目:
    mvn archetype:create -DgroupId=packageName -DartifactId=projectName
  2. 创建Maven的Web项目:
    mvn archetype:create -DgroupId=packageName -DartifactId=webappName-DarchetypeArtifactId=maven-archetype-webapp
  3. 编译源代码: mvn compile
  4. 编译测试代码:mvn test-compile
  5. 运行测试:mvn test
  6. 产生site:mvn site
  7. 打包:mvn package
  8. 在本地Repository中安装jar:mvn install
  9. 清除产生的项目:mvn clean
  10. 生成eclipse项目:mvn eclipse:eclipse
  11. 生成idea项目:mvn idea:idea
  12. 组合使用goal命令,如只打包不测试:mvn -Dtest package
  13. 编译测试的内容:mvn test-compile
  14. 只打jar包: mvn jar:jar
  15. 只测试而不编译,也不测试编译:mvn test -skipping compile -skipping test-compile
    ( -skipping 的灵活运用,当然也可以用于其他组合命令)
  16. 清除eclipse的一些系统设置:mvn eclipse:clean

maven的坐标

无论自己建立的maven项目还是第三方的maven依赖包都有坐标,想要查找一个依赖包就根据坐标来找。

  • groupId: 组织名称+"."+项目名称
  • artifactId:项目的模块名
  • version:项目版本号

示例如下

<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>

maven的依赖

依赖管理简述

在pom.xml中配置

<dependencies>
       <dependency>
	//要依赖的包的坐标
      </dependency>
</dependencies>

对第三方依赖包的查找去http://mvnrepository.com/来查找第三方包的坐标即可
依赖管理还可以对自己的项目做依赖

  1. 不需要把被依赖的工程安装到仓库
  2. 被依赖工程的classpath下的代码就相当于在依赖工程classpath下

依赖范围

在pom.xml文件中,有个元素是scope,用来表示依赖的范围。之所以会有依赖范围,是因为Maven在编译、测试和运行项目时会各自使用一套classpath,依赖范围就是用来控制这三种classpath的。

  • Java主目录的classpath
  • test测试目录的classpath
  • 运行时的classpath

简单来说,就是通过scope元素来控制项目的依赖是在编译时导入,还是在测试或运行项目时才导入。

使用<scope></scope>来配置依赖的范围,常用的依赖范围:compile,test,provided,runtime

  • <scope>compile</scope>三套classpath需要这个包
  • <scope>test</scope>只对test的classpath有效
  • <scope>provided</scope>只对test和Java主目录的classpath有效
  • <scope>runtime</scope>只对运行时的classpath有效

依赖传递

有时候我们在pom.xml文件中引入的依赖,其本身就需要依赖于其他的依赖,这时候我们不需要去考虑这些依赖,Maven会解析各个直接依赖的pom,将那些必要的间接依赖,以传递性依赖的形式引入到当前的项目中。

通过传递性依赖,我们可以在pom.xml文件中少写不少的依赖配置。

例如:

A<---B第一直接依赖
B<---C第二直接依赖
A<---C间接依赖

这样A和C之间就有了间接依赖,这就叫依赖的传递性,但是这种依赖传递也不是什么情况下都会无保留地传递,也会根据依赖范围改变而改变。

表格的第一列是B在A中的依赖范围,第一行是C在B中的依赖范围,交叉的格子是C在A中的依赖范围。
在这里插入图片描述
总的来说

  • 当C在B中的scope为test时,A不依赖C,C直接被丢弃
  • 当C在B中的scope为provided时,只有当B在A中的scope也是provided时,A才- 会依赖C,这时候C在A的scope是provided
  • 当C在B中的scope为compile或runtime时,A依赖C,此时C在A中的scope继承自B在A的scope。注意,如果C的scope是runtime,B的scope是compile,此时C在A的scope是runtime,而不是compile

需要注意的是A对log4j1.2.9版本依赖,B对log4j1.2.8版本依赖,那么C就会依赖log4j1.2.8版本,当A和B存在依赖时,而且A和B中都依赖了一个依赖包,但是版本不一样,C就会依赖步长较近的版本。

可选依赖

如果我们不想要依赖传递下去,那么也可以配置

<dependency> 
<groupId>cn.itcast.maven</groupId>
  <artifactId>hello</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <scope>compile</scope>
  <optional>false</optional>
</dependency>

当optional是true这个依赖包就不会传递下去,如果是false就可以传递,默认是false。

排除依赖

如果想要主动排除传递下来的依赖,那么可以通过exclusions配置要排除的依赖包的groupId和artifactId即可。

<dependency>
    <groupId>cn.itcast.maven</groupId>
    <artifactId>HelloFriend</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <exclusions>
	    <exclusion>
		    <groupId>cn.itcast.maven</groupId>
			<artifactId>hello</artifactId>
	    </exclusion>
    </exclusions>
 </dependency>

maven仓库

maven仓库是用来存储依赖包和插件的位置的文件夹,总共可以分为3种仓库,分别是中央仓库,本地仓库和私服仓库。

中央仓库

是互联网上一个巨大maven的仓库,这里面有绝大多数的依赖包,但是也有少数的依赖包不在中央仓库中,在这个http://mvnrepository.com/网站中可以找到中央仓库中的依赖包的坐标,我们不能上传依赖包。
在这里插入图片描述

本地仓库

默认情况下在~/.m2/repository/文件夹就是我们的仓库,当我们来执行maven的命令或者添加依赖包时,如果本地仓库不存在我们需要的依赖,那么maven就会到中央仓库去下载到本地仓库。

如果第二次再来使用同样的依赖包就不需要下载了,本地仓库可以上传或者安装自己的依赖包,使用的命令是mvn install。

本地苍库的位置可以修改,我们最好不要把它放在默认位置,修改时直接把仓库做剪切放到指定位置,修改用户范围的settings.xml,把localRepository的标签值修改成改变后的仓库的位置,然后rebuild index。
在这里插入图片描述

私服仓库

是一种特殊的远程仓库,它是架设在本地局域网内的仓库,当团队成员进行开发时,每个人都要从中央仓库下载项目构建到本地仓库,费时费力,这个时候可以在局域网环境搭建一个私人仓库供团队使用,这就是maven私服仓库。
在这里插入图片描述
私服仓库具体安装过程如下:
Maven仓库管理

maven的生命周期

Maven的生命周期分为互相独立的三部分,分别是clean,default,site,而每一个周期又包括若干阶段。

clean:用于清理项目,分为3个阶段
default:用于构建项目,分为23个阶段
site:用于建立项目站点,分为4个阶段

阶段

周期所包含的阶段是有前后顺序的,并且后面的阶段依赖于前面的阶段。

阶段的使用

在执行maven命令时,mvn命令之后使用的参数便是maven的各个阶段。

例如:

mvn compile

此命令使用了deault周期的compile阶段。

例如:

mvn clean deploy

此命令使用了clean周期的clean阶段和default周期的deploy阶段。

阶段的顺序

在调用maven的阶段时,会顺序执行本周期当前阶段之前的所有阶段,直至当前阶段。

例如:clean周期共有3个阶段,按顺序分别如下:

1. pre-clean
2. clean
3. post-clean

当执行命令

mvn compile

compile阶段属于default周期,而default周期有23个阶段,compile排序第7位,所以实际执行了default周期的第1阶段validate至第7阶段compile,共7个阶段。包括:

1. validate
2. initialize
3. generate-sources
4. process-sources
5. generate-resources
6. process-resources
7. compile

Maven内部是通过插件中的目标来实现各个阶段的执行

插件(plugin)和目标(goal)

Maven的操作是基于不同的插件的不同目标来实现的

一个插件中包括若干目标,而每个目标会执行一个特定的任务task。

例如:

mvn clean

在上面这个命令中,使用的参数是clean阶段,而实际执行的是maven-clean-plugin插件的clean目标。

因为clean周期的clean阶段是默认绑定到clean插件的clean目标绑定的。(不同的clean)

可在maven-core-*.jar包的META-INF/plexus/components.xml中找到此绑定关系。

<component>
    <role>org.apache.maven.lifecycle.Lifecycle</role>
    <implementation>org.apache.maven.lifecycle.Lifecycle</implementation>
    <role-hint>clean</role-hint>
    <configuration>
        <id>clean</id>
        <phases>
            <phase>pre-clean</phase>
            <phase>clean</phase>
            <phase>post-clean</phase>
        </phases>
        <default-phases>
            <clean>
            org.apache.maven.plugins:maven-clean-plugin:2.5:clean
            </clean>
        </default-phases>
    </configuration>
</component>

其它详细的绑定关系可查看META-INF/plexus目录下的xml文件。

生命周期与阶段的关系表及部分阶段默认绑定的插件目标

顺序生命周期阶段插件:目标
1cleanpre-clean
2cleanclean:clean
3post-clean
——————————————————————————————
1defaultvalidate
2initialize
3generate-sources
4process-sources
5generate-resources
6process-resourcesresources:resources
7compilecompiler:compile
8process-classes
9generate-test-sources
10process-test-sources
11generate-test-resources
12process-test-resourcesresources:testResources
13test-compilecompiler:testCompile
14process-test-classes
15testsurefire:test
16prepare-package
17package
18pre-integration-test
19integration-test
20post-integration-test
21verify
22installinstall:install
23deploydeploy:deploy
——————————————————————————————
1sitepre-site
2sitesite:site
3post-site
4site-deploysite:deploy

官网介绍在此

在生命周期里加入自己想要添加的插件

可以直接在maven项目的pom文件的插件里添加,主要是配置插件需要在生命周期的哪一个阶段的哪一个目标执行。

<plugin>
	<!--
		要使用的插件坐标
	-->
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-source-plugin</artifactId>
    <version>2.2.1</version>
    <!-- 要执行的目标或者是命令 -->
    <executions>
         <execution>
         	<!-- 生命周期的一个阶段 -->
	         <phase>verify</phase>
	         <!-- 要执行的目标(命令) -->
	         <goals>
	               <goal>jar-no-fork</goal>
	         </goals>
	   </execution>
  </executions>
</plugin>

继承与聚合

如果我们想一次构建多个项目模块,那我们就需要对多个项目模块进行聚合。

继承为了消除重复,我们把很多相同的配置提取出来。

  • 聚合主要为了快速构建项目

  • 继承主要为了消除重复

我们可以总结为子项目继承父项目的依赖,父项目将子项目聚合在一起。

聚合

这些配置在父项目上

<modules>
	<!-- 这里是相对路径 -->
  	<module>../Hello</module>  
  	<module>../HelloFriend</module>		
  	<module>../MakeFriends</module>
</modules>

定义属性

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <junit.version>4.9</junit.version>
    <maven.version>0.0.1-SNAPSHOT</maven.version>
</properties>

通过${}访问属性,例如:

<dependency>
	<groupId>junit</groupId>
	<artifactId>junit</artifactId>
	<version>${junit.version}</version>
	<scope>test</scope>
</dependency>	

可以用dependencyManagement控制依赖不被子module共享的方式,但可以做到版本控制

<dependencyManagement>
   <dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>${junit.version}</version>
			<scope>test</scope>
		</dependency>	
		<dependency>
	    	<groupId>cn.itcast.maven</groupId>
	    	<artifactId>HelloFriend</artifactId>
	    	<version>${maven.version}</version>
	    	<type>jar</type>
	    	<scope>compile</scope>
 	 	</dependency>
    </dependencies>
 </dependencyManagement>

需要注意父工程的packing属性为pom

  <!-- 父工程的packing是pom -->
  <packaging>pom</packaging>
  • dependencyManagement中定义的依赖子module不会共享,子项目需要自己配置,但是不需要配置版本,可以说用这个配置可以实现版本控制
  • dependencies中定义的依赖子module可以共享,子module可与不必配置父工程已经有的依赖

继承

通过parent实现对父工程的继承

 <parent>
 	 <groupId>com.rl.ecps</groupId>
 	 <artifactId>ecps-parent0315</artifactId>
	 <version>0.0.1-SNAPSHOT</version>
	 <!-- 父工程的pom.xml的相对路径 -->
	 <relativePath>../pom.xml</relativePath>
 </parent>

需要注意子工程不需要配置坐标的groupId和项目的版本号version

 <!-- pom的版本 -->
 <modelVersion>4.0.0</modelVersion>
 <!-- 坐标第一个维度,组织名.项目名 -->
 <!-- <groupId>com.rl.ecps</groupId> -->
 <!-- 第二维度,模块名 -->
 <artifactId>ecps-console</artifactId>
 <!-- 项目打包后的类型 -->
 <packaging>war</packaging>
 <!-- 第三维度,项目的版本号 -->
<!--  <version>0.0.1-SNAPSHOT</version> -->

如果父工程使用dependencyManagement来做的依赖管理,那么子工程依赖父工程已经有的依赖就不需要配置版本

<dependency>
	<groupId>org.jmock</groupId>
	<artifactId>jmock</artifactId>
	<scope>test</scope>
</dependency>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值