Maven基本概念与核心配置

版权声明:本文为博主原创文章,转载请注明出处。如有问题,欢迎指正。 https://blog.csdn.net/UncleMoveBrick/article/details/83688814

Maven的安装与核心配置

1、安装Maven

  1)、官网下载 Maven (http://maven.apache.org/download.cgi);
  2)、解压指定目录;
  3)、配置环境变量;
配置环境变量
配置path
  4)、使用mvn -version查看Maven是否安装成功。
验证Maven是否安装成功

2、编译

  1)、创建Maven的一个项目名叫demo-maven;
  2)、在demo-maven目录下创建src文件夹,在src文件夹内创建一个Hello.java文件,文件内容如下:

public class Hello {
	public static void main(String args[]){
		System.out.println("Hello World!");
	}
}

  3)、在demo-maven目录下创建并编写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代表pom.xml文件的版本,二不是maven的版本-->
	<modelVersion>4.0.0</modelVersion>
	<!--
		每一个Maven项目都有一个坐标,它的坐标由三个点组成:
		groupId、artifactId和version。
		我们Maven的项目名叫什么artifactId节点内的值就是什么
	-->
	<groupId>demo</groupId>
	<artifactId>demo-maven</artifactId>
	<version>1.0.SNAPSHOT</version>
</project>

  4)、进入demo-maven目录使用mvn compile命令进行编译;
mvn compile命令
  从这张图片可以看出时编译完成并成功了,但是上面显示No sources to compile,意思是说没有任何的class文件被编译,在demo-maven文件夹和src文件夹内没有任何的class编译文件。但是编译又是成功的,这又是为什么呢?其实在我们刚刚的pom.xml文件里面并没有指定java的类文件路径,也没有指定输出的class文件的路径在哪里。我们是不是需要在pom.xml文件里面配置这两个文件的路径呢?其实是不用配置的,在这里,maven使用了一个在软件设计上的一个设计思想,叫约定大于配置。在这个里面maven已经指定好了已src/main/java这个目录下的文件就代表着java的类文件。这么做的好处在于省去了在pom.xml文件中指定java类文件路径的配置了,规范了我们开发工程的结构。
  现在我们在demo-maven的目录下创建好src/main/java这个目录,再将Hello.java文件移动到src/main/java这个路径下,然后再demo-maven目录下使用mvn compile命令编译,如下图所示:
编译
  我们重新运行编译命令后将class文件编译到了F:\mavens\demo-maven\target\classes这个目录,这个编译目录同样的也是采用的约定大于配置的一种软件设计理念。

3、打包

  Maven不止能进行编译,还能进行打包,我们可以使用mvn package命令将项目打成一个jar包或者一个war包,如图:
打包
  我们在执行mvn package的时候并没有执行mvn compile编译命令,为什么能打包成功呢?因为我们执行打包命令的时候,maven顺便将编译命令也执行完成了。

4、Maven依赖管理

  在没有Maven之前 ,我们都是把jar包放到项目的src/lib文件夹下面。这样做的缺点就是项目特别大,并且不利于管理jar包,如果jar包有冲突就更加麻烦了。后来Maven就引入了一个jar包的依赖管理,这样就不需要将jar包放到lib目录下了,而是把jar包放到了本地仓库下面,如果本地仓库没有这个jar包,Maven就会自动的去远程仓库下载,这样管理依赖包的时候就特别方便。
Maven下载jar包顺序如图:
在这里插入图片描述
  Maven会默认将下载下来的jar放到C盘,并且是去访问国外的Maven中心去下载jar,所以这就导致C盘可用容量越来越小并且下载jar的速度也很慢。我们可以在maven的settings.xml文件内配置maven将jar包存放路径和阿里云私服。将以下配置内容放到settings.xml文件内即可:

<localRepository>E:/mvn-resp</localRepository>

<mirror>
    	<id>alimaven</id>
        <mirrorOf>central</mirrorOf>
        <name>aliyun maven</name>
        <url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
</mirror>

二、Maven核心配置

