【Java】Maven

2023-12-21 10:55:04

maven

maven是专门用于管理和构建Java项目的工具,它的主要功能有:

  • 提供了一套标准化的项目结构

    • 由于不同ide之间的项目结构是不一样的,所以是不通用的,maven项目则可以在所有ide通用
  • 提供了一套标准化的构建流程

  • 提供了一套依赖管理机制(从此导jar包和管理jar包变得非常方便)

1、maven仓库

本地仓库:本地计算机上的一个目录

中央仓库:由maven团队维护的全球唯一的仓库由于在国外访问速度很慢,而且有一些jar包不是免费开源的,有版权纠纷的不会出现在上边

远程仓库:一般由公司搭建的私有仓库(私服)搭建起来的时候一般会同步所有中央仓库的jar包,这样访问速度会很快。而且自己还可以导入一些其他的jar包(包括有版权的)

当项目中使用坐标引入对应jar包之后,首先会查找本地仓库中是否有对应的jar包,如果有则在项目中直接引用,如果没有则到中央仓库中下载对应的jar包到本地仓库。

如果搭建了远程仓库,则jar包的查找顺序变为:本地仓库->远程仓库->中央仓库。

2、maven的配置以及常用命令

maven的配置上网找。

maven常用命令:

//编译整个项目的java文件,在src下方生成一个target目录存放编译好的文件
mvn compile
//将compile创建的target目录删除
mvn clean
//会自动运行test包下的代码
mvn test
//将Java项目打包,打包的jar包存放在target目录里(没有该目录就先编译生成)
mvn package
//将Java项目打包,打包的jar包放在本地仓库的目录下
mvn install

3、maven坐标

坐标的作用:

  • 定义本项目的位置
  • 将其他项目的jar导入本项目

坐标组成:

在这里插入图片描述

4、依赖管理

使用pom写依赖导入jar包,这些jar包的作用范围是可以限制的。在pom里面使用标签就可以写入作用范围。

在这里插入图片描述

5、分模块开发

将原本的模块分成几个子模块,各个模块之间可以独立维护。这也是微服务的思想。将原本的一个服务分为几个服务,每个服务用一个模块(module)进行开发。

可以预见的是,一个模块不能使用另一个模块的实体、工具类等。那么怎么才能进行使用呢?

作为一个maven项目,pom文件中一定有这个模块的坐标。所以,想要在一个模块中使用另一个模块中的内容,可以在模块的pom文件中导入被引用模块的坐标。

但是直接引入是会报错的。因为:本地仓库里是没有这个模块的!所以,首先要把将要引入的模块打包进本地仓库。

一个模块要引用另一个模块:**在被引入的模块中使用maven的install指令自动打包入本地仓库。**不过在idea之中,右上角点点点就ok了。

6、依赖传递

如果模块A中导入了依赖:模块B。而模块B中导入了mybaits等其他依赖,那么mybatis等等依赖在模块A中也能使用。mybatis等依赖就叫做模块A的间接依赖。模块B就叫做模块A的直接依赖。

依赖传递会出现依赖冲突。假如模块A有一个间接依赖mybatis3.0,又有一个间接依赖mybatis2.0。那么会使用哪个依赖呢?

在这里插入图片描述

idea右边的maven工具栏中有一个查看依赖关系的按钮,可以生成思维导图快速查看依赖关系。

7、可选依赖和排除依赖

可选依赖就是隐藏自己jar包的依赖。(我不想让别人用我的依赖,如此一来,被隐藏的依赖无法成为间接依赖,可以解决依赖冲突问题)。只需要添加<optional>true<optional>即可配置可选依赖。配置可选依赖后,此依赖不再具有传递性。

<dependency>
	<groupId>org.projectlombok</groupId>
	<artifactId>lombok</artifactId>
	<version>1.16.18</version>
	<scope>provided</scope>
    
	<optional>true</optional>
</dependency>

排除依赖就是排除要导入的jar包的某个依赖。(我不想用别人的某个依赖)

