自动化构建工具:Maven

1.目前掌握的技术




2.目前的技术在开发中存在的问题(Why)

    ①一个项目就是一个工程

(如果项目非常庞大,就不适合继续使用package来划分模块,最好是每个模块对应一个人工程,利于分工协作)

    ②项目中需要的jar包必须手动“复制”、“粘贴”到WEB-INF/lib目录下

(带来的问题是:同样的jar包文件重复出现在不同的项目工程中,一方面浪费存储空间,另一方面也让工程比较臃肿)

    ③jar包需要别人替我们准备好,或到官网进行下载

(不同技术的官网提供jar包下载的形式五花八门的,有些技术的官网就是通过Maven或SVN等专门的工具提供下载的。

如果是以不规范的方式下载的jar包,那么其中的内容很可能也是不规范的。

借助于Maven可以以一种规范的方式下载jar包,因为所有知名框架或第三方工具的jar包以及按照统一的规范存放在了Maven的中央仓库中,以规范的方式下载的jar包,内容也是可靠的。

扫描二维码关注公众号,回复: 3070126 查看本文章

Tips:"统一的规范",不仅是对IT开发领域非常重要,对于整个人类社会都是非常重要的。)

    ④一个jar包依赖其他jar包需要自己手动加入到项目中

(FileUpload组件-->IO组件。commons-fileupload-1.3jar依赖于commons-io-2.0.1jar。

如果所有jar包之间的依赖关系 都需要程序员自己非常的了解,那么就会极大的增加学习成本。

Maven会自动将被依赖的jar包导入进来。)


3.Maven是什么(What)

    ①Maven是一款服务于Java平台的自动化构建工具。

            Make-->Ant-->Maven-->Gradle

    ②构建

            [1]概念:以“Java源文件”、“框架配置文件”、“JSP”、“HTML”、“图片”等资源为“ 原材料”,

            去“生产”一个可以运行的项目的过程。

                编译、部署、搭建

              [2]编译:Java源文件[User.java]-->编译-->Class字节码文件[User.class]-->交给JVM去执行

              [3]部署:一个BS项目最终运行的并不是动态Web工程本身,而是这个动态Web工程“编译的结果”

                            生成的鸡-->处理-->熟的鸡

                            动态Web工程-->编译、部署-->编译结果

                              

                        开发过程中,所有的路径或配置文件中配置的类路径等都是以编译结果的目录结构为标准的。

                Tips:运行时环境

                        

                        其实是一组jar包的引用,并没有把jar包本身复制到工程中,所以并不是目录。

                Tips:tc_server

                        整个目录复制到eclipse解压安装目录下的dropins目录下即可

                        

                    或是自己从官方下载,转载一篇博客教程地址http://blog.csdn.net/a332056918/article/details/76180530

    ③构建过程中的各个环节

            [1]清理:将以前编译得到的旧的class字节码文件删除,为下一次编译做准备

            [2]编译:将Java源程序编译成class字节码文件

            [3]测试:自动测试,自动调用junit程序

            [4]报告:测试程序执行的结果

            [5]打包:动态Web工程打war包,Java工程打jar包

            [6]安装:Maven特定的概念----将打包得到的文件复制到“仓库”中的指定位置

            [7]部署:将动态Web工程生成的war包复制到Servlet容器的指定目录下,使其可以运行

    ④自动化构建

4.安装Maven核心程序

    ①检查JAVA_HOME环境变量

    

    ②解压Maven核心程序的压缩包,放在一个非中文无空格路径下

    E:\maven\apache-maven-3.5.2

    ③配置Maven相关的环境变量

        [1]MAVEN_HOME或M2_HOME

            

         [2]Path

            

    ④验证:运行mvn -v命令查看Maven版本

        

5.Maven的核心概念

    ①约定的目录结构

    ②POM

    ③坐标

    ④依赖

    ⑤仓库

    ⑥生命周期/插件/目标

    ⑦继承

    ⑧聚合


