Java之Maven学习笔记

1.简介:

maven是一个项目管理工具(简单理解为maven可以将你的java开发过程变简单,尤其是导包这种每次都要执行的复杂步骤,maven可以把你构建工程,管理jar包,编译代码,还可以帮你自动运行单元测试,打包,生成报表等)

1.1 Maven的作用:

1.1.1 依赖管理系统

Maven为Java世界引入了一个新的依赖管理系统jar包管理,jar包升级时修改配置文件即可。在Java世界中,可以用groupid、artifactid、version组成的Coordination(坐标)唯一标识一个依赖。

任何基于Maven构建的项目自身也必须定义这三项属性,生成的包可以是jar包,也可以是war包或者jar包。一个典型的依赖引用如下所示:

<dependency>
  <groupId>javax.servlet</groupId>   com.baidu
  <artifactId>javax.servlet-api</artifactId>   ueditor echarts
  <version>3.1.0</version>
</dependency>
坐标属性的理解

Maven坐标为各种组件引入了秩序,任何一个组件都必须明确定义自己的坐标。

groupId

定义当前Maven项目隶属于的实际项目-公司名称。(jar包所在仓库路径)由于Maven中模块的概念,因此一个世纪项目往往会被划分为多个模块。比如Spring是一个实际项目,其对因的Maven模块会有很多,如Spting core,Spring webmvc等。

artifactId

该元素定义实际项目中的一个Maven模块-项目名,推荐的做法是使用实际项目名称作为artifactId的前缀。

version

该元素定义Maven项目当前所处的版本。

1.1.2 多模块构建

我们写项目的时候通常会将一个项目分成多个模块,因为一个项目回非常的大,运行的时候会出一些问题或者启动比较慢,所以一般都会将项目分成多个模块。

在Maven中需要定义一个parent POM作为一组module的聚合POM。在该POM中可以使用标签来定义一组子模块。parent POM不会有什么实际构建产出。而parent POM中的build配置以及依赖配置都会自动继承给子module。

1.1.3 一致的项目结构

不同的编译器的项目结构不同,将项目导入其他编译器的时候会因为目录不一致而出问题。但是Maven项目的结构在所有的编译器中是一致的。

Ant时代大家创建Java项目目录时比较随意,然后通过Ant配置指定哪些属于source,那些属于testSource等。而Maven在设计之初的理念就是Conversion over configuration(约定大于配置)。其制定了一套项目目录结构作为标准的Java项目结构,解决不同ide带来的文件目录不一致问题。

1.1.4 一直的构建模型和插件机制

        <plugin>
          <groupId>org.mortbay.jetty</groupId>
          <artifactId>maven-jetty-plugin</artifactId>
          <version>6.1.25</version>
          <configuration>
            <scanIntervaLseconds>10</scanIntervaLseconds>
            <contextPath>test</contextPath>
          </configuration>
        </plugin>

2.Maven安装与配置:

2.1 下载

image-20220915181211844.png

2.2 配置环境变量

  • 新建MAVEN_HOME,值为Maven的bin目录
  • 将MAVEN_HOME添加到Path中

image-20220915181615687.pngimage-20220915181432927.png

  • 验证是否安装成功:

image-20220915190951898.png

3.Maven的生命周期

如图:

4.Maven常用命令

命令作用
mvn clean清楚编译的class文件,即删除target目录
mvn validate验证项目是否正确
mvn compole编译maven项目
mvn test编译maven项目及测试文件
mvn package编译maven项目及测试文件,并打包
mvn install编译maven项目及测试文件,并打包,并发布到本地仓
mvn deploy部署项目到远程仓库
mvn tomcat:run使用tomcat运行项目

5.Maven工程测试—@ Before、@ After

在测试类中:
@ Before修饰的方法会在测试方法之前自动执行
@ After修饰的方法会在测试方法执行之后自动执行

public class A {
    @Before
    public void before(){
        System.out.println("开始测试");
    }
    @After
    public void after(){
        System.out.println("开始测试");
    }
}

6.依赖冲突调节(自动调节)—最短路径优先原则和最先声明原则:

6.1 依赖冲突:

假设你的项目依赖jar包A,jar包A又依赖jar包B。当添加jar包A时,Maven会把jar包B也自动加入到项目中。这时就可能会产生依赖冲突问题,比如依赖A会引入依赖C,依赖B也会引入依赖C。如果不进行调解则会引入两个依赖C,那么Maven就会发生依赖冲突。

6.2 Maven调解依赖冲突的第一原则——最短路径优先原则:

也就是说项目依赖关系树中路径最短的版本会被使用。例如,假设有几个jar包之间的依赖关系是:
A->B->C->D(2.0)和E->F->D(1.0),如果同时引入A和E,那么D(1.0)会被使用,因为E到D的路径更短。


Spring-context到Spring-aop的路径更短,所以Spring-aop会按照Spring-context的版本引入。

6.3 依赖冲突调节——最先声明原则:

最短路径优先原则不能解决所有问题,比如这样的依赖关系:
A->B->C(1.0)和D->E->C(2.0)
同时引入A和D之后,C(1.0)和C(2.0)的依赖路径长度都为2。此时第一原则将不能解决问题。
Maven调解依赖冲突的第二原则–最先声明原则:
在依赖路径长度相等的前提下,在POM中依赖声明的顺序靠前的会被解析使用。

7.依赖冲突调节(手动调节)——排除依赖和锁定版本

如果不想使用Maven默认的冲突调节方式,有两种方式可以手动进行冲突调节。

7.1 排除依赖

