maven 继承与聚合
聚合:聚合多个模块(可以一起构建) ,各模块之间单独打包
继承: 为了消除重复,将相同的配置提取,子模块默认继承全部父模块的依赖dependencies节点,通过它来管理jar包的版本,让子项目中引用一个依赖而不用显示的列出版本号
- 聚合只需要在 父模块 中指定module既可以
java
<modules>
<module>模块一</module>
<module>模块二</module>
<module>模块三</module>
</modules>
- 继承除了要在父模块中指定modules外,还需要在子模块中指定parent
java
<parent>
<groupId>me.gacl.maven</groupId>
<artifactId>ParentProject</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../ParentProject/pom.xml</relativePath>
</parent>
Maven中dependencies节点和dependencyManagement节点的区别
一个是项目依赖,一个是多模块maven项目时候的依赖管理控制的.
dependencyManagement一般存在在顶层pom文件中
dependencies即使在子项目中不写该依赖项,那么子项目仍然会从父项目中继承该依赖项(全部继承)
dependencyManagement里只是声明依赖,并不实现引入,因此子项目需要显示的声明需要用的依赖。如果不在子项目中声明依赖,是不会从父项目中继承下来的;只有在子项目中写了该依赖项,并且没有指定具体版本,才会从父项目中继承该项,并且version和scope都读取自父pom;另外如果子项目中指定了版本号,那么会使用子项目中指定的jar版本。
java
<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>
dependencyManagement的好处是子模块可以有选择行的继承,而不需要全部继承。
注意:dependencyManagement只是进行版本的管理,可以让子模块有选择的进行依赖
dependency元素
dependency中除了可以指定依赖项目的groupId、artifactId和version之外,还可以指定以下元素:
-
type:对应于依赖项目的packaging类型,默认是jar
-
scope:表示依赖项目的一个作用范围。scope的主要取值范围如下(还有一个是在Maven2.0.9以后版本才支持的import,关于import作用域将在后文《Dependency介绍》中做介绍):
-
compile:这是它的默认值,这种类型很容易让人产生误解,以为只有在编译的时候才是需要的,其实这种类型表示所有的情况都是有用的,包括编译和运行时。而且这种类型的依赖性是可以传递的。
-
provided:这个跟compile很类似,但是它表示你期望这个依赖项目在运行时由JDK或者容器来提供。这种类型表示该依赖只有在测试和编译的情况下才有效,在运行时将由JDK或者容器提供。这种类型的依赖性是不可传递的。
-
runtime:这种类型表示该依赖在编译的时候不是必须的,只有在运行的时候才是必须的。
-
test:这表示这种依赖只有测试的时候才需要,正常情况下是不需要的。
-
system:这种类型跟provided类似,唯一不同的就是这种类型的依赖我们要自己提供jar包,这需要与另一个元素systemPath来结合使用。systemPath将指向我们系统上的jar包的路径,而且必须是给定的绝对路径。
-
-
systemPath:上面已经说过了这个元素是在scope的值为system的时候用于指定依赖的jar包在系统上的位置的,而且是绝对路径。该元素必须在依赖的 jar包的scope为system时才能使用,否则Maven将报错。
-
optional:当该项目本身作为其他项目的一个依赖时标记该依赖为可选项。假设现在projectA有一个依赖性projectB,我们把projectB这个依赖项设为optional,这表示projectB在projectA的运行时不一定会用到。这个时候如果我们有另一个项目projectC,它依赖于projectA,那么这个时候因为projectB对于projectA是可选的,所以Maven在建立projectC的时候就不会安装projectB,这个时候如果projectC确实需要使用到projectB,那么它就可以定义自己对projectB的依赖。当一个依赖是可选的时候,我们把optional元素的值设为true,否则就不设置optional元素。
-
exclusions:考虑这样一种情况,我们的projectA依赖于projectB,然后projectB又依赖于projectC,但是在projectA里面我们不需要projectB依赖的projectC,那么这个时候我们就可以在依赖projectB的时候使用exclusions元素下面的exclusion排除projectC。
maven 打包
当项目要上线,部署到服务器上去的时候或许会碰见这样的问题。问题就是,服务器上没有maven的环境,也就是说,项目所依赖到的那些仓库(repository)中的jar包你需要单独提取出来上传到服务器中去。
maven 在进行打包(mvn package)时,会根据< packaging >来判断是打成何种包:
war包 :能自动将项目依赖的jar包打到web-inf下的lib文件夹中。
jar包:执行过程中不会将依赖的第三方包提取出来。
java
<groupId>com.sankuai.peisong.data</groupId>
<artifactId>waybill_dispatch_dw</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar or war</packaging>
maven assembly插件
maven在打包的时候,如果是对jar包进行打包,是不会将依赖的第三方包提取出来,发布项目只发布这个打包好的jar包,会提示找不到第三方依赖包中类的定义。之前看到有人在项目要上线的时候将pom类型改成war,然后执行一下mvn package命令,这样先把所以依赖到的包提取出来,然后再把pom类型改成jar,这样虽然能完成任务,但是,总感觉这样的做法比较拙劣。
其实,完全可以通过使用maven自带的assembly插件来完成 先打war包,然后再改为jar的过程。
1.在pom文件中指定assembly插件
java
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptors>
<descriptor>assembly.xml</descriptor>
</descriptors>
</configuration>
</plugin>
<plugins>
2.开发assembly.xml文件
java
<assembly>
<id>spark-online</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<unpack>true</unpack>
</dependencySet>
</dependencySets>
</assembly>
unpack元素指定为true,则会将所有的代码打包到指定的jar包中
注意这会将所有的包都unpack到目标jar包里(即该jar包包含所有的代码)
unpack元素指定为false,则会对各个第三方依赖分别打到jar包中