6.第一个Maven工程

     ①创建约定的目录结构

        [1]根目录:工程名

        [2]src目录:源码

        [3]pom.xml文件:Maven工程的核心配置文件

        [4]main目录:存放主程序

        [5]test目录:存放测试程序

        [6]java目录:存放Java源文件

        [7]resources目录:存放框架或其他工具的配置文件


②为什么要遵守约定的目录结构呢?

    Maven要负责我们这个项目的自动化构建,以编译为例,Maven要想自动进行编译,那么它必须知道Java源文件保存在哪里。

    如果我们自己自定义的东西想让框架或工具知道,有两种办法

           --以配置文件的方式明确告诉框架

                

           --遵守框架内部已存在的约定

                log4j.properties

                log4j.xml

                       约定>配置>编码

     

目录结构   

Hello

|---src
|---|---main
|---|---|---java
|---|---|---resources
|---|---test
|---|---|---java
|---|---|---resources

|---pom.xml


POM文件内容

<?xml version="1.0" ?>
<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.atguigu.maven</groupId>
	<artifactId>Hello</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<name>Hello</name>
	  
	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.0</version>
			<scope>test</scope>
		</dependency>
	</dependencies>
</project>

编写主程序代码

        在src/main/java/com/atguigu/maven目录下新建文件Hello.java,内容如下

package com.atguigu.maven;
		public class Hello {
			public String sayHello(String name){
				return "Hello "+name+"!";
			}
		}

编写测试代码

        在/src/test/java/com/atguigu/maven目录下新建测试文件HelloTest.java

package com.atguigu.maven;	
		import org.junit.Test;
		import static junit.framework.Assert.*;
		public class HelloTest {
			@Test
			public void testHello(){
				Hello hello = new Hello();
				String results = hello.sayHello("litingwei");
				assertEquals("Hello litingwei!",results);	
			}
		}

运行几个基本的Maven命令

                mvn compile 编译
mvn clean 清理
mvn test 测试
mvn package 打包
※注意:运行Maven命令时一定要进入pom.xml文件所在的目录!



7.常用Maven命令

    ①注意:执行与构建过程相关的Maven命令,必须进入pom.xml所在的目录。

            与构建过程相关:编译、测试、打包、.......

    ②常用命令

        [1]mvn clean : 清理

         [2]mvn compile : 编译主程序

         [3]mvn test-compile : 编译测试程序

         [4]mvn test : 执行测试

         [5]mvn package : 打包

         [6]mvn site : 生成站点


8.关于联网问题

        ①Maven的核心程序中仅仅定义了抽象的生命周期,但是具体的工作必须由特定的插件来完成。

而插件本身并不包含在Maven的核心程序中。

        ②当我们执行的Maven命令需要用到某些插件时,Maven核心程序会首先到本地仓库中查找。

        ③本地仓库的默认位置:[系统中当前用户的家目录]\.m2\repository

            C:\Users\ 登录当前系统的用户名\.m2\repository

        ④Maven核心程序如果在本地仓库中找不到需要的插件,那么它会自动连接外网,到中央仓库中下载。

        ⑤如果此时无法连接外网,则构建失败。

        ⑥修改默认本地仓库的位置可以让Maven核心程序到我们事先准备好的目录下查找插件

                [1]找到Maven解压目录\conf\settings.xml

                [2]在settings.xml文件中找到localRepository标签

                [3]将<localRepository>/path/to/localrepo</localRepository>从注释中取出

                [4]将标签体内容修改为已准备好的Maven仓库目录

                <localRepository>D:\RepMaven</localRepository>


9.POM

    ①含义:Project Object Model 项目对象模型

            DOM Document Object Model 文档对象模型

    ②pom.xml对于Maven工程是核心配置文件,与构建过程相关的一切设置都在这个文件中进行配置。

            重要程度相对于web.xml对于动态Web工程


