读书笔记-《Maven实战》

第一章:Maven简介

没有人会抵触优秀的技术,除非缺乏文档、学习成本高。

构建(build):包括编译、单元测试、文档生成、打包、部署等。

Maven是构建工具、依赖管理工具、项目信息管理工具。

Make和Ant是过程式的,Maven是声明式的;Make不易实现跨平台构建,Ant没有依赖管理。

第二章:Maven的安装和配置

Maven安装目录文件解析

- bin。包含mvn运行的脚本。这些脚本用来配置Java命令,准备好classpath和相关的Java系统属性,然后执行Java命令。mvn是基于UNIX平台的shell脚本,mvn.bat则是基于Windows平台的bat脚本。

- boot。类加载器框架,用来加载自己的类库。

- conf。Setting文件全局地控制Maven的行为,是最重要的部分。

- lib。Maven运行时所需要的Java类库。还包括超级POM。

- 其他文件。包括LICENSE.txt、NOTICE.txt、README.txt。

不建议使用IDE自带的Maven

- 通常该Maven版本较新,非稳定版。

- 可能与命令行Maven版本不一致,从而造成构建不一致。

第三章:Maven使用入门

Maven的POM(Project Object Model),相当于Make的Makefile,Ant的build.xml。

第四章:背景案例

跳过。

第五章:座标和依赖

Maven采用座标机制来管理构建。(联想:如果软件安装包也可以使用这个机制就好了,不过现在公司一般都会放在内网上。)

座标

- groupId。当前Maven项目所属的实际项目。例如com.companyName.projectName。

- artifacId。实际项目中的Maven项目(模块)。例如projectName-modularName。

- version。版本。

- packaging。打包方式。

- classifier。用于协助输出附属构件。

依赖的配置

- groupId、artifactId、version。即座标。

- type。类型,相当于packaging。

- scope。范围,控制与编译、测试、运行classpath的关系。包括compile(默认值,编译范围,3种classpath都有效)、test(仅测试classpath有效,例如JUnit)、provided(已提供依赖范围,编译和测试有效,运行无效,例如servlet-api,运行时容器已提供)、runtime(测试运行有效,编译无效,例如JDBC驱动实现)、system(与本机系统绑定,不推荐使用)、import(聚合工程中可能用到)。

- optional。是否可选。

- exclusions。排除传递性依赖。

传递性依赖和依赖范围

依赖调解:当同一个构件被多次引用时,首先采用最短路径优先原则,如果路径长度相同,则采用最先声明优先原则。

排除依赖:传递性依赖会导致隐士地引入很多依赖,有时也会造成问题。可通过以下方式解决。

<dependencies>
    <dependency>
        <groupId>com.companyName.projectName</groupId>
        <artifactId>projectName-modularName</artifactId>
        <version>1.0.0</version>
        <exclusions>
            <exclusion>
                <groupId>com.companyName.projectName</groupId>
                <artifactId>projectName-anotherModularName</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>com.companyName.projectName</groupId>
        <artifactId>projectName-anotherModularName</artifactId>
        <version>1.0.0</version>
    </dependency>
</dependencies>

优化依赖

- mvn dependency:list。查看已解析依赖。

- mvn dependency:tree。依赖树。

- mvn dependency:analyze。分析依赖。

第六章:仓库

座标可理解为构件的逻辑地址,仓库则为构件的物理地址。

超级POM

<repositories>
    <repository>
        <id>central</id>
        <name>Maven Repository Switchboard</name>
        <url>http://repo1.maven.org/maven2</url>
        <layout>default</layout>
        <snapshots>
            <enabled>false</enabled>
        <snapshots>
    </repository>
</repositories>

快照版本仅在组织内部的项目或模块间依赖使用,例如两位同学同时开发模块A和B,并且有依赖关系,其余时候都应避免使用快照版本。快照版本会在版本号后面加上时间戳。

镜像仓库会完全屏蔽掉被镜像仓库,如果镜像仓库不可用,Maven将无法下载构件。

第七章:生命周期和插件

Maven的3种生命周期:clean、default、site。

生命周期与插件目标

可自定义绑定生命周期与插件目标。可通过命令行、POM进行插件配置。

第八章:聚合与继承

通过<modules>标签实现聚合