1、项目 依赖(内部、外部)

  项目依赖是指maven通过依赖传播、依赖优先原则、可选依赖、排除依赖、依赖范围等特性来管理项目的第三方依赖。
  1)、依赖传播特性:
  我们的项目中基本上会依赖第三方组件,而第三方组件又会依赖其它组件遇到这种情况Maven会将依赖网络中的所有节点全部加载进项目的classpath,这就是依赖的传播特性。如果我们的项目依赖了Spring-webmvc,Spring-webmvc依赖了commons-loggin,那么我们在添加Spring-webmvc依赖后也会将commons-logging的依赖也添加进来。
  2)、最短路径优先原则:
  基于依赖传播特性,导致整个依赖网络会很复杂,难免会出现相同组件不同版本的情况。Maven此时会基于依赖优先原则选择其中一个版本。
  第一原则:最短路径优先原则,在下面这个Spring-webmvc这个依赖通过依赖网络图可以看到Spring-webmvc是依赖了commons-logging的,如图:
在这里插入图片描述

<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>4.0.4.RELEASE</version>
</dependency>

我们在pom.xml内再直接加入1.2版本的commons-logging的依赖,maven最终是通过最短路径优先原则直接引入1.2版本的commons-logging的依赖,因为项目是直接依赖的1.2版本的,1.3版本的commons-logging是通过SpringMVC的jar去依赖的。

<dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <version>1.2</version>
</dependency>

  3)、相同路径下配置在前的优先;
  我们建立一个Maven的工程来演示一下这个原则,新建的一个Maven父工程demo-parent,在这个父工程内新建两个子工程demo-server和demo-client,其中demo-server工程依赖了demo-client和spring-webmvc4.0.4,spring-webmvc又依赖了springweb4.0.8,demo-client依赖了springweb4.3.8,那么最终maven会引入springweb哪个版本的依赖呢?工程图如下:
在这里插入图片描述
  在这个情况下maven引入的是spring-web4.3.8版本的依赖,因为demo-client配置在spring-webmvc的前面,所以引入的是4.3.8版本的spring-web:
在这里插入图片描述
  3)、可选依赖:
  可选依赖表示这个依赖不是必须的。通过在 <dependency> 添加<optional>true</optional> 表示,默认是不可选的。可选依赖不会被传递。
  4)、排除依赖:
  排除指定的间接依赖。通过配置 <exclusions> 配置排除指定组件,举例如下:

 <dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-webmvc</artifactId>
	<version>4.0.4.RELEASE</version>
	<!--排除当前对springweb的依赖-->
	<exclusions>
		<exclusion>
			<groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
        </exclusion>
   </exclusions>
</dependency>

  5)、依赖范围:
  像junit这种组件,我们只有在运行测试用例的时候要去用到,这就没有必要在打包的时候把junit.jar构建到项目中了,我们可以通过Maven的依赖范围配置<scope>来达到这种目的。Maven一共支持几种依赖范围:
  compile(默认): 编译范围,编译和打包都会依赖。
  **provided:**提供范围,编译时依赖,但不会打包进去。
  **runtime:**运行时范围,打包时依赖,编译不会。
  **test:**测试范围,编译运行测试用例依赖,不会打包进去。
  **system:**表示由系统中CLASSPATH指定。编译时依赖,不会打包进去。配合<systemPath> 一起使用。system除了可以引用系统classpath中的包,也可以用于引入系统非maven收录的第三方jar,做法是将第三方jar放到项目的lib目录下,然后配置相对应的路径,但是因为system不会打包进去所以需要配合maven-dependency-plugin插件一起使用。当然推荐大家通过将第三方jar手动install到仓库。

<!-- system 的通常使用方式-->
<dependency>
	<groupId>com.sun</groupId>
	<artifactId>tools</artifactId>
	<version>${java.version}</version>
	<scope>system</scope>
	<optional>true</optional>
	<systemPath>${java.home}/../lib/tools.jar</systemPath>
