第4章--Maven

Maven实战

Java Web应用的部署:

手动式:

编译:javac -cp $CATALINA_HOME/lib/servlet-api.jar web-inf/classes/package/NoodlesServlet.java

打包:jar cvf Restaurant.war .

移动:mv Restaurant.war .../webapps/

项目复杂时:比如项目文件很多 -- IDE如eclipse -->

IDE式:(如eclipse)

下载第三方依赖包,去哪里下载?

目录结构怎么定?

编译、测试、打包、发行,构建流程怎么统一?

项目代码共享和依赖,怎么做?

版本如何管理?

--> 常用工具解决以上问题

Maven:

Java Web的项目构建和依赖管理工具

Apache基金会,开源,由Java写的

选择Maven的理由:

默认对于目录结构进行了限定(约定/惯例优先原则)

提供了三方依赖的管理--解决了依赖的维护问题

提供了一致的项目构建管理方式--减少了构建工作量,降低学习成本

插件式的架构,大量可重用插件

很方便集成了IDE

Maven的安装:

依赖JDK

官网:http://maven.apache.org/

$ brew install maven3

配置环境变量:

M2_HOME=/dir to maven/

PATH=$PATH:$M2_HOME/bin

Maven在构建项目的时候使用的配置:pom.xml

Maven项目的坐标:定位唯一项目(不可重复)

groupId:组织

artifactId:项目标识符

version:版本号(i.e. <version>1.0.0-SNAPSHOT</version>) (SNAPSHOT表示为开发版本)

其他属性:

packaging:类型,i.e. war

dependencies:依赖的项目

基本命令:

mvn archetype:generate:使用模板生成项目

mvn compile:编译

mvn test:单元测试

mvn package:打包War

mvn deploy:部署

mvn site:生成项目相关站点,在线文档之类

mvn clean:清理

mvn install:把包安装到本地仓库,可对其进行依赖

Tomcat插件:Tomcat官方提供的Maven插件:实现在Maven中内嵌启动一个Tomcat

mvn  help:describe -Dplugin=tomcat7

常见命令:

mvn tomcat7:run:启动一个嵌入的Tomcat实例

mvn tomcat7:deploy;mvn tomcat7:undeploy等

如何使用Maven管理Tomcat项目:

mkdir 创建目录

mvn archetype:generate -DgroupId=com.netease.restaurant -DartifactId=Restaurant -Dpackage=com.netease -Dversion=1.0.0-SNAPSHOT -DarchetypeArtifactId=maven-archetype-webapp 创建项目

生成的目录结构:

生成pom.xml:

缺少对servlet的依赖:在<dependencies></dependencies>中添加依赖

配置插件:编译器的插件和tomcat插件

在main下建立java/com/netease文件夹,并把上节课的Java文件拷贝到该文件夹下

拷贝静态资源到webapp文件夹下

替换WEB-INF下的web.xml为上节课写的web.xml

删除webapp下的index.jsp

运行项目:(注意,在Restaurant目录下运行,否则报错)

mvn tomcat7:run

and it is running

open another terminal tab and curl http://localhost:8080/Restaurant/noodles

it works.

多个项目之间的依赖问题:

Extend Noodle case:

Add a Kitchen for the purpose of handling with vegetable

Noodle is depended on Kitchen‘s vegetable

Solution:

Add a Kitchen project:

mvn archetype:generate -DgroupId=com.netease.restaurant -DartifactId=Kitchen -Dpackage=com.netease -Dversion=1.0.0-SNAPSHOT -DarchetypeArtifactId=maven-archetype-quickstart

// -DarchetypeArtifactId=maven-archetype-quickstart means its a java program rather than a web app

change App.java to Kitchen.java

package com.netease;

public class Kitchen {
public static String makeNoodles(String vegetable) {
if (vegetable == null) {
vegetable = "Tomato";
}
StringBuffer s = new StringBuffer();
s.append("<html><body>\n")
.append("<h1> Noodles with ")
.append(vegetable)
.append("</h1>\n")
.append("</body></html>");
return s.toString();
}
}

为了管理这两个子项目,在顶上创建pom.xml文件