<!-- account-aggregator的POM -->
<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.companyName.projectName</groupId>
    <artifactId>account-aggregator</artifactId>
    <version>1.0.0</version>
    <packaging>pom</packaging>
    <modules>
        <module>account-email</module>
        <module>account-persist</module>
    </modules>
</project>

通过<parent>标签实现继承

<!-- account-email的POM-->
<project>
    <parent>
        <groupId>com.companyName.projectName</groupId>
        <artifactId>account-parent</artifactId>
        <version>1.0.0</version>
        <relativePath>../account-parent/pom.xml</relativePath>
    </parent>
</project>

聚合与继承:聚合方便快速构建项目,继承减少重复配置。两者除了POM以外没有别的内容。

<dependencyManagement>标签:能让子模块继承到父模块的依赖配置,又能保证子模块的灵活性。子模块如果编写了该<dependency>,则不需要编写版本号,由父模块统一管理;如果没有编写该<dependency>,同样也不会引入依赖。

常见的可被继承的POM元素:groupId、version、distributionManagement、properties、dependencies、dependencyManagement、repositories、build。

Maven反应堆(Reactor):所有模块所组成的构建结构,以及各模块之间的继承与依赖关系。

可通过输出查看构建顺序,如果模块A继承模块B,则优先构建模块B。当模块A和B互相继承则会报错。

第九章:使用Nexus创建私服

私服的好处:降低中央仓库负荷,节省外网带宽,加速Maven构建,自己部署构件等。

Nexus的特性:内存占用小,REST API,支持代理仓库、宿主仓库、仓库组,基于文件系统,图形界面,支持搜索和权限控制。

两种安装包

- 不包含Web容器的war包。

- 包含Jetty容器的Bundle包。解压后得到nexus-webapp-1.7.2、sonatype-work。前者包括Nexus运行所需要的文件,如启动脚本,依赖jar包,是运行必需的,相同版本的内容是一样的。后者为Nexus运行时动态创建的目录,对于各实例是不一样的(因为不同的用户在不同的环境下使用会有不同的配置和仓库内容),所以备份也只需要备份这个目录。

Windows启动方式为运行/bin/jsw/windows-x86-32/nexus.bat。

Linux启动方式为进入/bin/jsw/linux-x86-32/,运行$ . /nexus console。此时可以看到命令行输出,使用Ctrl + C停止Nexus。此外还可以使用start/stop/status/restart,分别代表启动/停止/查看状态/重新启动。

在/conf/plexus.properties中可找到application-port,修改端口号。

仓库类型

权限:Nexus基于权限做访问控制,每一个资源都有相应的权限来控制。包括admin、deployment、anonymous,默认管理员为admin/admin123,默认开发者为deployment/deployment123。创建好仓库后,还需要创建基于仓库的增删改查权限并进行分配。

Maven中使用私服

<!-- 在settings.xml中配置Nexus仓库 -->
<settings>
    <profiles>
        <profile>    
            <id>nexus</id>
            <repositories>
                <repository>
                    <id>nexus</id>
                    <name>Nexus</name>
                    <url>http://localhost:8081/nexus/content/groups/public/</url>
                    <releases><enabled>true</enabled></releases>
                    <snapshots><enabled>true</enabled></snapshots>
                </repository>
            </repositories>
            <pluginRepositories>
                <pluginRepository>
                    <id>nexus</id>
                    <name>Nexus</name>
                    <url>http://localhost:8081/nexus/content/groups/public/</url>
                    <releases><enabled>true</enabled></releases>
                    <snapshots><enabled>true</enabled></snapshots>
                </pluginRepository>
            </pluginRepositories>
        </profile>
    </profiles>
    <activeProfiles>
        <activeProfile>nexus</activeProfile>
    </activeProfiles>
</settings>

<!-- 在settings.xml中配置 仅使用Nexus仓库 -->
<settings>
    <mirrors>
        <mirror>
            <id>nexus</id>
            <mirrorOf>*</mirrorOf>
            <url>http://localhost:8081/nexus/content/groups/public</url>
        </mirror>
    </mirrors>
    <profiles>
        <profile>
            <id></id>
            <repositories>
                <repository>
                    <id>central</id>
                    <url>http://central</url>
                    <releases><enabled>true</enabled></releases>
                    <snapshots><enabled>true</enabled></snapshots>
                </repository>
            </repositories>
            <pluginRepositories>
                <pluginRepository>
                    <id>central</id>
                    <url>http://central</url>
                    <releases><enabled>true</enabled></releases>
                    <snapshots><enabled>true</enabled></snapshots>
                </pluginRepository>
            </pluginRepositories>
        </profile>
    </profiles>
    <activeProfiles>
        <activeProfile>nexus</activeProfile>
    </activeProfiles>