10.坐标

    ①数学中的坐标:

        [1]在平面上,使用X、Y两个向量可以唯一的定位平面中的任何一个点。

        [2]在空间中,使用X、Y、Z三个向量可以唯一的定位空间中的任何一个点。

    ②Maven的坐标

        使用下面三个向量在仓库中唯一定位一个Maven工程

        [1]groupid:公司或组织域名倒序+项目名

        <groupid>com.atguigu.maven</groupid>

        [2]artifactid:模块名

        <artifactid>Hello</artifactid>

        [3]version:版本

        <version>1.0.0</version>

        ③坐标与仓库中路径的对应关系

                <groupId>org.springframework</groupId>
              <artifactId>spring-core</artifactId>
              <version>4.0.0.RELEASE</version>

        org/springframework/spring-core/4.0.0.RELEASE/spring-core-4.0.0.RELEASE.jar


11.仓库

    ①仓库的分类

            [1]本地仓库:当前电脑上部署的仓库目录,为当前电脑上所有Maven工程服务

            [2]远程仓库

                    (1)私服:搭建在局域网环境中,为局域网范围内的所有Maven工程服务

                        

                    (2)中央仓库:架设在Internet上,为全世界所有Maven工程服务

                    (3)中央仓库镜像:为了分担中央仓库的流量,提升用户访问速度

②仓库中保存的内容:Maven工程

        [1]Maven自身所需要的插件

        [2]第三方框架或工具的jar包

        [3]我们自己开发的Maven工程


第二个Maven工程

<?xml version="1.0" ?>
<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.atguigu.maven</groupId>
	<artifactId>HelloFriend</artifactId>
	<version>0.0.1-SNAPSHOT</version><!--SNAPSHOT为快照版的,作为开发时版本使用;RELEASE为正式版-->
	<name>HelloFriend</name>
	
	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.0</version>
			<scope>test</scope>
		</dependency>		
		
		<dependency>
			<groupId>com.atguigu.maven</groupId>
			<artifactId>Hello</artifactId>
			<version>0.0.1-SNAPSHOT</version>
			<scope>compile</scope>
		</dependency>
		
	</dependencies>
</project>
主程序:在src/main/java/com/atguigu/maven目录下新建文件HelloFriend.java
package com.atguigu.maven;	
		import com.atguigu.maven.Hello;
		public class HelloFriend {
			public String sayHelloToFriend(String name){
				Hello hello = new Hello();
				String str = hello.sayHello(name)+" I am "+this.getMyName();
				System.out.println(str);
				return str;
			}
			public String getMyName(){
				return "John";
			}
		}

测试程序:在/src/test/java/com/atguigu/maven目录下新建测试文件HelloFriendTest.java

package com.atguigu.maven;	
		import static junit.framework.Assert.assertEquals;
		import org.junit.Test;
		import com.atguigu.maven.Hello;
		
		public class HelloFriendTest {
			@Test
			public void testHelloFriend(){
				HelloFriend helloFriend = new HelloFriend();
				String results = helloFriend.sayHelloToFriend("litingwei");
				assertEquals("Hello litingwei! I am John",results);	
			}
		}

运行Maven命令

mvn install 安装


12.依赖(初步)

    ①Maven解析依赖信息时会到本地仓库中查找被依赖得到jar包。

        对于我们自己开发的Maven工程,使用install命令安装后就可以进入仓库。

    ②依赖的范围

        

        [1]compile

                对主程序是否有效:有效

                对测序是否有效:有效

                是否参与打包:参与

                是否参与部署:参与

                典型例子:spring-core


        [2]test范围依赖

                    对主程序是否有效:无效

                    对测试范围是否有效:有效

                    是否参与打包:不参与

                    是否参与部署:不参与

                    典型例子:junit


          [3]provided范围依赖

                对主程序是否有效:有效

                对测试程序是否有效:有效            

                是否参与打包:不参与

                是否参与部署:不参与

                典型例子:servlet-api.jar

                

13.生命周期

        ①各个构建环节执行的顺序:不能打乱顺序,必须按照既定的正确顺序来执行。

        ②Maven的核心程序中定义了抽象的生命周期,生命周期中各个阶段的具体任务是由插件来完成的。

        ③Maven核心程序为了更好的实现自动化构建,按照这一特点执行生命周期的各个阶段:无论现在要执行生命周期中的哪一个阶段,都是从这个生命周期最初的位置开始执行。

