Maven的学习

Maven是Apache的一个项目,它使用对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的软件项目管理工具。它集项目的构建,清理,编译等于一体,以前我们在使用IDE时,基本上一键就可以完成很多功能(编译,运行),而对其内部并不了解,虽然Maven不是作为让我们了解这些过程的工具,但其带来了一些好处却很有意义:比如说以前我们构建项目时,需要拷贝大量的jar包,虽然挺方便,复制粘贴,但是存在潜在问题,多个版本的冲突问题,不同开发者版本不一致的问题等等,而Maven可以帮助我们解决这些问题

Maven的下载与安装

我们在Maven官网(https://maven.apache.org/)下载之后,直接解压缩即可,是免安装的,我个人其实挺喜欢免安装的。下来是配置环境变量:

配置MAVEN_HOME到其解压缩的目录,值得注意的一点是:Maven需要JDK的支持,所以在使用之前一定要有JAVA_HONE的配置。

最后一步是在path中配置:(以便可以在cmd中使用Maven命令)

验证是否配置完成的方法是:在cmd中输入:mvn -v   可以输出版本信息就表示配置完成了,这也是我学到的第一个Maven命令

Maven的目录结构

了解一下Maven的目录结构,是有好处的:

conf文件夹中有一个settings.xml文件,我们一会要修改一下其中的配置

Maven的工作方式

Maven项目的是非常小的,因为web项目中占大头的就是jar包,Maven就对这一部分进行采用依赖的概念,所谓依赖就是只根据jar包的坐标信息就可以了,而不使用复制jar的方式。这就引发了另一个概念——坐标:坐标就是标识一个jar包的信息,通过这些信息表示jar

坐标信息由:groupId和artifactId,version信息构成。基本上我们的Maven项目也是根据这三者进行标识的,groupid表示公司域名反写,artifactid表示项目名,version表示版本

web项目中的jar都根据配置信息表示了,那是不是说我们不需要jar包就可以运行项目了?

并不是这样的,Maven需要在你的本地仓库中查找jar,如果没有就在你的Maven私服中的查找,如果还没有就去Maven的中央仓库中查找并下载到你的本地仓库。仓库就是存放jar的地方

 

虽然我们并不是通过复制/导入的方式使用jar包,但你在本地测试时还是需要jar的支持,不然怎么运行

构建本地仓库

这是时候就需要我们修改那个settings.xml文件了,打开找到下面的标签,修改为你的本地仓库:

 

本地仓库也不是说放一个jar包就可以了,还需要一些配置信息(这是一个mysql连接驱动)

我们再来看一个Maven项目的目录,注意是项目的目录,不是Maven的目录(这个pom.xml很重要,我们配置jar坐标就要在这里)

target目录就是我们编译过后class文件,配置文件以及最后打包后的文件所在了

常见Maven命令

Maven命令都是使用 mvn开头的 ,如 mvn clean,命令也可以组合使用 mvn clean package

1. clean:清理命令。将项目下的target目录删除

2. compile:编译命令。将.java文件编译为.class文件,同时生成target目录

3. test:测试命令。会运行所有单元测试类

4. package:打包命令。在target目录下生成jar/war

5. install:安装命令。安装打包的项目到本地仓库,以供其他项目使用

6. site:生成站点命令。会生成项目站点文档

7. deploy:发布命令。拷贝最终的工程包到远程仓库中,以共享给其他开发人员和工程

8. validate:验证命令。验证项目是否正确且所有必须信息是可用的

Maven常见的生命周期

1. 清理生命周期:执行clean命令

2. 默认生命周期:执行validate compile test package install deploy命令

3. 站点生命周期:执行 site命令

可以看到,因为clean单独作为一个生命周期,所以一般都会在执行其他命令之前先执行clean,例如:mvn clean package

Maven在IDE中的使用(这里使用Eclipse)

首先保证你使用Eclipse的JRE是JDK中的JRE,如果使用的是普通的jre是会有一个关于JDK的异常出现,在外面的jre和jdk中的jre还是有一些区别的,因为Maven要使用JDK,所以一定要使用JDK中的JRE

1.配置成我们下载的Maven

对了,如果你使用的Eclipse版本太低,设置中是没有Maven选项的,需要先安装一个Maven插件

2.配置User settings

配置成我们修改过的Maven中的settings.xml文件,同时下面也会找到我们的本地仓库

3.生成一个Maven项目

3.1右键new一个Maven项目

选择Maven Project就可以了

3.2然后就到了下面的页面:

勾选第一个选项,表示使用一个简易设置生成Maven项目,即使不勾选,自己去选一个Maven设置,其生成的Maven项目也不完整,还不如简单点

3.3填写一些Maven信息,这里可以看到要填写的是这个Maven项目的坐标

之后final就可以了

生成Maven项目出现的问题

1.web.xml文件的缺失

Maven自动生成的项目没有web.xml文件,我们需要添加:

这里使用了Eclipse的工具添加,当然,你也可以自己进行添加,添加到src/main/webapp下,记得web.xml文件要在WEB-INF文件夹中,也就是说要先添加WEB-INF,再在WEB-INF中添加web.xml

2.JDK版本不一致

自动生成的Maven项目中使用的JDK虽然是我们在Eclipse中配置的,但显示的名称却不一致,我们需要改一致(我是用的JDK1.8)。在pom.xml文件中配置maven-compiler-plugin这个插件:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-compiler-plugin</artifactId>
  <version>3.1</version>
  <configuration>
    <source>1.8</source>
    <target>1.8</target>
    <encoding>utf-8</encoding>
  </configuration>
</plugin>

我们可以在pom.xml文件右键添加插件

3.配置了1.8这么高的版本,还需要我们配置一下编译的Tomcat

添加tomcat7-maven-plugin插件:

<plugin>
  <groupId>org.apache.tomcat.maven</groupId>
  <artifactId>tomcat7-maven-plugin</artifactId>
  <version>2.2</version>
</plugin>

可以使用右键添加插件的方式

一会我们要使用tomcat7:run命令(如果使用tomcat8会不会去下载tomcat8?)来执行,tomcat7就可以使用JDK1.8了,而如果使用tomcat:run默认使用的tomcat6的版本,不支持1.8,只支持到1.7

4.xml文件竟然不会找不到

我们还需要添加配置指定我们的xml文件复制到编译的target\classes,不然SSH整合时会找不到那些xml文件

<resources>
    <resource>
        <directory>src/main/java</directory>
        <includes>
            <include>**/*.xml</include>
        </includes>
        <filtering>true</filtering>
    </resource>
    <resource>
        <directory>src/main/resources</directory>
        <includes>
            <include>**/*.xml</include>
            <include>**/*.properties</include>
        </includes>
    </resource>
</resources>

不论resources还是plugin节点都需要放在build节点下

5.拓展-多环境打包

Spring/SpringBoot应用可以配置多个环境下的配置文件

可以在application.yml中配置启用的配置文件,但是打包的时候还是会将所有的application-xxx.yml打包进去,可以使用Maven的resources标签解决这个问题

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <!--filtering表示开启文件过滤, 会对${}进行选择过滤-->
            <filtering>true</filtering>
            <includes>
                <include>application.yml</include>
                <include>application-${profileActive}.yml</include>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
        </resource>
    </resources>
</build>
<profiles>
    <profile>
        <id>dev</id>
        <properties>
            <profileActive>dev</profileActive>
        </properties>
    </profile>
    <profile>
        <id>dev2</id>
        <activation> <!--当未指定启用配置文件时, 默认启用的配置文件-->
            <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
            <profileActive>dev2</profileActive>
        </properties>
    </profile>
    <profile>
        <id>prod</id>
        <properties>
            <profileActive>prod</profileActive>
        </properties>
    </profile>
</profiles>

执行Maven命令

mvn clean package -DskipTest -P配置文件profile标识(profile-id)

6. 打包指定模块

在多module的maven项目中,如果每次打包整个工程显得有些冗余和笨重,可以指定打包所需的模块

执行Maven命令

mvn clean package -pl 模块的名称 -am -DskipTests

解决了这么多问题,开始运行

可以运行了嘛?很遗憾还没有,因为可能存在找不到Servlet和jsp的jar,下来我们需要添加这两个jar的坐标:

<!-- Servlet&JSP -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>javax.servlet.jsp-api</artifactId>
    <version>2.3.2-b02</version>
    <scope>provided</scope>
</dependency>

jar的坐标都需要放在dependencies节点下,可以使用右键的方式,方法和添加插件类似,只不过使用的是Add Dependency选项。

这里Servlet和JSP的jar都使用了scope指定其范围,可以指定的范围有:

Servlet和JSP的jar包不需要在运行时使用,因为Tomcat中有相应jar,会冲突。我们可以根据要添加的jar选择其范围,默认是compile

到现在我们竟然还不知道Java代码和xml文件,web页面放到哪里?

java代码放在src/main/java  

xml可以放在src/main/resources  

测试java代码放在src/test/java

测试资源和文件放在src/test/resources

web页面可以放在src/main/webapp

在运行之前update一下Maven项目,这是倒数第二步哦:

开始使用tomcat7:run运行吧

 

在这里也可以使用clean 或package等命令

如果使用Debug还需要在Source视图中把我们的项目添加进去,不然断点是不起作用的:

处理版本冲突

Maven是如何处理的jar包版本冲突的?

Maven使用两条原则:

1.选择路径最短的:比如两条路径A-B-C  D-C  第一条路径的C版本为1.0,第二条路径的C版本是1.1,就会使用路径最短的1.1版本

2.谁先声明,就是使用谁

会优先使用原则1,如果无法解决则尝试使用原则2解决,还是无法解决就需要我们去处理了,这就是Maven自动处理冲突的规则

如果还是不能解决版本冲突,也可以使用版本锁定:

<dependencyManagement>
     <dependencies>
      <dependency>
         <groupId>log4j</groupId>
         <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
   </dependencies>
</dependencyManagement>

锁定为要使用的版本坐标

项目的拆分与聚合

把我们的web项目拆分为Dao,Service,Web三层,便于开发和维护,同时也降低了耦合性

1.这个时候就要使用父工程了,我们在新建工程的时候要把打包方式设置为pom

我们来看看父工程的结构:

整个结构非常简单,可以知道父工程的作用就是来约束我们项目中使用的jar包,并组织子模块。我们把pom.xml文件添加需要的jar坐标就好了(父项目一般是做依赖管理的,将所需的jar坐标都添加到父项目的pom.xml),接着将父工程打包到本地仓库:

2.在将父工程打包之后,在父工程右键新建一个子模块(注意:选择的是Maven Module)

打包方式选择jar,因为我们的Dao都是一些Java代码,之后的Service模块也需要我们打成jar包:

之后编写相应的Dao层代码就好了(不要忘了那些xml文件,我把spring的XML文件,Log4j的配置文件也放到了Dao层,后面层可以继承)。编写完成后打包发布

3.Service层类似,不过需要在其pom文件中添加Dao的坐标信息,存在引用关系嘛。完成后打包发布

4.Web层有些特殊,因为web层有Html页面,所以记得要打成war包:

需要添加Service的坐标信息,完成后打包发布。

这是一个war包,我们可以使用tomcat7:run的命令运行,也可以使用在Eclipse中配置的Tomcat运行,推荐使用后者,因为运行和调试都很方便

来看一张表示拆分之后项目的依赖范围的图:

私服的搭建

Maven会先在本地仓库中寻找jar,没有找到,如果配有私服,就会到私服中查找,还没有才到中央仓库。可能有些公司都不提供外网给项目组人员,因此就不能使用maven访问远程的仓库地址,所以很有必要在局域网里找一台有外网权限的机器,搭建nexus私服,然后开发人员连到这台私服上,这样的话就可以通过这台搭建了nexus私服的电脑访问maven的远程仓库

1.首先确定我们的环境安装好maven,jdk等必须的环境

2.这些都准备好之后,去下载最新版本的nexus    下载地址:http://www.sonatype.org

    我本地安装的是 nexus-2.14,直接解压缩即可

3.使用管理员权限打开cmd,并cd进入该解压目录,输入命令nexus install ,安装成功后输入nexus start开启服务

看到nexus started之后就可以访问http://localhost:8081/nexus/ 启动之后,在右上角有个Log in 的超链接,点击登录,不登陆的话,一些操作无法进行

默认的用户名是 admin 密码是 admin123

来看一下仓库的类型,nexus又对仓库类型进行了细分

可能需要注意一下的,就是3rd party、Snapshots、Releases这三个,分别用来保存第三方jar(典型的oracle数据库的驱动包),项目组内部的快照、项目组内部的发布版

私服中jar包的上传与下载

上传

1.需要在maven的conf/settings.xml文件中配置认证:就是用户名和密码

2.在需要上传的maven项目中的pom.xml文件中设置上传的路径:上传到哪个仓库

  <distributionManagement>
    <repository>
      <id>releases</id>
      <url>http://localhost:8081/nexus/content/repositories/releases/</url>
    </repository>
    <snapshotRepository>
      <id>snapshots</id>
      <url>http://localhost:8081/nexus/content/repositories/snapshots/</url>
    </snapshotRepository>
  </distributionManagement>

这里上传到releases和snapshots仓库中。配置完成后,在maven build命令窗口输入deploy就可以上传了

mvn clean deploy

下载

之前没有使用私服构建maven项目,我们只需要给出jar的坐标信息即可,本地没有就从中央仓库下载,现在有了私服,如果本地仓库没有,应该先到私服中寻找,还没有再到外网仓库中下载

1.所以需要在maven的conf/settings.xml中的profiles节点配置一个模板:

    <profile>
    <!--配置文件ID为dev-->
      <id>dev</id>
      <repositories>
        <repository>
        <!--仓库id repositories可以配置多个仓库,保证id不重复-->
          <id>nexus</id>
          <!--仓库地址,这里使用nexus组仓库地址-->
          <url>http://localhost:8081/nexus/content/groups/public/</url>
          <!--是否下载releases构件-->
          <releases>
            <enabled>true</enabled>
          </releases>
          <!--是否下载snapshots构件-->
          <snapshots>
          <enabled>false</enabled>
          </snapshots>
        </repository>
      </repositories>
      <!--插件地址 nexus需要依赖的插件-->
      <pluginRepositories>
        <pluginRepository>
        <!--插件id不允许重复,如果重复,后面的会覆盖前面-->
            <id>public</id>
            <name>Public Repository</name>
            <url>http://localhost:8081/nexus/content/groups/public</url>
        </pluginRepository>
      </pluginRepositories>
    </profile>

指定从组仓库中下载,因为组仓库基本上包括所有的其他仓库

2.激活这个模板

  <!--激活dev配置文件-->
  <activeProfiles>
    <activeProfile>dev</activeProfile>
  </activeProfiles>

之后的使用只需要添加jar的GAV信息就可以了

替换成阿里云Maven仓库镜像

Maven默认的远程仓库(https://repo.maven.apache.org/maven2,解压Maven安装目录下lib/maven-model-builder-xxx.xx.jar中org/apache/maven/model/pom-4.0.0.xml文件中Central Repository),无奈有时下载jar会很慢,可以替换成阿里云的Maven仓库镜像,提升下载速度。只需要在conf\settings.xml 文件中添加如下配置:

<mirror>
    <id>nexus-aliyun</id>
    <mirrorOf>*</mirrorOf>
    <name>Nexus aliyun</name>
    <url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>

配置在 mirrors 标签下即可。私服也是通过配置镜像的方式配置的,方法如上

mirrorOf元素高级配置:

<mirrirOf>*</mirrirOf>:表示该镜像是所有Maven仓库的镜像,任务对于远程仓库的访问都会转到镜像的url

<mirrirOf>external: *</mirrirOf>:匹配远程仓库,所有不是本机上的仓库

<mirrirOf>repo1, repo2</mirrirOf>:匹配多个远程仓库id,使用逗号分隔

<mirrirOf>*, ! repo1</mirrirOf>:匹配所有远程仓库,repo1除外

需要注意,有于镜像仓库完全屏蔽了被镜像的仓库,当镜像仓库出现问题,Maven将无法下载构件

posted @ 2017-06-07 22:46  OverZeal  阅读(337)  评论(0编辑  收藏  举报