<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.netease.restaurant</groupId>
<artifactId>restaurant-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name> Multi modules demo </name> <modules>
<module>Restaurant</module>
<module>Kitchen</module>
</modules>
</project> 

修改Kitchen子项目和Restaurant子项目的pom.xml文件(添加parent)

修改NoodleServlet.java:

加入对Kitchen的依赖:import com.netease.Kitchen;

修改vegetable部分的代码

由于NoodleServlet.java对Kitchen有了依赖,所以在Restaurant的pom.xml中加入dependency

NB:不要加入<packaging>jar</packaging>

在main目录下创建resources文件夹

修改完成,试一试:

mvn install (在最顶端的pom.xml所在目录下)

install成功,进入Restaurant目录,运行mvn tomcat7:run,成功

抛开bash,使用IDE试一试:

打开eclipse,安装maven插件

Help->Install New Software->...cannot find it:

solution -> https://stackoverflow.com/questions/8620127/maven-in-eclipse-step-by-step-installation

import the project:

import->Maven->Existing Maven Projects

Root Directory: maven-restaurant (with pom.xml)

How to run:

右键Restaurant->Run Configuration->Maven Build

Name: Restaurant

Base directory: ${workspace_loc:/Restaurant}

Goals: tomcat7:run

Run.

curl works.

Maven核心概念

约定(惯例)优先于配置:对于一些配置,给予默认值,就无需用户进行配置

约定有:

标准的目录结构:

*.java位于src/main/java目录下

*.class位于target目录下

配置文件 如web.xml 及静态文件 如SoyMilk.html 位于src/main/webapp目录下

etc.

项目描述符:pom.xml

Project Object Model 项目对象模型

一个pom.xml定义了一个maven项目

一个构建(artifact)等价于一个项目(project)

配置:

项目类型<packaging>:pom, jar, war

坐标:groupId, artifactId, version

属性:${property}

依赖 <dependency>:详见下

构建配置:i.e. maven-compiler插件的配置项

多项目、继承:<parent> <module>

项目总体信息:name, author等

问题:

多个项目配置重复

修改繁琐,比如依赖关系等

依赖版本不一致

配置管理混乱

怎么办?

借助OO思想:pom.xml的继承或覆盖 <parent>

常用继承项:

坐标属性,如groupId;依赖关系的配置;插件配置;一般性信息,如开发者信息等

继承的根在哪?

Super POM:所有的Maven项目的POM都继承Super POM(默认继承于Super POM)

Super POM是Maven的组成部分,定义了一组被所有项目共享的默认设置

如默认的文件位置,统一的插件配置,默认的中央仓库配置等

mvn help:effective-pom:把所有的继承项都继承下来之后的pom内容

i.e. in Restaurant, run mvn help:effective-pom --> tons of contexts are shown.

多模块构建中:

有一个parent项目,类型是pom,在该pom中定义<modeles><module>

子模块中配置<parent>以继承

NB: 统一配置提到parent项目中

依赖配置:

依赖坐标:groupId, artifactId, version

scope:依赖的范围,常见compile(default): 编译的时候用,打包的时候也会打包 / provided:编译时需要,打包时不需要

用于继承的pom配置:<dependencyManagement>

i.e.

<project>
<dependencyManagement>
<dependencies>
<dependency>
...

依赖如何寻找呢?

仓库:

用于统一存储所有maven项目,并提供共享的空间

仓库分类:

本地仓库:在本地目录内,很多时候用于缓存,下次使用无需重新从远程仓库下载。

默认路径 ~/.m2/repository

远程仓库:本地仓库查找优先,若找不到,到远程仓库查找并下载构件至本地仓库

项目在远程仓库中的路径 /<groupId>/<artifactId>/<version>/<artifactId>-<version>.<packaging>

远程仓库分类:

中央仓库:The Central Repository (自带仓库,有大部分项目,但在中国访问速度较慢)

其他公共仓库:如开源中国社区的maven镜像(oschina.net)

私服:比如公司内部(artifactory),相当于做一个代理

远程仓库的配置:

配置文件settings.xml(对所有依赖而言)

在pom.xml为依赖指定repositories(对单个依赖而言)

maven的架构:

插件(Plugin)式架构:很小的一个引擎+很多插件

