【Maven】 基于Java的 Maven项目对象模型认识

Maven介绍

Maven 是一个项目管理和 综合工具,Maven 提供了开发人员构建一个完整的生命周期框架,开发团队可以自动完成项目的基础工具建设,Maven 使用标准的目录结构 和 默认构建生命周期

Maven 是什么?

它是一个 Apache 的开源项目,主要服务于基于 Java 平台的项目构建,依赖管理 和项目信息管理。

配置 maven 的环境变量

右击此电脑,选择属性,打开高级系统设置,选择环境变量,在系统变量找到 path ,点击编辑,将 maven 的安装路径添加上即可

maven 的目录说明

  • bin:该目录下存放的是执行文件,命令
  • boot:该目录存放的是 maven 启动时需要的 jar 包
  • conf: 存放一个重要的配置文件,maven 的核心配置文件/全家配置文件—> settings.xml 文件

自定义安装 maven

在 maven.Apache 官网中下载到 meven.zip 文件,解压完成后,需要配置环境变量,同时需要一个 .m2 文件夹,如果没有该文件夹,我们在 cmd 命令 执行 mvn help:system 命令,执行完该命令会发现目录下自动创建了.m2 文件目录

Maven 仓库

Maven 仓库是基于简单文件系统存储的,集中化管理 Java API 资源(构件)的一个服务

仓库中的任何一个构件都有其唯一的坐标,根据这个坐标可以定义其在仓库中的唯一存储路径,得益于 Maven的坐标机制,任何 Maven 项目使用任何一个构件的方式都是完成相同的

Maven 可以在某个位置统一存储所有Maven 项目共享的构件,这个统一的位置就是仓库,项目构建完毕后生成的构件也可以安装或部署到仓库中,供其他项目使用

对于 Maven 来说,仓库分为两类,本地仓库和远程仓库

远程仓库

不在本机中的一切仓库,都是远程仓库: 分为中央仓库和本地私服仓库

远程仓库指通过各种协议如:file:// 和 http://访问的其他类型的仓库,这些仓库可能是第三方搭建的真实的远程仓库,用来提供它们的构件下载(例如 repo.maven.apache.org和uk.maven.org是Maven的中央仓库)。其他 远程 仓库可能是你的公司拥有在建立在文件或HTTP服务器的内部仓库(不是Apache 的那个中央仓库,而是你们公司的私服,你们自己在局域网中搭建的 maven仓库),用来在开发团队间共享私有构件和管理发布的.

默认的远程仓库使用的 Apache 提供的中央仓库 http://mvnrepository.com

本地仓库

本地仓库指本地的一份拷贝,用来缓存远程下载,包含你尚未发布的临时构件

配置

在 settions.xml 文件中配置本地仓库

打开 setting.xml 配置文件

<localRepository>本地仓库在硬盘中的位置localRepository>

在 settions.xml 文件中配置镜像仓库

如果仓库 A 可以提供仓库 B 存储的所有内容,那么就可以认为A是B的镜像。例如:在国内直接连接中央仓库下载依赖,由于一些特殊原因下载速度非常慢。这是,我们可以使用阿里云提供的 镜像 http://maven.aliyun.com.nexus/content/grounps/public/来替换中央仓库 http://repol.maven.ort/maven2/ 修改 maven 的 setting.xml 文件

<mirror>
	
    <id>nexus-aliyunid>
    
    <mirrorOf>centralmirrorOf>
    
    <name>Nexus aliyunname>
    
    <url>http://maven.aliyun.com/nexus/content/grounps/public/url>
mirror>

优先级别

本地仓库 --> 到配置文件中指定的仓库中 --> 如果没有配置镜像仓库,就会去到中央仓库中找(如果配置了镜像仓库就会到镜像仓库中找,如果镜像仓库中没有,再去默认的中央仓库)

JDK的配置

如果你的 idea 中有多个 jdk的时候,就需要指定你的编译和运行的 jdk:

在 settings.xml 中配置

<profile>
    
	<id>jdk1.8id>
    
    <activation>
    	<activeByDefault>trueactiveByDefault>
        <jdk>1.8jdk>
    activation>
    <properties>
        
        <maven.compiler.source>1.8maven.compiler.source>
        <maven.compiler.target>1.8maven.compiler.target>
    	<maven.compiler.compilerVersion>1.8maven.compiler.compilerVersion>
    properties>
profile>

配置的前提是 idea 中要有对应的 jdk

maven 工程类型

POM工程

POM工程是逻辑工程 ,用在父级工程或聚合工程中,用来做 jar包的版本控制

该工程更多是起到管理作用,该工程中不能写逻辑性代码和业务性代码

JAR 工程

将会打包成 jar,用作jar包使用,即常见的本地工程 — > Java Project

WAR 工程

将会打包成 war,发布在服务器上的工程

maven 项目的目录结构

src/mian/java:该目录下存储的是 Java源代码

src/mian/resources:存储主要的资源文件,比如 xml 配置文件和properties 文件

