MOYUN(/Java/SQL/Linux/DevOps/运维/架构/管理/敏捷/开发)

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

1、Maven介绍

  Maven 翻译为"专家"、"内行",是 Apache 下的一个纯 Java 开发的开源项目。基于项目对象模型(缩写:POM)概念,Maven利用一个中央信息片断能管理一个项目的构建、报告和文档等步骤。

       Maven是一个管理工具,可以对 Java 项目进行构建、依赖管理。Maven 曾是 Jakarta 项目的子项目,现为由 Apache 软件基金会主持的独立 Apache 项目,

 

2、Maven特点

  1.  项目设置遵循统一的规则
  2.  任意工程中共享
  3.  依赖管理包括自动更新
  4.    一个庞大且不断增长的库
  5.    可扩展,能够轻松编写 Java 或脚本语言的插件
  6.    只需很少或不需要额外配置即可即时访问新功能
  7.    基于模型的构建 − Maven能够将任意数量的项目构建到预定义的输出类型中,如 JAR,WAR 或基于项目元数据的分发,而不需要在大多数情况下执行任何脚本
  8.    项目信息的一致性站点 − 使用与构建过程相同的元数据,Maven 能够生成一个网站或PDF,包括您要添加的任何文档,并添加到关于项目开发状态的标准报告中
  9.    发布管理和发布单独的输出 − Maven 将不需要额外的配置,就可以与源代码管理系统(如 Subversion 或 Git)集成,并可以基于某个标签管理项目的发布。也可以发布到分发位置供其他项目使用。包含其他依赖和文档的归档,或者作为源代码发布。
  10.    向后兼容性 − 您可以很轻松的从旧版本 Maven 的多个模块移植到 Maven 3 中
  11.    子项目使用父项目依赖时,正常情况子项目应该继承父项目依赖,无需使用版本号

 

3、Maven scope依赖范围详解

   Maven的生命周期存在编译、测试、运行这些过程,那么显然有些依赖只用于测试,比如junit;有些依赖编译用不到,只有运行的时候才能用到,比如mysql的驱动包在编译期就用不到(编译期用的是JDBC接口),而是在运行时用到的;还有些依赖,编译期要用到,而运行期不需要提供,因为有些容器已经提供了,比如servlet-api在tomcat中已经提供了,我们只需要的是编译期提供而已。总结说来,在POM 4中,<dependency>中还引入了<scope>,它主要管理依赖的部署。大致有compile、provided、runtime、test、system等几个。

  1. compile:默认的scope,运行期有效,需要打入包中
  2. provided:编译期有效,运行期不需要提供,不会打入包中
  3. runtime:编译不需要,在运行期有效,需要导入包中。(接口与实现分离)
  4. test:测试需要,不会打入包中
  5. system:非本地仓库引入、存在系统的某个路径下的jar。(一般不使用)

 

3.1 compile模式(编译范围)

  默认就是compile,什么都不配置也就是意味着compile。compile表示被依赖项目需要参与当前项目的编译,当然后续的测试,运行周期也参与其中,是一个比较强的依赖。打包的时候通常需要包含进去.

  该依赖需要参与当前项目的编译、测试、运行、打包

 

 

3.2 compile模式(运行时范围)

  runntime表示被依赖项目无需参与项目的编译,不过后期的测试和运行周期需要其参与。与compile相比,跳过编译而已.

  比如,你可能在编译的时候只需要JDBC API JAR,而只有在运行的时候才需要JDBC驱动实现。

  编译时该包不参与,运行时参与

 