</settings>

Maven部署构件至Nexus

<!-- POM -->
<project>
    <distributionManagement>
        <repository>
            <id>nexus-releases</id>
            <name>Nexus Releases Repository</name>
            <url>http://localhost:8081/nexus/content/repositories/releases/</url>
        </repository>
        <snapshotRepository>
            <id>nexus-snapshots</id>
            <name>Nexus Snapshots Repository</name>
            <url>http://localhost:8081/nexus/content/repositories/snapshots/</url>
        </snapshotRepository>
    </distributionManagement>
</project>

<!-- settings -->
<settings>
    <servers>
        <server>
            <id>nexus-releases</id>
            <username>admin</username>
            <password>admin123</password>
        </server>
        <server>
            <id>nexus-snapshots</id>
            <username>admin</username>
            <password>admin123</password>
        </server>
    </servers>
</settings>

第十章:使用Maven进行测试

跳过,学习意义不大,对小公司来说时间成本过高,不如直接按照测试用例文档进行自测,大公司在自测后会有单独的测试环境和测试团队来进行测试。

第十一章:使用Hudson进行持续继承

持续集成(Continuous Integration)快速高频率自动构建项目的所有源码,并为项目成员提供丰富的反馈信息。

持续集成示例

集成的步骤

- 持续编译。与版本控制系统(如Git)集成,自动触发编译。

- 持续数据库集成

- 持续测试

- 持续审查。与代码检查系统集成。

- 持续部署

- 持续反馈

集成的好处:尽早暴露问题、减少重复操作、简化项目发布、建立团队信息。

第十二章:使用Maven构建Web应用

跳过,与主流的 Spring Boot 的项目骨架脱节太多。

第十三章:版本管理

跳过。

第十四章:灵活的构建

Maven属性:内置属性、POM属性、自定义属性、Settings属性、Java系统属性、环境变量熟悉。

自定义Maven属性:变量定义在<properties>标签里,然后通过${}调用。

使用示例:将Spring的版本抽象出来统一管理;聚合项目中子模块直接调用父的groupId和version。

profile示例(开发环境的数据库配置)(可写在POM、Settings):

<profiles>
    <profile>
        <id>dev</id>
        <properties>
            <db.driver>com.mysql.jdbc.Driver</db.driver>
            <db.url>jdbc:mysql://localhost:3306/test</db.url>
            <db.username>dev-username</db.username>
            <db.password>dev-password</db.password>
        </properties>
    </profile>
</profiles>

激活profile

- 命令行激活。在命令行尾部加上 -Pdev。

- Settings文件显示激活。

<settings>
    <activeProfiles>
        <activeProfile>dev</activeProfile>
    </activeProfiles>
</settings>

- 系统属性激活。本质上和命令行激活一样。

- 操作系统环境激活。(这个方法应该是最常用的,服务器和开发机OS一般都是不一样的)

<profiles>
    <profile>
        <activation>
            <os>
                <name>Windows XP</name>
                <family>Windows</family>
                <arch>x86</arch>
                <version>5.1.2600</version>
            </os>
        </activation>
    </profile>
</profiles>

- 文件存在与否激活。和上面的类似,在<activation>标签里配置<file>标签,<file>标签里配置<missing>标签或<exists>标签。

- 默认激活。和上面的类似,在<activation>标签里配置<activeByDefault>标签,且值为true。

命令行查看:通过$mvn help:all-profiles和$mvn help:active-profiles来查看所有profile和已激活的profile。

第十五章:生成项目站点

跳过,功能一般,用不到。

第十六章:m2eclipse

跳过,目前主流用IDEA。

第十七章:编写Maven插件

跳过,前人编写的插件能满足几乎100%的业务需求了,不用重复造轮子。

第十八章:Archetype

跳过,项目骨架不要标新立异,按照规范来,减少人员学习成本。

发布了25 篇原创文章 · 获赞 12 · 访问量 4万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章