所有的插件本身也是一个maven构件,由maven仓库管理

每一个插件提供多个目标(Goal)。调用目标的格式:mvn <Plugin>:<Goal>

maven的构建生命周期:

一组有序的阶段:编译,打包,部署等

会根据项目类型来确定每个阶段的动作

三套独立的生命周期:

一些命令:mvn clean/ mvn clean install /mvn package/

clean (删除项目的构建):pre-clean (预处理工作) --> clean (移出构建过程中生成的文件) --> post-clean (善后)

site (生成站点文档):pre-site --> site --> post-site -->site-deploy

default (详解):... -> process-resources -> compile -> ... -> test -> package -> install -> deploy

默认生命周期:整个项目构建的模型

validate:验证项目是否正确,是否拥有构建所需的完整信息

process-resources:复制资源文件到目录下,方便之后打包

compile:编译源代码

test:单元测试

package:打包编译好的代码,比如jar包、war包等

install:把调用的包安装到本地仓库

deploy:最后一个阶段,将包上传到远程仓库

maven的生命周期阶段是与目标绑定的,用户通过制定生命周期阶段会隐式地通过插件执行任务

i.e. mvn compile --> mvn compiler:compile

生命周期阶段 目标
process-resources resources:resources
compile compiler:compile
test surefire:test
install install:install
deploy deploy:deploy

对于package阶段,会根据项目类型不同,绑定到不同的目标

插件的配置:<plugins><plugin>......</plugin>...

查看configuration配置:mvn help:describe -Dplugin=<plugin_name> -Dgoal=<goal> -Ddetail

对于父pom的继承:pluginManagement

maven的内建插件:

i.e. help:mvn help:help -Ddetail=true

tomcat7将tomcat嵌入到maven的plugin中、exec简单的把一个jar包跑起来

maven的全局配置文件${M2_HOME}/conf/settings.xml

本地仓库、远程仓库等

pom文件summary:

项目关系配置:坐标、多项目、继承关系、依赖

属性:${property}

构建配置:插件配置、生命周期绑定

普通项目属性:作者信息、使用的开源协议

maven项目构建summary:

pom.xml:描述项目构建 -- 项目对象模型

依赖仓库:存放三方依赖 -- 依赖管理(从pom.xml读取配置信息)

构建生命周期,不同的构建阶段,depends on particular plugin

构建产出资源文件、源文件、中间产出文件、class文件、打包文件等

课程summary:

默认标准的目录结构

pom继承、Super POM、多项目管理

依赖及依赖配置、依赖配置的继承

仓库

构建生命周期

插件plugin、目标goal

Maven单元测验:http://www.itnose.net/detail/6632794.html

Maven单元作业:https://my.oschina.net/hava/blog/738572

http://www.cnblogs.com/windJcoder/p/5382143.html

_

