maven学习系列篇

maven

1、maven核心

先介绍一下核心:使用maven管理项目。具体分为:依赖管理项目构建分模块开发

依赖管理: maven对项目的第三方构件(jar包)进行统一管理。向工程中加入jar包不要手工从其它地方拷贝,通过maven定义jar包的坐标,自动从maven仓库中去下载到工程中。

注意:如果jar包A依赖jar包B,那么在导入jar包A的时候,maven会自动导入jar包B进来;

项目构建: maven提供一套对项目生命周期管理的标准,开发人员、和测试人员统一使用maven进行项目构建。项目生命周期管理:编译、测试、打包、部署、运行。

maven对工程分模块构建,提高开发效率。(稍后介绍)

1.1、maven坐标

Maven的一个核心的作用就是管理项目的依赖,引入我们所需的各种jar包等。为了能自动化的解析任何一个Java构件,Maven必须将这些Jar包或者其他资源进行唯一标识,这是管理项目的依赖的基础,也就是我们要说的坐标。包括我们自己开发的项目,也是要通过坐标进行唯一标识的,这样才能才其它项目中进行依赖引用。坐标的定义元素如下:

groupId:项目组织唯一的标识符,实际对应JAVA的包的结构 (一般写公司的组织名称 eg:com.jidong,com.alibaba)
artifactId: 项目的名称
version:定义项目的当前版本

例如:要引入druid,只需要在pom.xml配置文件中配置引入druid的坐标即可:

<!--druid连接池--> 
<dependency> 
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId> 
    <version>1.0.9</version> 
</dependency>

maven就会帮我们从仓库中下载对应的jar包到我们的项目中来,而不在需要自己手动来进行导包到自己的项目中。

1.2、maven命令作用

clean 用来清除编译后的文件(target文件夹里面的)【一般清缓存】;

compile 编译,将.java文件编译成为.class文件;

test 执行单元测试,注意:在idea中执行时,可以看一下工作空间选择的是否是不是对的,执行mvn test之后,可以看到单元测试有运行结果。

package 打包 (javaSe-->jar, javaweb-->war),通过执行这个即可,以后没有必要的话不需要执行install命令再来安装到本地仓库中去了

install 把项目打包之后安装到本地仓库

1.3、生命周期

具体的maven周期可以分为两个:cleanclean之外的,分为两个生命周期。

当我们执行了install 也会执行compile test package

那么这里有时候就会产生问题,这里没有将旧的jar包清除掉,所以我们应该直接执行mvn clean install命令,先将缓存清除掉,然后再来进行安装。

那么所有的声明周期都会来进行执行。

1.4、maven依赖管理

导入依赖坐标,无需手动导入jar包就可以引入jar。在pom.xml中使用标签引入依赖。做项目/工作里面 都有整套的依赖的, 不需要背诵的.

去Maven官网找, 赋值,粘贴. http://mvnrepository.com/

导入几个依赖来查看一下:

导入junit测试类,那么在test目录下的类中就可以来进行测试了,不需要额外的来引入包:

<dependency> 
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version> 
    <scope>test</scope> 
</dependency>

对应的测试类是:

public class DemoTest {

    @Test
    public void test1(){
        System.out.println("----->hello,world<-----");
    }
}

导入servlet依赖,创建Servlet,但是发现报错,原因是没有导入Servlet的坐标依赖;

只需要引入对应的servlet依赖即可,那么代码就不会报错。

<dependency> 
    <groupId>javax.servlet</groupId> 
    <artifactId>javax.servlet-api</artifactId> 
    <version>3.1.0</version>
    <scope>provided</scope> 
</dependency>

1.4.1、依赖范围

maven中不同的命令对应的依赖范围是不同的。

依赖范围 对于编译 对于测试 对于运行时 案例
compile fast-json
test × × Junit
provided × servlet
runtime × JDBC驱动
  • compile,在编译、测试以及运行的时候都需要;默认是compile,可以将其打包成war包或者是jar包;

  • test,只需要在测试的时候发挥其作用即可,不需要在编译和运行时发生任何作用;不会达到war包

  • provided,因为其他组件已经自带了,只是需要在编译和测试的时候来使用一下,运行的时候不需要来使用;不会达到war包,这就是在使用web项目的时候,打包运行部署无效的情况

  • runtime,这里就有点类似多态了,编译阶段是不知道运行哪个的,但是在运行和测试阶段知道是舍取哪一个;在进行测试和运行的时候,JDBC需要连接到数据库来获取得到数据进行测试。所以需要获取对应的信息

1.5、maven插件

Maven是一个核心引擎,提供了基本的项目处理能力和建设过程的管理,以及一系列的插件是用来执行实际建设任务。maven插件可以完成一些特定的功能。例如,集成jdk插件可以方便的修改项目的编译环境;集成tomcat插件后,无需安装tomcat服务器就可以运行tomcat进行项目的发布与测试。在pom.xml中通过plugin标签引入maven的功能插件。

1.5.1、JDK编译版本插件