mvn compile


mvn test


mvn package


    ④插件和目标

            [1]生命周期的各个阶段仅仅定义了要执行的任务是什么。

            [2]各个阶段和插件的目标是相对应的。

            [3]相似的目标由特定的插件来完成。


            [4]可以将目标看作“调用插件功能的命令”


14.在Eclipse中使用Maven

    ①Maven插件:Eclipse内置

            [1]installations:指定Maven核心程序的位置。不建议使用插件自带的Maven程序,而应该使用我们自己解压的那个。

           

  [2]user settings:指定conf/settings.xml的位置,进而获取本地仓库的位置。


    global settings 本机器的配置,使用这台机器的所有用户都是用这个配置

    user settings    当前用户的配置

       * 个人配置会覆盖全局配置

    通过user settings中settings.xml位置,进而知道本地仓库的位置(Local Repository)

            *注意:新的工作空间需要重新设置

    ②基本操作

            [1]创建Maven版的Java工程





跳过skup archetype selection这种方式(创建后目录不全,不建议使用),使用简单的方式来创建



创建好发现每次都要更改jdk版本


第三个Maven工程

①设置通过Maven创建的工程的JDK版本——一劳永逸
[1]打开settings.xml文件
[2]找到profiles标签

[3]加入如下配置

<profile>
				<id>jdk-1.7</id>
				<activation>
					<activeByDefault>true</activeByDefault>
					<jdk>1.7</jdk>
				</activation>
				<properties>
					<maven.compiler.source>1.7</maven.compiler.source>
					<maven.compiler.target>1.7</maven.compiler.target>
					<maven.compiler.compilerVersion>1.7</maven.compiler.compilerVersion>
				</properties>
</profile>

另外在标签<mirrors>中,更改标签中对应代码如下,从阿里云仓库中下载,可以使下载的插件速度加快

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

②工程坐标

groupId:com.atguigu.maven
ArtifactId:MakeFriends
Package:com.atguigu.maven

③在src/main/java中新建类com.atguigu.maven.MakeFriends

public String makeFriends(String name){
			HelloFriend friend = new HelloFriend();
			friend.sayHelloToFriend("litingwei");
			String str = "Hey,"+friend.getMyName()+" make a friend please.";
			System.out.println(str);
			return str;
		}

④在src/test/java中新建类com.atguigu.maven.MakeFriendsTest

package com.atguigu.maven;
		import static junit.framework.Assert.assertEquals;
		import org.junit.Test;
		public class MakeFriendsTest {
			@Test
			public void testMakeFriends(){		
				MakeFriends makeFriend = new MakeFriends();
				String str = makeFriend.makeFriends("litingwei");
				assertEquals("Hey,John make a friend please.",str);
			}
		}

⑤添加依赖信息

<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.9</version>
			<scope>test</scope>
		</dependency>
		<dependency>
	    	<groupId>com.atguigu.maven</groupId>
	    	<artifactId>HelloFriend</artifactId>
	    	<version>0.0.1-SNAPSHOT</version>
	    	<type>jar</type>
	    	<scope>compile</scope>
		</dependency>

⑥在Eclipse环境下执行Maven命令:右击pom.xml选择run as 中的命令执行即可



        [2]创建Maven版的Web工程





创建jsp页面报错

-->The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path

解决方法

在pom.xml中添加ServletAPI依赖

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

jsp中EL表达式代码提示,在pom.xml中添加JSPAPI依赖

<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>jsp-api</artifactId>
			<version>2.1.3-b06</version>
			<scope>provided</scope>
</dependency>

jar包之间的冲突



与Tomcat的包冲突,<scope>里应改为原来默认的provided


导入手动创建的Maven工程


根据pom.xml识别工程


生成Eclipse能识别的文件


*用Maven方式导入不能复制工程到工作区

*平时的开发不必将引入别的模块安装到仓库中,在开发完成后,直接打包就会自动构建执行一系列命令,在Eclipse中的开发没有将引入的模块安装到仓库中也是可以用的。