例如:如果想使用Spring-webmvc的Spring-aop包,那么可以让Spring-context引入时排除引入Spring-aop包,这样就可以使用Spring-webmvc包了,写法如下:

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-webmvc</artifactId>
  <version>4.2.4.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>5.2.12.RELEASE</version>
  <exclusions>
    <exclusion>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
    </exclusion>
  </exclusions>
</dependency>

7.2 锁定版本:

在Maven中为某个jar包配置锁定版本后,不考虑依赖的声明顺序和依赖路径,以锁定的版本的为准添加到工程中,此方法在企业开发中常用。以下可以直接配置spring-aop锁定的版本。

<dependencyManagement>
  <dependencies>
    <dependency>
      <grouprd>org.springframework</groupId>
        <artifactrd>spring-
          aop</artifactId>
          <version>4.2.4.RELEASE</version></dependency>
  </dependencies>
</dependencyManagement>

8.Maven聚合开发——聚合关系:

之前我们在Idea中开发时回将项目的所有包放在同一个工程中。
image.png

  • daomain:定义实体类
  • dao:操作数据库
  • service:具体业务逻辑,需要调用dao的方法
  • controller:前后端交互,需要调用service的方法
  • webapp:存放前端资源

假如我们现在写了两个项目分别是电商卖家和电商买家端,两个项目都需要调用service层查询订单的方法。原来的写法如下:

重复编码造成开发效率低。
而使用maven后,我们可以把之前的项目按需拆分成一个个小项目,之后将小项目发布到仓库中,小项目之间也可以使用相互引用,并且在我们的项目中引入需要的小项目即可。

Maven将一个大项目分成一个个小项目开发,最后打包时会将这些小的项目打成一个完整的war包独立运行。

Maven聚合开发总结:

  1. 将原有项目按需拆分成一个个小项目开发
  2. 最后打包时会将小项目打成一个完整的war包独立运行
  3. 聚合开发能提高代码复用率,提升开发效率

9.Maven聚合开发——继承关系:

Maven中的继承是针对于父工程和子工程。父工程定义的依赖和插件子工程都可以直接使用。注意父工程类型一定为POM类型工程。

多继承

在Maven中对于继承采用的也是单继承,也就是说一个子项目只能有一个父项目。但我们可以在配置多继承。

<dependencyManagement>
  <dependencies>
    <!--    父项目a-->
    <dependency>
      <groupId>com.itbaizhan</groupId>
      <artifactId>parent_a</artifactId>
      <version>1.0-SNAPSHOP</version>
      <type>pom</type>
      <!--      引入父类,scope的值为import-->
      <scope>import</scope>
    </dependency>
    <!--    父项目b-->
    <dependency>
      <groupId>com.itbaizhan</groupId>
      <artifactId>parent_b</artifactId>
      <version>1.0-SNAPSHOP</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

10.Maven聚合案例——搭建父工程


创建Maven工程作为父工程,父工程是虚拟工程,不需要写逻辑代码,所以删除父工程的src目录。
由于父工程的依赖和插件子工程都能继承,所以可以将需要的依赖和插件都配置在父工程中。

<packaging>pom</packaging>

<properties>
  <!--  Spring版本  -->
  <spring.version>5.2.12.RELEASE</spring.version>
</properties>
<dependencies>
  <!--  mybatis  -->
  <dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.7</version>
  </dependency>
  <!--  mysql驱动  -->
  <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.26</version>
  </dependency>
  <!--  druid连接池  -->
  <dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.8</version>
  </dependency>
  <!--  MyBatis与Spring的整合包  -->
  <dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>2.0.6</version>
  </dependency>

  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>${spring.version}</version>
  </dependency>
  <!--  springmvc  -->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>${spring.version}</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>${spring.version}</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>${spring.version}</version>
  </dependency>
  <!--  事务  -->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
    <version>${spring.version}</version>
  </dependency>
  <dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.8.7</version>
  </dependency>
  <!--  jstl  -->
  <dependency>
    <groupId>org.apache.taglibs</groupId>
    <artifactId>taglibs-standard-spec</artifactId>
    <version>1.2.5</version>
  </dependency>
  <dependency>
    <groupId>org.apache.taglibs</groupId>
    <artifactId>taglibs-standard-impl</artifactId>
    <version>1.2.5</version>
  </dependency>
  <!--  servlet  -->
  <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
    <scope>provided</scope>
  </dependency>
  <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.0.1</version>
    <scope>provided</scope>
  </dependency>
  <!--  jsp  -->
  <dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>jsp-api</artifactId>
    <version>2.0</version>
    <scope>provided</scope>
  </dependency>
  <!--  junit  -->
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>${spring.version}</version>
  </dependency>
  <!--  log4j  -->
  <dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.12</version>
  </dependency>
</dependencies>

<build>
  <plugins>
    <!--  tomcat插件  -->
    <plugin>
      <groupId>org.apache.tomcat.maven</groupId>
      <artifactId>tomcat7-maven-plugin</artifactId>
      <version>2.1</version>
      <configuration>
        <port>8080</port>
        <path>/</path>
        <uriEncoding>UTF-8</uriEncoding>
        <server>tomcat7</server>
        <systemProperties>
          <java.util.logging.SimpleFormatter.format>%1$tH:%1$tM:%1$tS %2$s%n%4$s: %5$s%6$s%n </java.util.logging.SimpleFormatter.format>
        </systemProperties>
      </configuration>
    </plugin>
  </plugins>
</build>

IDEA中工程project和模块Module有什么区别?

答:没有什么区别,只是新工程会占据一个新窗口,一般写父工程时定义为新工程,写子工程时定义为新模块。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小秋LY

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值