<!--jdk编译插件--> 
<plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-compiler-plugin</artifactId> 
    <version>3.2</version> 
    <configuration>
        <source>1.8</source> 
        <target>1.8</target> 
        <encoding>utf-8</encoding> 
    </configuration> 
</plugin>

1.5.2、Tomcat7编译版本插件

<plugins> 
    <plugin>
        <groupId>org.apache.tomcat.maven</groupId> 
        <artifactId>tomcat7-maven-plugin</artifactId> 
        <configuration> 
            <!-- 指定端口 --> 
            <port>82</port> 
            <!-- 请求路径 --> 
            <path>/</path> 
        </configuration> 
    </plugin> 
</plugins>

注意: Maven的中央仓库中只有Tomcat7.X版本的插件,而之前我们使用的是8.X的版本,如果想使Tomcat8.X的插件可以去其他第三方仓库进行寻找,或者使用IDEA集成外部Tomcat8极其以上版本,进行项目的发布。

1.5.3、标签说明

参考文章:https://blog.csdn.net/qq_36779675/article/details/119002721

dependencyManagement一般是用在顶层的POM文件中,用来管理jar包的版本,子项目中就不用再指定版本号(只是声明依赖,并没有引入依赖)。

dependencies中的依赖都会自动引入,默认被所有子项目继承。

使用dependencyManagement更换版本只需要修改父POM中的版本即可。

如果子项目需要另一个版本号,只需要在dependencies中声明一个版本号,就会优先使用子POM的版本号。

2、jar包冲突解决方式

首先分析下jar包冲突是如何产生的?这里通过图形来进行演示:

因为引入了两个jar包:a.jar和b.jar。但是maven有个特性,就是将jar包依赖的jar包也会导入进来。

那么这个时候,就会导入引入的ab两个jar包中的cjar包也会被引入进来。

那么看看maven中默认的处理方式。有三种:遵循第一声明者优先原则、路径近者优先、直接排除法

2.1、第一声明有限原则

哪个jar包在靠上的位置,这个jar包就是先声明的,先声明的jar包下的依赖包,可以优先引入项目中。在pom.xml中引入如下坐标,分别是spring中不同的版本。

<?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.guang</groupId>
    <artifactId>maven_day01_demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <packaging>jar</packaging>

    <!--导入相关依赖包-->
    <dependencies>
        <!--引入spring-context,它所以来的包都会导入进来-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>4.2.4.RELEASE</version>
        </dependency>
    </dependencies>

</project>

在maven中来分析一下坐标之间的关系,从maven中的一个按钮:show dependenies中可以看到整个项目中的依赖关系。

首先可以看到spring-context这个jar包和spring-beans这个jar包共同的依赖:spring-core

但是因为spring-context这个依赖在spring-beans前先导入,那么默认使用的是spring-core是5.0.2版本的。

那么也就是说,如果共同依赖了的,谁放在前面,那么就先使用谁的依赖。

但是可以看到spring-context和spring-beans同时又都依赖了spring-beans这个依赖,那么从左边可以看到,spring-beans是4.2.4,这是怎么回事?看看下面这个。

2.2、路径优先原则

修改jar包,直接引入依赖spring-core

<!--导入相关依赖包-->
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>4.2.4.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.0.2.RELEASE</version>
    </dependency>

    <!--引入直接依赖-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>4.2.8.RELEASE</version>
    </dependency>
</dependencies>

此时优先引入的是直接依赖的引用

那么这里也来画个图分析一波:

因为spring-context和spring-beans同时又都依赖了spring-beans这个依赖,而spring-beans是4.2.4又是已经导入进来了,所以就直接使用了。

这叫路径优先原则

2.3、直接排除法

整合项目需要用到5的版本,引入4的版本,会不会出现异常(类没有找到,方法没有找到)

这种情况是经常出现的,所以这种解决方式是我们需要必备的。

当我们需要排除某个jar包的依赖时,在配置exclusions标签的时候,内部可以不写版本号。pom.xml依赖如下:

<!--导入相关依赖包-->
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>4.2.4.RELEASE</version>
        <!--直接排除-->
        <exclusions>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.0.2.RELEASE</version>
    </dependency>
</dependencies>

依赖导入的jar包如下,没有添加exclusion之前:

添加exclusion之后,因为排除了4.2.4的版本spring-core的jar包

在哪个坐标下面进行排除,表示的就是将哪个版本进行排除。

真实项目中,出现1个项目存在多个同种jar包的时候,需要我们进行解决maven的jar包冲突问题

(否则将会出现异常:Class not found、Method not found等)

3、工程拆分

3.1、项目为什么拆分

对于单体项目来说,只需要依赖共同的依赖即可。但是对于多个项目来说,如果有共同的功能,那么就应该将公共的模块单独拆分出来,组合成公共的模块,放在maven仓库中,以供其他模块来进行使用。

如下所示:

3.1、项目怎么拆分

3.1、项目拆分和聚合

对于单体项目来说,毫无区别。但是对于多模块项目来说,可能模块A依赖到模块B,模块C也需要依赖到模块B,那么对于开发人员来说,不可能将模块B分别复制到模块A、C中来,应该将模块B放置到本地仓库中来,然后打包的时候就会将模块B分别打包的模块A和模块C中来。