15.依赖(高级)

    ①依赖的传递性


        [1]好处:可以传递的依赖不必在每个模块工程中都重复声明,在“最下面”的工程中依赖一次即可。

        [2]注意:非compile范围的依赖不能传递。所以在各个工程模块中,如果有需要就得重复声明依赖。

    ②依赖的排除

        [1]需要设置依赖排除的场合

            

        [2]依赖排除的设置方式在pom.xml依赖的模块<scope>标签后加入

            

    ③依赖的原则

            [1]作用:解决j模块工程之间的jar包冲突问题  

            [2]情景设定1:验证路径最短者优先原则

                  

            [3]情景设定2:验证路径相同时先声明者优先

                    


    ④统一管理依赖的版本

        [1]情景举例

            

            这里对Spring各个jar包依赖的版本都是4.0.0

            如果需要统一升级为4.1.1,怎么办?手动逐一修改不可靠。


       [2]建议配置方式

                i.使用properties标签内使用自定义标签统一声明版本号

                

                ii.在需要统一版本的位置,使用${自定义标签名}引用声明的版本号

                

               [3]其实properties标签配合自定义标签声明数据的配置并不是只能用于声明依赖的版本号。凡是需要统一声明后再引用的场合都可以使用。

                


16.继承

①现状

        Hello依赖的junit:4.0

        HelloFriend依赖的junit:4.0

        MakeFriends依赖的junit:4.9

        由于test范围的依赖不能传递,所以必然会分散在各个模块工程中,很容易造成版本不一致。

②需求:统一管理各个模块工程中对juniit依赖的版本

③解决思路:将junit依赖统一提取到“父”工程中,在子工程中声明junit依赖时不指定版本,以父工程中统一设定的为准。同时也便于修改。

④操作步骤

        [1]创建一个Maven工程作为父工程。注意打包的方式pom


        [2]在子工程中声明对父工程的引用



    [3]将子工程的坐标中与父工程坐标中重复的内容删除


    [4]在父工程中统一管理junit的依赖


    [5]在子工程中删除junit依赖的版本号部分

        

    ⑤注意:配置继承后,执行安装命令时要先安装父工程。


17.聚合

    ①作用:一键安装各个模块工程。

    ②配置方式:在一个“总的聚合工程”中配置各个参与聚合的模块


    ③使用方式:在聚合工程的pom.xml上点右键run as-->maven install


18.Web工程自动部署

<!--配置当前工程构建过程中的特殊设置-->
<build>
		<finalName>AtguiguWeb</finalName><!--最终的名字-->
		<plugins><!--配置构建过程需要使用的插件-->
			<plugin><!--cargo是一家专门从“启动Servlet容器”的组织-->
				<groupId>org.codehaus.cargo</groupId>
				<artifactId>cargo-maven2-plugin</artifactId>
				<version>1.2.3</version>
				<configuration><!--配置当前系统中容器的位置-->
					<container>
						<containerId>tomcat6x</containerId>
						<home>D:\DevInstall\apache-tomcat-6.0.39</home>
					</container>
					<configuration>
						<type>existing</type>
						<home>D:\DevInstall\apache-tomcat-6.0.39</home>
						<!-- 如果Tomcat端口为默认值8080则不必设置该属性 -->
						<properties>
							<cargo.servlet.port>8989</cargo.servlet.port>
						</properties>
					</configuration>
				</configuration>
				<executions>  <!--配置插件在什么情况下执行-->
					<execution>  
						<id>cargo-run</id>  
						<phase>install</phase>  <!--生命周期的阶段-->
						<goals>  
							<goal>run</goal> <!--插件的目标--> 
						</goals>  
					</execution>  
				</executions>
			</plugin>
		</plugins>
	</build>

需在命令行中启动,在Eclipse启动可以,但不能停止


ctrl+c关闭


Maven官方网址:http://mvnrepository.com,寻找相关依赖

猜你喜欢

转载自blog.csdn.net/mumihahaha/article/details/79524690