Java开发工程师(Web方向) - 01.Java Web开发入门 - 第4章.Maven的更多相关文章

  1. Java开发工程师(Web方向) - 01.Java Web开发入门 - 第6章.蜂巢

    第6章--蜂巢 蜂巢简介 网站开发完,就需要测试.部署.在服务器上运行. 网易蜂巢: 采用Docker容器化技术的云计算平台 https://c.163.com 容器管理:容器可被视作为云主机的服务器 ...

  2. Java开发工程师(Web方向) - 01.Java Web开发入门 - 第3章.Tomcat

    第3章--Tomcat Tomcat安装与运行 Tomcat:目前最常用的基于java的web应用服务器 本课程中所有的Java代码最终都需要部署到Tomcat中运行 Tomcat的配置文件是XML的 ...

  3. Java开发工程师(Web方向) - 01.Java Web开发入门 - 第1章.Web应用开发概述

    第1章--Web应用开发概述 Web应用开发概述 浏览器-服务器架构(BS-architecture) browser/ App    ---- request ---->    server ...

  4. Java开发工程师(Web方向) - 01.Java Web开发入门 - 第5章.Git

    第5章--Git 版本控制简介 VCS (version control system) 版本控制系统:记录若干文件的修订记录的系统,帮助查阅/回到某个历史版本 LVCS本地 CVCS集中式(Cent ...

  5. Java开发工程师(Web方向) - 01.Java Web开发入门 - 第2章.HTTP协议简介

    第2章--HTTP协议简介 HTTP协议简介 Abstract: HTTP协议的特性,HTTP请求/响应的过程,HTTP请求/响应的报文格式等知识,最后会演示如何通过Chrome提供的开发者工具,去跟 ...

  6. Java后端开发工程师是否该转大数据开发?

    撰写我对java后端开发工程师选择方向的想法,写给在java后端选择转方向的人 背景 看到一些java开发工程师,对java后端薪酬太悲观了.认为换去大数据领域就会高工资.觉得java后端没有前途.我 ...

  7. Java软件工程师面试题:Java运行时异常与一般异常有什么不一样?

    异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误.java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕 ...

  8. 【转】测试开发工程师必备软硬能力&高级测试开发工程师需要具备什么能力?

    对于测试的基本知识,可以查看软件测试相关书籍 对于在公司成为一位优秀的测试开发工程师,我觉得下面这篇文章涉及到的是我们需要的,稍微进行改动https://blog.csdn.net/sinat_210 ...

  9. Android开发工程师面试题总结。android开发面试经验

    1:Android中五种数据存储方式分别是什么?他们的特点?     (1)SharedPreference,存放较少的五种类型的数据,只能在同一个包内使用,生成XML的格式存放在设备中 (2) SQ ...

随机推荐

  1. NSLog的各种打印格式符 和 打印CGRect时用NSStringFromCGRect

    打印CGRect时用NSStringFromCGRect 转载自:http://blog.csdn.net/chenyong05314/article/details/8219270 1. 打印CG开 ...

  2. ZooKeeper系列(3)--基于ZooKeeper实现主从协作

    基于ZooKeeper实现主从协作 主-从模式的模型中,主要包括三个角色: 主节点:主要负责监视新的节点和任务,分配任务给可用的从节点; 从节点:通过注册自己,确保主节点看到它们可以执行任务,收到主节 ...

  3. Knowledge Point 20180308 Dead Code

    不知道有没有前辈注意过,当你编写一段“废话式的代码时”会给出一个Dead Code警告,点击警告,那么你所写的废物代码会被编译器消除,那么如果你不理睬这个警告呢?编译后会是什么样的呢?下面我们写点代码 ...

  4. 编译问题: "ld: duplicate symbol _OBJC_METACLASS_$_XXX..."

    在新的SDK环境中调试百度地图的应用程序时,app总是意外退出,找了半天发现错误的原因是unrecognized selector xx的错误,另外还有报了一个Unknown class XXX in ...

  5. CF1066B Heaters(贪心)

    题意描述: Vova先生的家可以看作一个n×1的矩形,寒冷的冬天来了,Vova先生想让他的家里变得暖和起来.现在我们给你Vova先生家的平面图,其中111表示这个地方是加热炉,0表示这个地方什么也没有 ...

  6. 模板——最小生成树prim算法&&向前星理解

    通过最小生成树(prim)和最短路径优化引出的向前星存图,时至今日才彻底明白了.. head[i]存储的是父节点为i引出的最后一条边的编号, next负责把head[i]也就是i作为父节点的所有边连接 ...

  7. 03JavaScript 输出

    JavaScript 输出 JavaScript 没有任何打印或者输出的函数. 先来一点DOM的小知识点: DOM 解释: 您会经常看到 document.getElementById("i ...

  8. Vue——关于css过渡和动画那些事

    1. 单元素/组件的过渡transition Vue 提供了 transition 的封装组件,在下列情形中,可以给任何元素和组件添加进入/离开过渡 条件渲染 (使用 v-if) 条件展示 (使用 v ...

  9. php源码建博客2--实现单入口MVC结构

    主要: MVC目录结构 数据库工具类制作 创建公共模型类和公共控制器类 --------------文件结构:-------------------------------------- blog├─ ...

  10. php的基础知识(一)

    php(超文本预处理器)定义: php(外文名:php:Hertext Preprocessor,中文名:“超文本预处理器”)是一种通用的开源脚本语言.语法吸收了C语言.Java和Perl的特点,利于 ...