Java入门系列16 -- Maven

Maven

  • Maven作为Apache组织中的一个项目,主要服务于基于Java平台的项目构建,依赖管理与项目信息管理;
项目构建工具
  • Ant构建,最早的构建工具,XML文件过大;
  • Maven构建,支持网络下载功能,专注于依赖管理,弥补了Ant的缺点;
  • Gradle构建,结合了Ant与Maven的优点,主要用于Android的管理工具;
Maven的四大特性
  • 依赖管理系统,类似于iOS中Cocoapods工具,可使用groupId,artifactId,version三者组合坐标,其能唯一标识一个依赖;
    • groupId:定义当前Maven项目所隶属的公司;
    • artifactId:项目模块名称;
    • version:项目版本;
  • 多模块构建
  • 一致的项目结构
  • 一致的构建模型和插件机制
Mac下Maven的安装与配置
  • 首先检查JDK版本,JDK版本在1.7及其以上,终端输入java -version
  • 其次下载Maven,点击下载
Snip20211214_18.png
  • 解压下载包,将解压之后的包放在/usr/local目录下,即/usr/local/apache-maven-3.8.4
  • 然后配置Maven环境变量,终端cd到~目录下,执行open .bash_profile,然后输入Maven的环境变量配置,如下:
#配置Maven环境变量
export Maven_Home=/usr/local/apache-maven-3.8.4
export Java_Home=/Library/Java/JavaVirtualMachines/jdk1.8.0_311.jdk/Contents/Home
export PATH=$PATH:$Maven_Home/bin:$Java_Home/bin
  • 其中Java_Home是JDK的目录,可通过/usr/libexec/java_home -V查询获得;
  • Maven环境变量配置完成后,重启终端,然后输入mvn -v,看到如下内容,表示Maven环境变量配置成功了;
image.png
Maven的命令
  • mvn -version:显示版本信息;
  • mvn clean:清理项目生产的临时文件,一般是模块下的target目录;
  • mvn compile:编译源代码,一般编译模块下的src/main/java目录;
  • mvn package:项目打包工具,会在模块下的target目录生成jar或者war等文件;
  • mvn test:测试命令,或执行src/test/java下junit的测试用例;
  • mvn install:将打包的jar/war文件复制到你的本地仓库中,供其他模块使用;
  • mvn deploy:将打包的文件发布到远程,提供给其他人员进行下载依赖;
  • mvn site:生成项目相关信息的网站;
  • mvn eclipse:eclipse:将项目转化为Eclipse项目;
  • mvn dependency:tree:打印出项目的整个依赖树;
  • mvn archetype:generate:创建Maven的普通Java项目;
  • mvn tomcat7:run:在tomcat容器中运行Web应用;
  • mvn jetty:run:调用jetty插件的Run目标在jetty Servlet容器中启动web应用;
  • 运行mvn命令时,首先要定位maven项目的目录;
  • 命令参数:
    • - D 传入属性参数;
    • - P 使用指定的Profile配置;
IDEA集成Maven环境
  • 首先在集成Maven环境之前,对Maven中的文件作些许配置,找到Maven安装目录下的settings.xml文件,我的文件目录为/usr/local/apache-maven-3.8.4/conf/settings.xml,将此文件中的镜像换成阿里的镜像,如下所示:
<!-- 更换阿里镜像,加快依赖下载速度 -->
<mirror>
  <id>nexus-aliyun</id>
  <mirrorOf>central</mirrorOf>
  <name>Nexus aliyun</name>
  <url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
  • 如下截图:
image.png
  • 至于下载jar包的存放路径,这里不做更改,保持默认,默认存放在/Users/用户名/.m2/repository目录下;

  • 然后打开IDEA,打开File -> New Projects Settings -> Preference for new Projects,输入Maven,配置如下:

image.png
IDEA利用Maven创建Java项目
  • 进入File -> New -> Project,如下所示:
image.png
  • 点击Next,进入如下;
image.png
  • 如果是第一次创建,会去下载各种jar包,存放在/Users/用户名/.m2/repository目录下;
image.png
image.png
  • jar包下载完成,最后编译成功,如下所示:
image.png
  • 新建编译命令,点击右上角的Edit Configurations,弹出如下:
Snip20211215_29.png
  • 编译命令设置完成之后,点击执行,如下所示:
image.png
  • 再新建一个打包命令,设置如下:
image.png
  • 然后点击package命令,执行如下所示:
image.png
IDEA利用Maven创建Web项目
  • 创建Web项目的基本流程与创建Java项目的基本一致;
  • 详细流程如下:
Snip20211215_35.png
Snip20211215_36.png
Snip20211215_37.png
  • 项目创建成功后,在pom.xml文件中作如下配置:
<?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.sf</groupId>
  <artifactId>maven03</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>maven03 Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <!-- JDK版本设置 -->
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <!-- 单元测试版本设置 -->
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <!-- 引入jetty与tomcat的maven插件 -->
  <build>
    <finalName>maven03</finalName>
    <plugins>
      <plugin>
        <!-- jetty插件 -->
        <groupId>org.mortbay.jetty</groupId>
        <artifactId>maven-jetty-plugin</artifactId>
        <version>6.1.25</version>
        <configuration>
          <!-- 热部署 每10秒扫描一次 -->
          <scanIntervalSeconds>10</scanIntervalSeconds>
          <!-- 可指定当前项目的站点名 -->
          <contextPath>/maven03</contextPath>
          <connectors>
            <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
              <port>9090</port> <!-- 设置启动端口号 -->
            </connector>
          </connectors>
        </configuration>
      </plugin>

      <!-- tomcat插件 -->
      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.1</version>
        <configuration>
          <port>8080</port> <!-- 启动端口 默认8080 -->
          <path>/test</path> <!-- 项目站点名 对外访问路径 -->
          <uriEncoding>UTF-8</uriEncoding> <!-- 字符集 -->
          <server>tomcat7</server> <!-- 服务器名称 -->
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>
  • 其中junit的版本,可使用本地仓库中最新版本,可查看本地仓库中下载的版本,我的本地路径是/Users/liyanyan33/.m2/repository/junit/junit,版本如下:
image.png
  • 这里配置了jetty与tomcat两种插件来启动服务,注意配置的对外访问路径与端口号;
  • 创建jetty命令,启动服务,如下所示:
Snip20211215_38.png
Snip20211215_40.png
  • 创建tomcat命令,启动服务,如下所示:
Snip20211215_39.png
Snip20211215_41.png
Maven仓库
  • 对于Maven来说,仓库分为本地仓库和远程仓库;
  • 当Maven在根据坐标寻找构件的时候,首先会查看本地仓库,若本地仓库存在目标构建,则直接使用,若本地仓库没有,会去远程仓库查找,发现构建下载到本地仓库之后再使用,若远程仓库也没有,就会出现报错;
  • 远程仓库又分为以下三种:
    • 中央仓库:Maven的默认配置,Maven下载jar的地方;
    • 私服:是一种比较特殊的远程仓库,为了节省宽带和时间,在局域网内架设一个私有仓库服务器,用其代替外部的远程仓库;
    • 其他公共库:例如阿里云仓库;
  • 默认情况下,每个用户默认的本地仓库地址为/Users/用户名/.m2/repository,这个地址可以在/usr/local/apache-maven-3.8.4/conf/settings.xml文件中进行修改;
<!-- 本地仓库地址: 存放jar包 -->
<localRepository>自定义路径</localRepository>
  • Maven依赖包的查询,可点击这里,在搜索框中输入目标依赖包的名称即可,得到其详细信息;
Maven环境下构建多模块项目
  • 这里分为四个模块来搭建项目;
    • maven_parent模块:基模块(pom);
    • maven_controller模块:用来接收请求,响应数据的(war)
    • maven_service模块:项目的业务逻辑层(jar)
    • maven_dao模块:数据库访问层,例如JDBC(jar)
  • 首先来创建maven_parent模块,如下所示:
Snip20211215_43.png
Snip20211215_45.png
  • 其次创建maven_dao模块,如下所示:
    • maven_parent项目的基础上创建Moudle
Snip20211215_46.png
Snip20211215_48.png
Snip20211215_49.png
Snip20211215_50.png
  • 再其次创建maven_service模块,步骤与创建maven_dao模块完全相同;
  • 最后创建maven_controller模块,与创建maven_dao模块唯一区别选择的模版不同,其他步骤还是一样的,如下所示:
Snip20211215_52.png
  • 所有模块创建完毕的项目结构如下所示:
image.png
  • 接下来,修改模块的配置,针对maven_daomaven_servicemaven_controller三个模块的pom.xml文件进行修改;
    • 设置JDK版本;
    • 设置单元测试版本;
    • 删除多余的配置;
image.png
  • 再接下来,设置模块之间的依赖;
    • maven_service依赖于maven_dao
    • maven_controller依赖于maven_service,且依赖于Servlet类
  • 首先在maven_servicepom.xml中引入maven_dao的依赖;
  • maven_daopom.xml中的内容,如下所示:
<groupId>com.sf</groupId>
<artifactId>maven_dao</artifactId>
<version>1.0-SNAPSHOT</version>
  • 将其复制到maven_servicepom.xml中,如下所示:
image.png
  • 然后在maven_controllerpom.xml文件中引入maven_serviceServlet的依赖,如下所示:
image.png
  • 然后在maven_controllerpom.xml文件中引入tomcat插件,用于启动服务,所以其完整的pom.xml文件内容如下所示:
<?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.sf</groupId>
  <artifactId>maven_controller</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>maven_controller Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13</version>
      <scope>test</scope>
    </dependency>

    <!-- 引入maven_service层 -->
    <dependency>
      <groupId>com.sf</groupId>
      <artifactId>maven_service</artifactId>
      <version>1.0-SNAPSHOT</version>
    </dependency>

    <!-- 引入Servlet依赖 -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>

  <build>
    <finalName>maven_controller</finalName>

    <!-- 添加插件 -->
    <plugins>
      <!-- tomcat插件 -->
      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.1</version>
        <configuration>
          <port>8080</port> <!-- 启动端口 默认8080 -->
          <path>/web</path> <!-- 项目站点名 对外访问路径 -->
          <uriEncoding>UTF-8</uriEncoding> <!-- 字符集 -->
          <server>tomcat7</server> <!-- 服务器名称 -->
        </configuration>
      </plugin>
    </plugins>

  </build>
</project>
  • 再然后要为maven_daomaven_servicemaven_controllermaven_parent分别配置install执行命令,如下所示:
image.png
  • 再然后配置服务启动命令tomcat,如下所示:
image.png
  • maven_dao中创建UserDao文件,内容如下:
package com.sf.dao;

public class UserDao {

    public static void TestDao() {
        System.out.println("UserDao Test");
    }
}
  • maven_service中创建UserService文件,内容如下:
package com.sf.service;

import com.sf.dao.UserDao;

public class UserService {

    public static void testService() {
        System.out.println("UserService Test");
        //调用maven_dao层的方法
        UserDao.TestDao();
    }
}
  • maven_controller中创建UserServlet文件,内容如下:
package com.sf.controller;

import com.sf.service.UserService;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/user")
public class UserServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("UserServlet service");
        //调用maven_service层的方法
        UserService.testService();
    }
}
  • 最后首先子模块maven_daomaven_servicemaven_controller依次执行install命令,然后主项目maven_parent执行install命令,最后执行tomcat命令,启动服务,待服务启动成功,浏览器输入http://localhost:8080/web/user,结果如下:
image.png
Maven的打包
  • 通过Maven的简单配置,能实现不同环境下项目的整体打包;
  • 创建一个Web项目,来实验打包的流程;
  • 创建Java源文件夹java,并标记为源文件夹即蓝色的文件夹;
  • 创建资源文件夹resources,并标记为源Resource Root,有三个小横杠,选中右击选择Mark Directory as
  • resources目录下,创建三个不同环境的目录 分别为dev,test,product,然后都为其创建db.propertiesbean.properties文件;
  • dev中的db.propertiesbean.properties文件内容如下:
name=root
password=root
<bean>
    dev
</bean>
  • test中的db.propertiesbean.properties文件内容如下:
name=test
password=test
<bean>
    test
</bean>
  • product中的db.propertiesbean.properties文件内容如下:
name=product
password=product
<bean>
    product
