Maven初步

    xiaoxiao2022-07-03  152

    为什么需要Maven

    1.如果没有Maven,你如何完成java项目的开发,配置,测试,和发布呢?

    以下是一个普通的Java工程

    src下建包写代码,那么配置文件放在哪里?单元测试代码放在哪里?没有一个统一标准,更多时候都是开发者的自由发挥,每个人有自己的风格,这并不十分适合团队协作。

     

    2.如果没有Maven,你如何完成Java项目包管理?

    先找好要调用的包,然后手动导包。这样做有以下缺陷:

    1)如果开发过程中,现所调用的包B中有bug,则必须将B项目修改好,并重新将B打包并对A项目进行导包和重编译操作,或者重新下载新版本的包导入再重编译操作。

    2)如果所导入的包很多,那么要一个个手动找和导入,再如果所依赖的包版本有更新,又要自己手动更新重编译

    Maven是什么

    Maven主要做了两件事:统一开发规范与工具(对应问题1);统一管理jar包(对应问题2)。

     

    1.统一开发规范与工具

    看一下使用maven构建一个普通Java项目之后的目录结构:

    看到使用Maven构建的普通Java项目,对源代码、单元测试代码、资源乃至后续需要的文件都有专门的目录规划。

    main目录下是项目的主要代码,test目录下存放测试相关的代码 编译输出后的代码会放在target目录下 src/main/java下存放Java代码,src/main/resources下存放配置文件 这里没有webapp,Web项目会有webapp目录,webapp下存放Web应用相关代码 pom.xml是Maven项目的配置文件

     

    2.统一管理jar包

    pom.xml,这是Maven的核心配置文件,pom称为Project Object Model(项目对象模型),它用于描述整个Maven项目,所以也称为Maven描述文件。

    pom.xml

    打开pom.xml,最基础的是这样的:

     

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.xrq.withmaven</groupId> <artifactId>withmaven</artifactId> <version>0.0.1-SNAPSHOT</version> <build/> </project>

    1、modelVersion

    指定了当前Maven模型的版本号,对于Maven2和Maven3来说,它只能是4.0.0

    2、groupId

    顾名思义,这个应该是公司名或是组织名。一般来说groupId是由三个部分组成,每个部分之间以"."分隔,第一部分是项目用途,比如用于商业的就是"com",用于非营利性组织的就 是"org";第二部分是公司名,比如"tengxun"、"baidu"、"alibaba";第三部分是你的项目名

    3、artifactId

    可以认为是Maven构建的项目名,比如你的项目中有子项目,就可以使用"项目名-子项目名"的命名方式

    4、version

    版本号,SNAPSHOT意为快照,说明该项目还在开发中,是不稳定的版本。在Maven中很重要的一点是,groupId、artifactId、version三个元素生成了一个Maven项目的基本坐标,

     

    其中几点需要重点看看:

    1)dependencyManagement

    <dependencyManagement> <dependencies> <dependency> <groupId>com.xxx.xxx</groupId> <artifactId>dm</artifactId> <version>1.0.0.1</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.xxx.xxx</groupId> <artifactId>bsa-setl</artifactId> <version>0.1.3</version> <scope>provided</scope> </dependency> </dependencies>

    比如这个例子,在pom.xml中,依赖部分只有这些。可见的显示的依赖包只有junit,bsa-setl,但事实上这是基于spark,hadoop等一些列包的的项目。

    可以打开,idea中module setting查看

    那么这些包的依赖关系配置在哪里呢?

    <dependencyManagement> <dependencies> <dependency> <groupId>com.xxx.xxx</groupId> <artifactId>dm</artifactId> <version>1.0.0.1</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>

    这时候,dependencyManagement的作用就突显出来了。

    由于这不是一个独立的项目,而是一个待开发的子项目,但是它又需要一些父项目依赖的相关包。那么我们又要重新copy一遍父项目的依赖配置吗?显然是多余的。

     

    解决这个问题可以通过两种方式,一种是继承父pom,一种是导入其他pom,上例中是使用的导入方式。如果在dependencyManagement的还定义了新版本的dependency,则会覆盖原有版本。

     

    例如:

    项目A

    <project> <modelVersion>4.0.0</modelVersion> <groupId>maven</groupId> <artifactId>A</artifactId> <packaging>pom</packaging> <name>A</name> <version>1.0</version> <dependencyManagement> <dependencies> <dependency> <groupId>test</groupId> <artifactId>a</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>test</groupId> <artifactId>b</artifactId> <version>1.0</version> <scope>compile</scope> </dependency> <dependency> <groupId>test</groupId> <artifactId>c</artifactId> <version>1.0</version> <scope>compile</scope> </dependency> <dependency> <groupId>test</groupId> <artifactId>d</artifactId> <version>1.2</version> </dependency> </dependencies> </dependencyManagement> </project>

     

    导入的方式

    项目B需要使用到项目A中包:

    <project> <modelVersion>4.0.0</modelVersion> <groupId>maven</groupId> <artifactId>B</artifactId> <packaging>pom</packaging> <name>B</name> <version>1.0</version> <dependencyManagement> <dependencies> <dependency> <groupId>maven</groupId> <artifactId>A</artifactId> <version>1.0</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>test</groupId> <artifactId>d</artifactId> <version>1.0</version> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>test</groupId> <artifactId>a</artifactId> <version>1.0</version> <scope>runtime</scope> </dependency> <dependency> <groupId>test</groupId> <artifactId>c</artifactId> <scope>runtime</scope> </dependency> </dependencies> </project>

    注意这里的d这个包就被覆盖掉 了。

     

    至于继承的方式,由于maven中也只能使用单继承,所以对于大型项目来说,灵活性可能不够了。

     

    详见:https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Management

     

    2.repositories

    运行Maven的时候,Maven所需要的任何构件都是直接从本地仓库获取的。如果本地仓库没有,它会首先尝试从远程仓库下载构件至本地仓库,然后再使用本地仓库的构件。

     

    以下是配置远程仓库,这样做的原因有很多,比如你有一个局域网的远程仓库,使用该仓库能大大提高下载速度,继而提高构建速度

    <repositories> <repository> <id>xxx-repo</id> <name>xx private repo</name> <url>http://xxx:8888/nexus/content/groups/public/</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories>

    <releases><enabled>true</enabled></releases>

    告诉Maven可以从这个仓库下载releases版本的构件

    <snapshots><enabled>false</enabled></snapshots>

    告诉Maven不要从这个仓库下载snapshot版本的构件。

    禁止从公共仓库下载snapshot构件是推荐的做法,因为这些构件不稳定,且不受你控制,你应该避免使用。

    3.Build

    一种<build>被称为Project Build,即是<project>的直接子元素。另一种<build>被称为Profile Build,即是<profile>的直接子元素。

    Profile Build包含了基本的build元素,而Project Build还包含两个特殊的元素,即各种<...Directory>和<extensions>。

    例如:

    <build> <sourceDirectory>src/main/java</sourceDirectory> <testSourceDirectory>src/test/java</testSourceDirectory> <resources> <resource> <directory>src/main/java/resources</directory> <includes> <include>**/*.xml</include> <include>**/*.properties</include> </includes> </resource> </resources> <plugins> <plugin> <artifactId>maven-dependency-plugin</artifactId> <executions> <execution> <phase>package</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <prependGroupId>true</prependGroupId> <outputDirectory>${project.build.directory}/lib</outputDirectory> <includeScope>runtime</includeScope> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <manifest> <mainClass>com.xxx.xxx</mainClass> <addClasspath>true</addClasspath> <classpathLayoutType>custom</classpathLayoutType> <customClasspathLayout>$${artifact.groupId}@$${artifact.artifactId}@$${artifact.version}</customClasspathLayout> </manifest> </archive> </configuration> </plugin> </plugins> </build>

    <resources>

    资源往往不是代码,无需编译,而是一些properties或XML配置文件,构建过程中会往往会将资源文件从源路径复制到指定的目标路径。<resources>给出各个资源在Maven项目中的具体路径。

     

    https://blog.csdn.net/u010010606/article/details/79727438 

    https://www.cnblogs.com/gengaixue/p/6933773.html

    http://maven.apache.org/guides/introduction/introduction-to-repositories.html

    怎么用Maven

    待续,参见:

    https://www.cnblogs.com/whgk/p/7112560.html

    https://www.cnblogs.com/hongwz/p/5456578.html

     

     

     

    最新回复(0)