《Maven实战》学习笔记 目录
《Maven实战》pdf 百度网盘
链接:https://pan.baidu.com/s/1i0rIN4P2LlsdTmRbCl-C1g
提取码:a7x4
若失效,请发送邮件至 2946632291@qq.com ,我看到后会分享给你
Maven的安装和配置
- 安装目录M2_HOME分析
bin:包含mvn运行的脚本
boot:plexus-classworlds-2.6.0.jar,是一个类加载器框架
conf:包含`settings.xml`,一般会复制到`~/.m2/`目录下,然后修改该文件
lib:包含Maven运行时需要的Java类库
Maven使用入门
-
编写pom
- pom:Project Object Model,项目对象模型
groupId
定义了项目属于哪个组,这个组一般和公司或组织相关联,例如在googlecode上建立一个名为myapp的项目,那么groupId就应该是com.googlecode.myapp
。如果公司是mycom,有一个项目是myapp,那么groupId是com.mycom.myapp
artifactId
定义了当前maven项目在组中唯一的IDversion
定义了该项目的版本号
-
编写主代码
-
使用Archetype生成项目骨架:
mvn archetype:generate
背景案例
fun.hb.mvnbook.account.service:封装所有下层细节
fun.hb.mvnbook.account.web:包括可能的JSP、Servlet、web.xml等,它直接依赖于service模块,使用其提供的服务
fun.hb.mvnbook.account.persist:处理账户信息的持久化,包括增删改查
fun.hb.mvnbook.account.verification:处理验证码的key生成、图片生成以及验证等
fun.hb.mvnbook.account.email:处理邮件服务的配置、激活邮件的编写和发送
坐标和依赖
-
坐标 Coordinate
- Maven定义了一组规则,使世界上不同区域的任何一个**构件** 都可以使用Maven坐标唯一标识
- Maven坐标的元素包括
groupId、artifactId、version、packaging、classifier
-
groupId:定义当前Maven项目隶属的实际项目
- 一个实际项目往往会被划分为很多模块
- groupId 不应该 对应项目隶属的组织或公司,因为一个组织下会有很多实际项目
-
artifactId:定义实际项目中的一个Maven项目(模块)
- 推荐使用实际项目名作为artifactId的前缀,例如
nexus-indexer
- 默认情况下,Maven生成的构件,其文件名会以artifactId作为开头,例如
nexus-indexer-2.0.0.jar
- 这样方便区分和寻找实际构件
- 推荐使用实际项目名作为artifactId的前缀,例如
-
version:定义Maven项目当前所处的版本
-
packaging:定义Maven项目的打包方式
- 打包方式通常与所生成构件的文件扩展名对应
- 打包方式会影响到构件的生命周期,例如jar打包和war打包会使用不同的命令
- 不定义packing时,Maven默认使用jar
-
classifier:帮助定义构件的一些附属构件
- 例如主构件
nexus-indexer-2.0.0.jar
通过使用一些插件生成如nexus-indexer-2.0.0-javadoc.jar、nexus-indexer-2.0.0-sources.jar
这些附属构件 - 这样,附属构件也拥有了唯一的坐标
- 不能直接定义项目的classifier,因为附属构件不是项目直接默认生成的,而是由附加的插件帮助生成
- 例如主构件
-
总结:groupId、artifactId、version是必须定义,packaging可选(默认是jar),而classifier不能直接定义
-
依赖范围
compile:编译依赖范围,对编译、测试、运行三种classpath都有效。例如spring-core test:测试依赖范围,只对测试classpath有效。例如JUnit provided:对编译和测试classpath有效,在运行时无效。例如servlet-api runtime:对测试和运行classpath有效,编译主代码时无效。例如JDBC驱动实现 system:系统依赖范围,和provided依赖范围完全一致,但由于常与本机系统绑定,应慎重使用 import:导入依赖范围
-
总结:
-
-
传递性依赖机制:Maven会解析各个直接依赖的POM,将必要的间接依赖,以传递性依赖的形式引入到当前的项目中
-
依赖调解:解决依赖路径上不同版本的包
- Maven依赖调解(Dependency Mediation)第一原则:路径最近者优先
- 依赖调解的第二原则:第一声明者优先
-
常用套路
-
排除依赖
<dependency> <groupId>***</groupId> <artifactId>+++</artifactId> <version>---</version> <!-- 不想引入传递性依赖111.222,可以使用如下代码。不需要version就可唯一定位依赖 --> <exclusions> <exclusion> <groupId>111</groupId> <artifactId>222</artifactId> </exclusion> </exclusions> </dependency>
-
归类依赖
<!-- 以springframework为例,先用properties标签, 再用dependencies标签,实现归类 --> <properties> <springframework.version>2.5.6</springframework.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${springframework.version}</version> </dependency> ... </dependencies>
-
优化依赖
<!-- 经过前两步之后,最终得到的那些依赖被称为 已解析依赖(Resolved Dependency)--\> mvn dependency:list 第一二三四...等层依赖经Maven解析后,构成一个依赖树--\> mvn dependency:tree dependency:analyze 可以帮助分析当前项目编译主代码和测试代码需要的依赖 1. Used undeclared dependencies,意味着给以后留大坑 2. Unused declared dependencies,不能轻易删除 -->
-
仓库
-
仓库的布局
-
任何一个构件都有唯一的坐标,根据这个坐标定义其在仓库的唯一存储路径
-
该路径与坐标的大致对应关系为:
groupId/artifactId/version/artifactId-version.packaging
-
生命周期和插件
-
Maven的生命周期是抽象的,实际行为都由插件来完成
- 这种思想与设计模式中的
模板方法(Template Method)
相似 - 模板方法模式在父类中定义算法的整体结构
- 子类可以通过实现或者重写父类的方法来控制实际的行为
- 这样既保证了算法有足够的可扩展性,又能够严格控制算法的整体结构
- 通过默认插件简化和稳定了项目的构建,同时用户可以通过配置现有插件或自行编写插件来自定义构建行为
- 这种思想与设计模式中的
-
生命周期详解
-
执行Maven任务的最主要方式是调用Maven的生命周期阶段。
- 各个生命周期是相互独立的,而一个生命周期的阶段是有前后依赖关系的
-
三套独立的生命周期:
clean、default、site
1. clean:清理项目 三个阶段(phase):pre-clean、clean、post-clean 2. default:构建项目(最核心的部分),以下phase是重点不是全部 process-sources:处理项目主资源文件。对src/main/resources 目录的内容进行变量替换等工作后,复制到项目输出的 主classpath 目录中 compile:编译项目的主源码。编译src/main/java 目录下的Java文件至项目输出的主classpath目录中 process-test-resources:处理项目测试资源文件。对src/test/resources 目录的内容进行变量替换等工作后,复制到项目输出的 测试classpath 目录中 test-compile:编译项目的测试代码。编译src/test/java 目录下的Java文件至项目输出的 测试classpath 目录中 test:使用单元测试框架运行测试,测试代码不被打包或部署 package:接受编译好的代码,打包成可发布的格式,如jar install:将包安装到Maven本地仓库,供本地其他Maven项目使用 deploy:将最终的包复制到远程仓库,供其他开发人员和Maven项目使用 3. site:基于POM所包含的信息,建立和发布项目站点,方便团队交流和发布项目信息 pre-site:执行一些在生成项目站点之前需要完成的工作 site:生成项目站点文档 post-site:执行一些在生成项目站点之后要完成的工作 site-deploy:将生成的项目站点发布到服务器上
-
-
插件目标(Plugin Goal)
- 插件以独立的构件的形式存在
插件本身为了复用代码,往往能够完成多个任务。例如 maven-dependency-plugin ,它能够基于项目依赖做很多事情,包括分析项目依赖、找出潜在的无用依赖、列出项目的依赖树、帮助分析依赖来源、列出项目所有已解析的依赖等等。这些功能聚集在一个插件里,每个功能就是一个插件目标。 maven-dependency-plugin 有十多个目标,每个目标对应一个功能,上述提到的功能对应的插件目标为: dependency:analyze、dependency:tree、dependency:list