</bean>
  • 添加Profile配置到pom.xml文件中,内容如下:
  <!-- 打包配置 -->
  <profiles>
    <profile>
      <id>id</id>
      <properties>
        <env>dev</env>
        <activation>
          <activeByDefault>true</activeByDefault>
        </activation>
      </properties>
    </profile>

    <profile>
      <id>test</id>
      <properties>
        <env>test</env>
      </properties>
    </profile>

    <profile>
      <id>product</id>
      <properties>
        <env>product</env>
      </properties>
    </profile>

  </profiles>
  • 设置资源文件配置到pom.xml文件中的build标签中,内容如下:
    <!-- 资源文件的配置 -->
    <resources>
      <resource>
        <directory>src/main/resources/${env}</directory>
      </resource>
      <resource>
        <directory>src/main/java</directory>
        <includes>
          <include>**/*.xml</include>
          <include>**/*.properties</include>
          <include>**/*.tld</include>
        </includes>
        <filtering>false</filtering>
      </resource>
    </resources>
  • 最终pom.xml文件内容如下:
<?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.sf</groupId>
  <artifactId>maven03</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>maven03 Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <!-- JDK版本设置 -->
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <!-- 打包配置 -->
  <profiles>
    <profile>
      <id>id</id>
      <properties>
        <env>dev</env>
        <activation>
          <activeByDefault>true</activeByDefault>
        </activation>
      </properties>
    </profile>

    <profile>
      <id>test</id>
      <properties>
        <env>test</env>
      </properties>
    </profile>

    <profile>
      <id>product</id>
      <properties>
        <env>product</env>
      </properties>
    </profile>

  </profiles>

  <!-- 单元测试版本设置 -->
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <!-- 引入jetty与tomcat的maven插件 -->
  <build>
    <finalName>maven03</finalName>
    <!-- 资源文件的配置 -->
    <resources>
      <resource>
        <directory>src/main/resources/${env}</directory>
      </resource>
      <resource>
        <directory>src/main/java</directory>
        <includes>
          <include>**/*.xml</include>
          <include>**/*.properties</include>
          <include>**/*.tld</include>
        </includes>
        <filtering>false</filtering>
      </resource>
    </resources>

    <plugins>
      <plugin>
        <!-- jetty插件 -->
        <groupId>org.mortbay.jetty</groupId>
        <artifactId>maven-jetty-plugin</artifactId>
        <version>6.1.25</version>
        <configuration>
          <!-- 热部署 每10秒扫描一次 -->
          <scanIntervalSeconds>10</scanIntervalSeconds>
          <!-- 可指定当前项目的站点名 -->
          <contextPath>/maven03</contextPath>
          <connectors>
            <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
              <port>9090</port> <!-- 设置启动端口号 -->
            </connector>
          </connectors>
        </configuration>
      </plugin>

      <!-- tomcat插件 -->
      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.1</version>
        <configuration>
          <port>8080</port> <!-- 启动端口 默认8080 -->
          <path>/test</path> <!-- 项目站点名 对外访问路径 -->
          <uriEncoding>UTF-8</uriEncoding> <!-- 字符集 -->
          <server>tomcat7</server> <!-- 服务器名称 -->
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>
  • 执行打包操作,为不同的环境创建打包命令;
  • package_dev:clean compile package -Pdev -Dmaven.test.skip=true
  • package_test:clean compile package -Ptest -Dmaven.test.skip=true
  • package_product:clean compile package -Pproduct -Dmaven.test.skip=true
  • 创建过程如下所示:
image.png
  • 最后执行不同的打包命令,生成不同环境下的war包;
Maven的依赖
  • pom.xml文件中的dependencies标签下,可以包含多个dependenc依赖,每个依赖会包含以下元素:
    • groupIdartifactIdversion:依赖的基本坐标,能标识唯一的依赖;
    • Type:依赖的类型,大部分情况下为jar
    • Scope:依赖的范围,有compile,test,provide,runtime,system范围的依赖;
    • Optional:标记依赖是否可选;
    • Exclusion:用来排出传递性依赖;
  • 传递性依赖可能会造成依赖冲突;
  • 例如 A->B->C 且 A->D->C
  • C可能是不同的版本,那么要选择合适版本的C 同时支持A;
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,504评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,434评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,089评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,378评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,472评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,506评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,519评论 3 413
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,292评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,738评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,022评论 2 329
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,194评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,873评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,536评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,162评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,413评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,075评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,080评论 2 352

推荐阅读更多精彩内容