</dependency>
<!-- system 另外使用方式 ,将工程内的jar直接引入 -->
<dependency>
    <groupId>jsr</groupId>
    <artifactId>jsr</artifactId>
    <version>3.5</version>
    <scope>system</scope>
    <optional>true</optional>
    <systemPath>${basedir}/lib/jsr305.jar</systemPath>
</dependency>
<!-- 通过插件 将system 的jar 打包进去。 -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>2.10</version>
    <executions>
        <execution>
            <id>copy-dependencies</id>
            <phase>compile</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
				<outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/lib</outputDirectory>
                <includeScope>system</includeScope>
                <excludeGroupIds>com.sun</excludeGroupIds>
            </configuration>
        </execution>
    </executions>
</plugin>

将第三方jar手动加入仓库命令:mvn install:install-file -Dfile=abc_client_v1.20.jar -DgroupId=tuling -DartifactId=tuling-client -Dversion=1.20 -Dpackaging=jar

2、项目聚合与继承

  1)、聚合
  是指将多个模块整合在一起,统一构建,避免一个一个的构建。聚合需要一个父工程,然后使用<moduls>进行配置其中对应的是子工程的相对路径,项目聚合的优点在于指需要对父项目进行打包,不需要对子模块一个一个的打包了,这就节省了我们的开发时间,moduls配置如下:

<modules>
        <module>demo-server</module>
        <module>demo-client</module>
</modules>

  2)、项目继承
  继承是指子工程直接继承父工程 当中的属性、依赖、插件等配置,避免重复配置,并且这三个配置子工程都可以进行重写,重写之后以子工程的为准。项目继承使用<parent>配置,如下:

<parent>
        <groupId>demo-parent</groupId>
        <artifactId>demo-parent</artifactId>
        <version>1.0-SNAPSHOT</version>
</parent>

  3)、依赖管理
  通过继承的特性,子工程是可以间接依赖父工程的依赖,但多个子工程依赖有时并不一至,这时就可以在父工程中加入 声明该功程需要的JAR包,然后在子工程中引入,如下所示:

<!-- 父工程中声明 junit 4.12 -->
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>
</dependencyManagement>
<!-- 子工程中引入 -->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
</dependency>

3、项目构建配置

  基本配置示例:

<defaultGoal>package</defaultGoal>
<directory>${basedir}/target2</directory>
<finalName>${artifactId}-${version}</finalName>

  基本配置示例说明:
  defaultGoal:执行构建时默认的goal或phase,如jar:jar或者package等
  directory:构建的结果所在的路径,默认为${basedir}/target目录
  finalName:构建的最终结果的名字,该名字可能在其他plugin中被改变
  在pon.mxl文件的<build>节点下可以配置<resources>,这个<resources>是配置的一个打包的一个源,在默认情况下是在src/main/java目录下只会打包.java文件,但是有的时候我们会把MyBatis的一些orm的配置文件也写到我们的dao层里面,这个时候使用默认的方式打包肯定是把那个orm的配置文件打不进去的。配置如下:

<resources>
   <resource>
      <directory>src/main/java</directory>
      <includes>
         <include>**/*.MF</include>
         <include>**/*.XML</include>
      </includes>
      <filtering>true</filtering>
   </resource>
   <resource>
      <directory>src/main/resources</directory>
      <includes>
         <include>**/*</include>
         <include>*</include>
      </includes>
      <filtering>true</filtering>
   </resource>
</resources>

说明:
  resources:build过程中涉及的资源文件。
  targetPath:资源文件的目标路径。
  directory:资源文件的路径,默认位于${basedir}/src/main/resources/目录下。
  includes:一组文件名的匹配模式,被匹配的资源文件将被构建过程处理。
  excludes:一组文件名的匹配模式,被匹配的资源文件将被构建过程忽略。同时被includes和excludes匹配的资源文件,将被忽略。
  filtering: 默认false ,true 表示 通过参数对资源文件中 的${key} 在编译时进行动态变更。

猜你喜欢

转载自blog.csdn.net/UncleMoveBrick/article/details/83688814