src/test/java:存储测试用的类,比如 JUNIT的测试一般就放在这个目录下面,因为测试类本身就不属于项目的,所以放在任何一个包下都显得很尴尬,所以 maven 专门创建了一个测试包,用于存放测试的类

src/test/resources:可自己创建存储测试环境使用资源文件

src:包含了项目所有的源代码和资源文件,以及其他项目相关的文件

target:编译后内容放置的文件夹 如 .class文件

pom.xml:是Maven的配置文件,配置项目和项目之间的关系,包含配置依赖关系等等

在 Maven 创建的项目中的包名不要随便更改

POM 模式-Maven 工程关系

Maven 工具基于POM(Project Object Model 项目对象模型)模式实现的,在Maven中每个项目都相当于是一个对象,对象(项目)和对象(项目)之间是由关系的。关系包含了:依赖,继承,聚合,实现 Maven 项目可以更加方便的实现到 jar 包,拆分项目等效果

依赖关系

即A工程开发或运行过程中需要B工程提供支持,则代表 A工程依赖B工程

在这种情况下,需要在A项目的pom.xml文件中添加下属配置定义依赖关系

通俗理解:就是导 jar 包

B 工程可以是自己的项目打包后的 jar 包,也可以是中央仓库的 jar 包

如何注入依赖

在 pom.xml 文件,根元素 project 下的depencies 标签中,配置依赖信息,内可以包含多个依赖,每个依赖 dependence 标签都应该包含以下元素:groupld,artifactld,version:依赖的基本坐标,对应任何一个依赖来说,基本坐标是最要的,Maven 根据坐标才能找到需要的依赖

如:

<depencies>
	<dependence>
    	<grounpId>org.mybatisgroupld>
        <artifactId>mybatisartifactId>
        <version>3.5.4version>
    dependence>
depencies>

好处:

  • 省去了手动导入jar 报道操作,更加的便捷
  • 可以帮我们解决 jar 包 冲突的问题

特性—依赖的传递性

传递性依赖是 Maven2.0的新特性。假设你的项目依赖于一个库,而这个库有依赖于其他库。你不必自己去找出所有这些依赖,只需要加上你直接依赖的库,Maven 会隐式的把这些库间接依赖的库也加入到你的项目中。这个特性是靠解析从远程仓库中获取的依赖库的项目实现的。一般的,这些项目的所有依赖都会加入到项目中,或者从父项目中继承,或者通过传递性依赖

如果 A依赖了B,那么C依赖A时会自动把 A和 B都导入进来

创建A项目后,选择IDEA最右侧 Maven 面板 lifecycle,双击 install 后,其他项目就可以通过坐标引用此项目

原则

第一原则:最短路径优先原则

最短路径优先,意味着 项目依赖关系树中路径最短的版本会被使用

例如:假设A,B,C之间的依赖关系是 A -> B -> C -> D(2.0) 和 A -> E --> D(1.0),那么D(1.0)会被使用,因为 A 通过 E 到 D 的路径更短

第二原则:最先声明原则

依赖路径长度是一样的时候,第一原则不能解决所有问题,比如这样的依赖关系 A --> B --Y(1.0), A --> C --> Y(2.0),Y(1.0)和Y(2.0)的依赖路径的长度是一样的。那么到底谁会被解析使用呢?在 maven2.0.8即之前的版本中,这是不确定的,但是在 maven2.0.9开始,为了尽可能的避免构建的不确定性,maven 定义了依赖调解的第二原则:第一声明者优先,在依赖路径长度相等的前提下,在POM中依赖声明的顺序决定了谁会被解析使用,顺序最靠前的那个依赖优胜

依赖范围

依赖范围就决定了你依赖的坐标,在什么情况下有效,什么情况下无效:

  • compile : 这是默认范围。如果没有指定,就会使用该依赖范围。表示该依赖在编译和运行时都生效。

    <dependencies>
    	<dependency>
        	<grounpId>org.mybatisgrounpId>
            <artifactId>mybatisartifactId>
            <version>3.5.4version>
    		<scope>compilescope>
        dependency>
    dependencies>
    
  • provided:以提供依赖范围,使用此依赖范围的 Maven 依赖。典型的例子是 servlet-api,编译和测试测试项目的时候需要改依赖,但在运行项目的时候,由于容器已经提供,就不需要 Maven 重复的引入一遍

  • runtime: 表示编译时不需要生效,而只在运行时生效,典型的例子是 JDBC 驱动,项目主代码的编译只需要 JDK 提供的 JDBC 接口,只有在执行测试或运行项目时才需要实现上述接口的具体JDBC驱动

  • system:系统范围和provided 类似,不过你必须显示的指定一个本地系统路径的JAR,此类依赖应该一直有效,Maven 也不会去仓库中寻找它,但是使用 system 范围依赖时必须通过 systemPath 元素显示的指定依赖文件的路径

    <dependencies>
    	<dependency>
        	<grounpId>org.mybatisgrounpId>
            <artifactId>mybatisartifactId>
            <version>3.5.4version>
    		<scope>systemscope>
            <systemPath>
            	
            systemPath>
        dependency>
    dependencies>
    
  • test:表明使用此依赖范围的依赖,只在编译测试代码和运行测设代码时候需要,应用的正常运行不需要此类依赖,典型的例子就是JUnit,他只有在编译测试代码及运行测试的时候才需要,Junit 的 jar 就在测试阶段用就行了,导出项目的实话没有必要把 Junit 的东西导出了,所以在 Junit 坐标下加入scope-test

  • Import import 范围只适用于 pom 文件中的 部分,表明指定的 POM必须使用 部分的依赖。注意:import 只能用在 dependencyManagement 的 scope 里



	<groupId>com.gxgroupId>
    <artifactId>MavenDemoartifactId>
    <version>1.0-SNAPSHOTversion>