继承和聚合结构图:

聚合:父工程将子工程统一打包运行

父工程的作用:统一管理依赖以及聚合子工程

演示一个父工程的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.guang</groupId>
    <artifactId>ssm_parent</artifactId>
    <version>1.0-SNAPSHOT</version>

    <packaging>pom</packaging>

    <!--
        特殊属性定义,一般是版本号
    -->
    <properties>
        <spring.version>5.0.2.RELEASE</spring.version>
        <slf4j.version>1.6.6</slf4j.version>
        <log4j.version>1.2.12</log4j.version>
        <mysql.version>5.1.6</mysql.version>
        <mybatis.version>3.4.5</mybatis.version>
        <aspectjweaver.version>1.6.8</aspectjweaver.version>
        <junit.version>4.12</junit.version>
        <jsp-api.version>2.0</jsp-api.version>
        <servlet-api.version>2.5</servlet-api.version>
        <jstl.version>1.2</jstl.version>
        <mybatis-spring.version>1.3.0</mybatis-spring.version>
        <druid.version>1.0.9</druid.version>
        <!--文件的编码格式-->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    </properties>

    <!--
        jar包管理
        dependencyManagement:并非导入依赖,而只是管理依赖(这样子工程可供选择)
    -->
    <dependencyManagement>
        <!--引入依赖-->
        <dependencies>
            <!-- spring(切面) -->
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjweaver</artifactId>
                <version>${aspectjweaver.version}</version>
            </dependency>
			<!-- spring(aop) -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aop</artifactId>
                <version>${spring.version}</version>
            </dependency>

            <!--spring包(核心)-->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>${spring.version}</version>
            </dependency>

            <!--用于SpringMVC-->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-web</artifactId>
                <version>${spring.version}</version>
            </dependency>

            <!--用于数据库源相关操作-->
            <!-- spring(整合jdbc) -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jdbc</artifactId>
                <version>${spring.version}</version>
            </dependency>
			<!-- spring(事务) -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-tx</artifactId>
                <version>${spring.version}</version>
            </dependency>

            <!--Servlet相关API(可以使用Request、Response)-->
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>servlet-api</artifactId>
                <version>${servlet-api.version}</version>
                <scope>provided</scope>
            </dependency>

            <dependency>
                <groupId>javax.servlet.jsp</groupId>
                <artifactId>jsp-api</artifactId>
                <version>${jsp-api.version}</version>
                <scope>provided</scope>
            </dependency>

            <!--jstl标签-->
            <dependency>
                <groupId>jstl</groupId>
                <artifactId>jstl</artifactId>
                <version>${jstl.version}</version>
            </dependency>

            <!--MySQL数据库驱动-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
				<scope>runtime</scope>
            </dependency>

            <!--spring测试-->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-test</artifactId>
                <version>${spring.version}</version>
            </dependency>

            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
                <scope>test</scope>
            </dependency>


            <!-- log日志 start -->
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>${log4j.version}</version>
            </dependency>

            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>${slf4j.version}</version>
            </dependency>

            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
                <version>${slf4j.version}</version>
            </dependency>
            <!-- log end -->

            <!--mybatis-->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>${mybatis.version}</version>
            </dependency>

            <!--MyBatis集成Spring-->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis-spring</artifactId>
                <version>${mybatis-spring.version}</version>
            </dependency>

            <!--数据源-->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>${druid.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>


    <build>
        <pluginManagement>
            <!--插件-->
            <plugins>
                <!--tomcat插件-->
                <plugin>
                    <groupId>org.apache.tomcat.maven</groupId>
                    <artifactId>tomcat7-maven-plugin</artifactId>
                    <version>2.2</version>
                    <!--插件使用的相关配置-->
                    <configuration>
                        <!--端口号-->
                        <port>18081</port>
              <!--写当前项目的名字(虚拟路径),如果写/,那么每次访问项目就不需要加项目名字了-->
                        <path>/</path>
                        <!--解决get请求乱码-->
                        <uriEncoding>UTF-8</uriEncoding>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>

</project>

如子类的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">
    <parent>
        <artifactId>ssm_parent</artifactId>
        <groupId>com.guang</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>ssm_dao</artifactId>

    <!--jar包-->
    <packaging>jar</packaging>

    <!--引入依赖-->
    <dependencies>
        <!--model的依赖-->
        <dependency>
            <groupId>com.itheima</groupId>
            <artifactId>ssm_model</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <!--mybatis-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
        </dependency>

        <!--MyBatis集成Spring-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
        </dependency>

        <!--数据源-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
        </dependency>

        <!--MySQL数据库驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <!--SpringJdbc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
        </dependency>

        <!-- log start -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </dependency>
        <!-- log end -->
        
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>
    </dependencies>
</project>

不再需要指定对应的版本号,即可直接使用了。

posted @ 2022-03-28 16:28  雩娄的木子  阅读(348)  评论(0编辑  收藏  举报