<dependency>
	<groupId>org.projectlombok</groupId>
	<artifactId>lombok</artifactId>
	<version>1.16.18</version>
	<scope>provided</scope>
	<exclusions>
		<exclusion>
			<!--在这里写不想要lombok中哪个依赖(^-^-->
			<groupId></groupId>
			<artifactId></artifactId>
		</exclusion>
	</exclusions>
</dependency>

如果一个依赖中的代码被改变了,那么但凡引用到这个依赖的jar包都要进行更新,由此引出了聚合的概念。

8、聚合和继承

聚合

聚合其实就是同时打包。试想一个场景:有两个模块iss_schedule和iss_ucenter,iss_schedule引用了iss_ucenter的坐标。当iss_ucenter更改了某些东西,从版本1变成了版本2,此时iss_schedule如果没有重新打包,它用的还是版本1的iss_ucenter,这会造成错误。

所以就想要实现一个功能:一个模块重新构建了,引用该模块的其他模块必须一起跟着构建。这就是聚合。

为了实现聚合,可以创建一个聚合模块,该模块不具有业务功能,仅有pom文件。把想要聚合的所有模块放入聚合模块之中,并且把这些模块写入聚合模块的pom文件之中(不是依赖引入,而是在<modules></modules>标签内写入要聚合的模块)。同时,聚合模块的打包方式必须是pom

<?xml version="1.0" encoding="UTF-8"?>
<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.iss</groupId>
    <artifactId>intelligent_schedule_system</artifactId>
    <version>1.0-SNAPSHOT</version>
             
    <!-- 聚合模块 -->
    <modules>
        <module>common</module>
        <module>service</module>
    </modules>
    <!-- 打包方式是pom,表示聚合模块 -->
    <packaging>pom</packaging>

聚合的构建顺序:首先构建最底层的模块,再顺着依赖关系一层一层往上构建。

继承

又出现了一个问题:多个模块中如果引入了大量相同的依赖,不仅增加了代码量,而且管理起来很麻烦(要改动某一个依赖的版本需要把所有相同依赖的版本都更新一遍),于是就有了继承的思想。

把多个模块中相同的依赖都抽取出来,然后创建一个父模块,把这些依赖放入父模块之中。Java中,继承是在子类中实现的,maven中也是一样,在子模块中使用<parent></parent>声明它有一个父模块。

<?xml version="1.0" encoding="UTF-8"?>
<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">
             
    <!--这样一来,这个模块就可以使用intelligent_schedule_system这个父模块中的依赖了-->
    <parent>
        <artifactId>intelligent_schedule_system</artifactId>
        <groupId>com.iss</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

继承虽好,但是有一个小问题。如果模块1是模块2、模块3、模块4的父模块,模块2、模块3共用一些依赖,提到父模块之中去;模块3、模块4共用一些依赖,也提到父模块之中去。如此一来,由于继承,模块2会有模块4的依赖,不是很好。

可以在父模块中使用<dependencyManagement></dependencyManagement>代替<dependency></dependency>即可解决这个问题。注意,父模块在dependency中的所有依赖会全部传递到所有子模块中去,而dependencyManagement中的依赖,如果子模块不引入坐标(不需要写版本),是不会传递到子模块中去的。

以下代码中,没有版本号的依赖就是存在于父模块service之中的dependencyManagement中的依赖。

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <parent>
        <artifactId>service</artifactId>
        <groupId>com.iss</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>schedule_service</artifactId>

    <dependencies>
        <!--springboot web的起步依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--邮件发送-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-email</artifactId>
            <version>1.4</version>
        </dependency>
        <!--mybatis-plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>
        <!--mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>2.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
        </dependency>
    </dependencies>

</project>

通常,会选择父模块作为聚合模块。聚合和继承其实都是为了更好地管理依赖。

9、通过属性管理依赖版本

属性可以实现对依赖的统一管理。比方说spring那么多个依赖,每次导入都要导入同样的版本。如果要更新版本,一个一个去改很麻烦。可以通过设置属性对同类依赖的版本进行统一管理。(属性其实就有点儿变量的味道)。

直接在pom文件中写属性<properties></properties>,然后要到对应的依赖那里的版本用${什么.version}替换版本。

这样一来,直接对属性进行管理,就可以实现对所有jar包的版本进行管理了。

我在后面其实也有用到属性。

<?xml version="1.0" encoding="UTF-8"?>
<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.iss</groupId>
    <artifactId>intelligent_schedule_system</artifactId>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>common</module>
        <module>service</module>
    </modules>
    <packaging>pom</packaging>

    <!--父依赖是springboot的起步依赖-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.9.RELEASE</version>
        <relativePath/>
    </parent>

    <properties>
        <mybatis-plus.version>3.0.5</mybatis-plus.version>
        <velocity.version>2.0</velocity.version>
        <swagger.version>2.7.0</swagger.version>
        <spring-cloud.version>Hoxton.SR10</spring-cloud.version>
        <mysql.version>8.0.18</mysql.version>
        <junit.version>4.12</junit.version>
        <alibaba-dependencies.version>2.2.5.RELEASE</alibaba-dependencies.version>
        <fastjson.version>1.2.28</fastjson.version>
        <jwt.version>0.7.0</jwt.version>
        <slf4j.version>1.7.30</slf4j.version>
        <joda-time.version>2.3</joda-time.version>
        <aliyun-sdk-oss.version>3.15.1</aliyun-sdk-oss.version>
        <poi.version>5.2.2</poi.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <!--mybatis-plus-->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>${mybatis-plus.version}</version>
            </dependency>
            <!--mysql-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>
            <!-- velocity 模板引擎, Mybatis Plus 代码生成器需要 -->
            <dependency>
                <groupId>org.apache.velocity</groupId>
                <artifactId>velocity-engine-core</artifactId>
                <version>${velocity.version}</version>
            </dependency>
            <!--swagger-->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger2</artifactId>
                <version>${swagger.version}</version>
            </dependency>
            <!--swagger ui界面-->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger-ui</artifactId>
                <version>${swagger.version}</version>
            </dependency>
            <!--junit-->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
            </dependency>
            <!--Spring Cloud-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--阿里巴巴cloud依赖库-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${alibaba-dependencies.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--阿里巴巴的fastjson-->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>${fastjson.version}</version>
            </dependency>
            <!-- JWT令牌,登录时需要用到 -->
            <dependency>
                <groupId>io.jsonwebtoken</groupId>
                <artifactId>jjwt</artifactId>
                <version>${jwt.version}</version>
            </dependency>
            <!--日志-->
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>${slf4j.version}</version>
            </dependency>
            <!--阿里云的oss存储-->
            <dependency>
                <groupId>com.aliyun.oss</groupId>
                <artifactId>aliyun-sdk-oss</artifactId>
                <version>${aliyun-sdk-oss.version}</version>
            </dependency>
            <!--joda-time日期格式转换-->
            <dependency>
                <groupId>joda-time</groupId>
                <artifactId>joda-time</artifactId>
                <version>${joda-time.version}</version>
            </dependency>
            <!--用来操作03年xls格式的excel-->
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi</artifactId>
                <version>${poi.version}</version>
            </dependency>
            <!--07年的 .xlsx-->
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-ooxml</artifactId>
                <version>${poi.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

10、通过属性管理resource包下的配置文件

利用pom文件的<properties></properties>对配置文件进行管理。其实直接在配置文件中写也是非常方便的,而且还清楚明了。

这一部分内容感觉有点儿多此一举,用到再学。

11、版本

在这里插入图片描述

12、maven多环境开发

maven提供配置多种环境的设定,帮助开发者在使用过程中快速切换环境。

	<profiles>
        <profile>
            <!--开发环境-->
            <id>env_dev</id>
            <activation>
                <!--默认启动该环境-->
                <activeByDefault>true</activeByDefault>
            </activation>
            
            <properties></properties>
            <dependencies></dependencies>
            <dependencyManagement></dependencyManagement>
        </profile>
        <profile>
            <!--生产环境-->
            <id>env_prod</id>
            <properties></properties>
            <dependencies></dependencies>
            <dependencyManagement></dependencyManagement>
        </profile>
        <profile>
            <id>测试环境</id>
            <properties></properties>
            <dependencies></dependencies>
            <dependencyManagement></dependencyManagement>
        </profile>
    </profiles>

之后,使用mvn -install -P env_dev就可以将开发环境打包。通过最后的参数可以很方便地控制要打包哪一个环境。

文章来源:https://blog.csdn.net/weixin_52808620/article/details/135117511
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。