<proerties>
	<banben>3.5.4banben>
proerties>
<dependencyManagement>
	<dependencies>
	<dependency>
    	<grounpId>org.mybatisgrounpId>
        <artifactId>mybatisartifactId>
        <version>${banben}version>
		<scope>importscope>
    dependency>
dependencies>
dependencyManagement>


<dependencies>
    
	<parent>
    	<groupId>com.gxgroupId>
    	<artifactId>MavenDemoartifactId>
    	<version>1.0-SNAPSHOTversion>
        <relativePath>
        	
        relativePath>
    parent>
dependencies>

继承关系

如果 A 工程继承工程 B,则代表A 工程默认 依赖 B 工程的所有资源,且可以应用 B 工程中定义的所有资源信息

被继承的工程只能时 POM 工程

注意:在父工程放在 中的内容时不被子项目继承,不可以直接使用

和 即可,(注意:如果子项目不希望使用父项目的版本,可以明确配置version)

聚合关系

当我们开发的工程拥有两个以下的模块,每个模块都是一个独立的功能集合,比如大学系统中拥有搜索平台,学习平台,考试平台等,开发的时候每个平台都可以独立编译,测试,运行,这个时候我们就需要一个聚合工程

在创建聚合工程过程中,总的工程必须是一个POM 工程(聚合工程必须是一个pom类型的项目,jar 项目 war 项目是没有办法做聚合工程的),各个子模块可以是任意类型模块

实际上聚合一个 pom 工程时,也是继承了这个 pom 工程

聚合包含了继承的特性

聚合时多个项目的本质还是一个项目,这些项目被一个大的父项目包含,且这时父项目类型为 pom 类型,同时在父项目的 pom.xml 中出现 表示包含所有的子模块

常见插件

编译器插件

通过编译器插件,我们可以配置使用的 jdk 或者编译器的版本

在 settings.xml 文件中配置的是全局编译器插件

我们可以通过编译器插件配置当前项目中使用的是什么版本的编译器插件


<build>
	<plugins>
        
    	<plugin>
            
	  		<groupId>org.apache.maven.pluginsgroupId>
	  		<artifactId>maven-compiler-pluginartifactId>
            <version>3.1version>
            <configuration>
                
            	<source>1.8source>
                
                <target>1.8target>
                <encoding>utf-8encoding>
            configuration>
	  	plugin>
    plugins>
build>

拷贝插件

Maven 在打包时默认只将 src/main/resources 里的配置文件拷贝到项目中并做打包处理,而非 resource 目录下的配置文件在打包时不会添加到项目中

<build>
    
    <resource>
		<directory>src/main/resourcesdirectory>
    resource>
    
    
	<resource>
		<directory>src/main/resourcesdirectory>
		<includes>
            
			<include>*.propertiesinclude>
			<include>*.xmlinclude>
			<include>config/*.xmlinclude>
			<filtering>truefiltering>
		includes>
	resource>
build>

Tomcat 插件

 
		<plugin>
		    <groupId>org.apache.tomcat.mavengroupId>
		    <artifactId>tomcat7-maven-pluginartifactId>
		    <version>2.2version>
		    <configuration>
                <--端口控制-->
				<port>8080port>
                <--项目路径控制意味着http://localhost:8080/abc-->
				<path>/abcpath>
                <--编码-->
				<uriEncoding>UTF-8uriEncoding>
			configuration>
		plugin>

Maven 中的常见命令

  • install : 本地安装,包含编译,打包,安装到本地项目

    • 编译 - javac: 打包 jar,将 java 代码打包为 jar 文件
    • 安装到本地仓库 ,将打包的 jar 文件,保存到 本地仓库目录中
  • clean : 消除已编译信息。删除工程中的 target 目录

  • compile : 只编译,javac 命令

  • package: 打包,包含编译,打包两个功能

  • package 和 install 的区别:

    • package 命令完成了项目编译,单元测试,打包功能,但没有把打包好的可执行 jar 包 (war 包或其他形式的包) 部署到本地 maven 仓库和 远程 maven私服仓库
    • install 命令完成了项目编译,单元测试,打包功能,同时把打包好的可执行 jar 包 (war 包或其他形式的包)部署到本地 maven 仓库,但没有部署到远程 maven 私服仓库

你可能感兴趣的:(Java,java,maven,学习)