3.3 test 模式(测试范围)

  test范围依赖 在一般的编译和运行时都不需要,它们只有在测试编译和测试运行阶段可用。比如

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <scope>test</scope>
</dependency>

  

 3.4 provided(已提供范围)

  provided 表明该依赖已经提供,故只在未提供时才被使用,

  应用场景是你定义了一个Servlet,此刻得需要Servlet-api.jar 才能编译成功,但是当你达成war 包时,你并不想将 Servlet-api.jar 包进去,因为Tomcat等容器会提供

  跟compile 类似,说明JDK、容器或使用者会提供这个依赖,如Servlet.jar

  这个依赖只作用在** 编译和测试,该依赖会由系统组件提供,不需手动添加,只存在编译、运行、测试阶段,打包是不用包进去,打包阶段做了exclude**动作

  provided意味着打包的时候可以不用包进去,别的设施(Web Container)会提供。

  阿里开发规范文档:如果依赖其它二方库,尽量是 provided 引入,让二方库使用者去依赖具体版本号log 具体实现,只依赖日志框架

  例如 : 添加<scope>provided</scope>,因为provided表明该包只在编译和测试的时候用,所以,当启动tomcat的时候,就不会冲突了

<dependency>
	<groupId>javax.servlet</groupId>
	<artifactId>servlet-api</artifactId>
	<version>3.0-alpha-1</version>
	<scope>provided</scope>
</dependency>

  

3.5 system (系统范围)

  被依赖项不会从maven仓库下载,而是从本地系统指定路径下寻找,需要 systemPath 属性

  system范围依赖与provided 类似,但是你必须显式的提供一个对于本地系统中JAR 文件的路径,这么做是为了允许基于本地对象编译,而这些对象是系统类库的一部分。这样的构件应该是一直可用的,Maven 也不会在仓库中去寻找它

    从参与度来说,与provided相同,不过被依赖项不会从maven仓库抓,而是从本地文件系统拿,一定需要配合systemPath属性使用,例如:

 

  一、方式1.dependency 本地jar包,如果没有建私服,可以在pom.xml中通过文件方式引

<dependency>
	<!--自定义-->
	<groupId>com.im</groupId>  
	<!--自定义-->
	<artifactId>sdk</artifactId>    
	<!--自定义-->
	<version>1.0</version> 
	<!--system,类似provided,需要显式提供依赖的jar以后,Maven就不会在Repository中查找它-->
	<scope>system</scope> 
	<!--项目根目录下的lib文件夹下-->
	<systemPath>${basedir}/lib/sdk-1.0.jar</systemPath> 
</dependency> 

  

  二、方式2.编译阶段指定外部lib

<plugin>
	<artifactId>maven-compiler-plugin</artifactId>
	<version>2.3.2</version>
	<configuration>
	<source>1.8</source>
	<target>1.8</target>
	<encoding>UTF-8</encoding>
	<compilerArguments>
	<!--指定外部lib-->
	<extdirs>lib</extdirs>
	</compilerArguments>
	</configuration>
</plugin>

  

  三、方式3.0 将外部jar打入本地maven仓库

  mvn install:install-file -Dfile=sdk-1.0.jar -DgroupId=com.im -DartifactId=sdk -Dversion=1.0 -Dpackaging=jar

 

  四、方式3.1 引入jar包

<dependency>
	<groupId>com.im</groupId>
	<artifactId>sdk</artifactId>
	<version>1.0</version>
</dependency>

  

  五、maven预定义内置属性

${basedir}表示项目根目录,即包含pom.xml文件的目录;
${version}表示项目版本;
${project.basedir}同${basedir};
${project.baseUri}表示项目文件地址;
${maven.build.timestamp}表示项目构件开始时间;
${maven.build.timestamp.format}表示属性${maven.build.timestamp}的展示格式,默认值为yyyyMMdd-HHmm,可自定义其格式

  

 

4、scope 的传递依赖

  A -> B -> C, 当前项目 A,A依赖于B,B依赖于C,知道B在 A中的scope,怎么知道 C在 A 中的 scope

  即,A需不需要 C的问题,本质由 C在B中的scope决定

  当 C 在 B 中的scope 是test 或 provided 时,C 直接被丢弃,A不依赖C

  否则 A 依赖 C,C的scope 继承与B 的scope

 

posted on 2019-11-14 14:15  moyun-  阅读(15792)  评论(0编辑  收藏  举报