Maven详解

1.什么是Maven

      Maven是apache下的开源项目,项目管理工具,管理java项目。

1、项目对象模型 (Project Object Model)

      POM对象模型,每个maven工程中都有一个pom.xml文件,定义工程所依赖的jar包、本工程的坐标、打包运行方式。。

2、依赖管理系统(基础核心 )

       maven通过坐标对项目工程所依赖的jar包统一规范管理。

3、maven定义一套项目生命周期

清理、初始化、编译、测试、报告 、打包、部署、站点生成

4、一组标准集合

       强调:maven工程有自己标准的工程目录结构、定义坐标有标准。

5、maven 管理项目生命周期过程都是基于插件完成的

Maven详解_第1张图片

2.Maven仓库

Maven详解_第2张图片

1、中央仓库

   就是远程仓库,仓库中jar由专业团队(maven团队)统一维护。

   中央仓库的地址:http://repo1.maven.org/maven2/

2、本地仓库

     相当于缓存,工程第一次会从远程仓库(互联网)去下载jar 包,将jar包存在本地仓库(在程序员的电脑上)。第二次不需要从远程仓库去下载。先从本地仓库找,如果找不到才会去远程仓库找。

3、私服

       在公司内部架设一台私服,其它公司架设一台仓库,对外公开。

3.Maven环境搭建

(一)Maven下载

可以到maven的官网下载  

http://maven.apache.org/download.cgi

Maven详解_第3张图片

我们将下载的压缩包解压到D盘根目录,D盘根目录会有下面的文件夹apache-maven-3.3.9

(二)本地仓库配置

1. 拷贝本地仓库

将资料中的repository_ssh.zip解压到D盘

2. 配置本地仓库

打开maven的安装目录中conf/ settings.xml文件,在这里配置本地仓库:

D:\repository_ssh

这里的意思是配置本地仓库的目录为D:\repository_ssh

(三)eclipse配置Maven

1. 配置Maven的安装目录

进入eclipse ,选择菜单windows - Preferences , 在左侧的树状导航中

Maven详解_第4张图片

点击add按钮,弹出窗口后选择maven的安装目录

Maven详解_第5张图片

然后点击Apply 

Maven详解_第6张图片

2. 配置User Settings

Maven详解_第7张图片

选择左侧树形导航的User Settings  ,选择Maven目录下conf下的settingsxml

然后点击Update Settings 、Reindex 和Apply按钮.

(四)重建本地仓库索引

选择菜单 window --> show View 

Maven详解_第8张图片

 

 

Maven详解_第9张图片

选择 Rebuild  Index  重新创建索引

4、Maven入门

(一)创建工程

1. 选择菜单  File ->new -> Other

Maven详解_第10张图片

选择Maven下的Maven Project,   Next

2. 选中下图红框部分的复选框(跳过骨架),next

Maven详解_第11张图片

3. 定义工程坐标

maven对所有工程管理基于坐标进行管理。

Maven详解_第12张图片

坐标包括:

Group Id:项目的名称,项目名称以域名的倒序,比如:cn.itcast.mavendemo

Artifact Id:模块名称(子项目名称)

Version:模块的版本,snapshot(快照版,没有正式发行)、release(正式发行版本)

输入后,Finish 。完成后如下图

Maven详解_第13张图片

工程目录结构说明:

project

       /src/main/java      主体程序 java源文件(不要放配置文件)

       /src/main/resources  主体程序所需要的配置文件(不要放java文件)

       /src/test/java       单元测试程序 java源文件

       /src/test/resources   单元测试程序所用的配置文件

       /target            编译输出目录

pom.xml          Maven进行工作的主要配置文件。   

4. 编写代码

(1)在src/main/java 目录下创建包cn.itcast.mavendemo

(2)在包cn.itcast.mavendemo下创建HelloWorld 类

package cn.itcast.mavendemo;

 

public class HelloWorld {

 

   public static void main(String[] args) {

      System.out.println("Hello World!!");

   }

}

(二)设置编译版本

我们现在的Maven工程默认是JDK1.5 ,我们需要将编译版本改为JDK1.7

<build> 

      <plugins>

          <plugin> 

              <groupId>org.apache.maven.pluginsgroupId> 

              <artifactId>maven-compiler-pluginartifactId> 

              <version>2.3.2version> 

              <configuration> 

                  <source>1.7source> 

                  <target>1.7target> 

              configuration> 

          plugin> 

      plugins> 

   build> 

将上边的配置信息粘贴到pom.xml中。

点击工程右键  Maven ->  Update Project ...

弹出窗口后OK .操作后 ,编译版本改为 1.7

Maven详解_第14张图片

(三)添加依赖

Maven详解_第15张图片

右键点击工程  Maven -- >  Add Dependency

Maven详解_第16张图片

添加后打开pom.xml,发现多了以下信息

  <dependencies>

    <dependency>

        <groupId>org.hibernategroupId>

        <artifactId>hibernate-coreartifactId>

        <version>5.0.7.Finalversion>

    dependency>

  dependencies>

我们再看工程目录下的Maven Dependecies 下又多了很多jar包

Maven详解_第17张图片

奇怪了!我只是加了一个hibernate的核心包,为什么会多出这么多jar包呢?

这是因为hibernate的核心包本身又会依赖其它的jar包,所以导入hibernate包自动会添加hibernate所依赖的包。

(四)项目生命周期(了解)

Maven有三套相互独立的生命周期,分别是:clean、default、site。clean主要是清理项目、default是Maven最核心的的构建项目、site是生成项目站点。每一个大的生命周期又分为很多个阶段。后面的阶段依赖于前面的阶段,这点有点像Ant的构建依赖。生命周期本身相互独立,用户可以仅仅调用生命周期的某一个阶段,也就是说用户调用了default周期的任何阶段,并不会触发clean周期以及site周期的任何事情。三大生命周期蕴含着小小的阶段,我们按顺序看一下:

Maven详解_第18张图片

(1)clean周期:

pre-clean:准备清理

clean:真正的清理工作

post-clean:执行清理后的一些后续工作

(2)default周期:

validate:验证

initialize:初始化配置

generate-sources:生成源代码编译目录

process-sources:处理项目主资源文件,复制资源文件到outputclasspath

generate-resources:生成资源目录

process-resources:处理资源文件

complie:编译源代码

process-classes:处理编译后文件

generate-test-sources:生成测试目录

process-test-sources:处理项目测试资源文件,复制测试资源文件到outputclasspath

generate-test-resources:生成测试资源文件

process-test-resources:处理测试资源文件

test-compile:编译测试代码

process-test-classes:处理测试代码

test:单元测试运行测试代码

prepare-package:打包前的准备

package:将编译好的代码打包成为jar或者war或者ear等等

pre-integration-test:准备整体测试

integration-test:整体测试

post-integration-test:为整体测试收尾

verify:验证

install:安装到本地Maven库

deploy:将最终包部署到远程Maven仓库

(3)site周期:

pre-site:准备生成站点

site:生成站点及文档

post-site:站点收尾

site-deploy:将生成的站点发布到服务器上

(五)常见命令

maven通过命令对工程进行清理、编译、测试、打包、部署。

点击工程右键 ,Run As (或Debug As ) -- >  Maven  Build ... 

Maven详解_第19张图片

常用命令如下:

compile:编译

clean:清理,将target下的class文件清理

test: 执行单元测试类,执行src/test/java下的类

package :将java工程打成jar、war。

install:安装命令,将将程的jar发布到本地仓库

发布到仓库,目录按照本工程定义的坐标生成目录

扩展:

其实我们所执行的这些命令是对maven原生命令的封装,我们可以在命令提示符下直接通过这些命令来对代码进行编译打包等操作,格式如下:

mvn 命令名称        运行不调试

mvnDebug 命令名称   调试运行

我们要在命令提示符下执行maven命令必须配置下面两个环境变量

MAVEN_HOME    D:\apache-maven-3.3.9

PATH             %MAVEN_HOME%\bin

测试Maven环境 ,在控制台输入mvn -v ,有下列信息输出表示Maven配置正常。

Maven详解_第20张图片

 

5、创建SSH2工程(重点)

需求,用SSH2集成框架搭建工程mavenweb ,功能为单表的列表查询。

表名称 dep  (部门表)

字段名称

字段类型

字段含义

uuid

bigint

主键:部门编号

name

varchar

部门名称

tele

varchar

部门电话

(一)创建war工程

1. 选择菜单  File ->new -> Other

Maven详解_第21张图片

选择Maven下的Maven Project, next

2. 选中下图红框部分的复选框(跳过骨架),next

Maven详解_第22张图片

3. 定义工程坐标

Maven详解_第23张图片

注意打包方式选择war工程。

4. 手动添加web.xml 

(1)在src /main/webapp 目录下手动创建WEB-INF目录

(2)将资源文件夹下的web.xml拷贝至WEB-INF目录

Maven详解_第24张图片

5. 添加插件

将下列配置拷贝至pom.xml 

 <build> 

      <plugins>

          <plugin> 

              <groupId>org.apache.maven.pluginsgroupId> 

              <artifactId>maven-compiler-pluginartifactId> 

              <version>2.3.2version> 

              <configuration> 

                  <source>1.7source> 

                  <target>1.7target> 

              configuration> 

          plugin> 

          <plugin>

                <groupId>org.apache.tomcat.mavengroupId>

                <artifactId>tomcat7-maven-pluginartifactId>

                <configuration>

                   

                    <port>8080port>

                   

                    <path>/path>

                configuration>

          plugin>

      plugins> 

    build>

 

点击工程右键  Maven ->  Update Project ...

  1. 在pom.xml中添加servlet-api

因为我们创建的是war工程 ,需要response 和request 等对象,而这些对象是在servlet-api中的,所以我们需要添加servlet-api ,才能保证工程正常编译。

注意:必须指定scope为provided , 这是设置依赖范围,我们后边的章节会详细讲解。如果设置则启动会报错。

  <dependencies>

    <dependency>

        <groupId>javax.servletgroupId>

        <artifactId>servlet-apiartifactId>

        <version>2.5version>

        <scope>providedscope>

    dependency>

  dependencies>

添加后更新工程

7. 创建index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>测试页面title>

head>

<body>

开启神秘的Maven世界~

body>

html>

部署运行测试   执行命令

tomcat7:run

用浏览器测试,地址: http://localhost:8080/index.jsp

(二)添加SSH依赖

SSH2框架需要添加的依赖如下:

<dependencies>

  <dependency>

    <groupId>javax.servletgroupId>

    <artifactId>servlet-apiartifactId>

    <version>2.5version>

    <scope>providedscope>

  dependency>

  <dependency>

    <groupId>org.hibernategroupId>

    <artifactId>hibernate-coreartifactId>

    <version>5.0.7.Finalversion>

  dependency>

  <dependency>

    <groupId>org.springframeworkgroupId>

    <artifactId>spring-coreartifactId>

    <version>4.2.4.RELEASEversion>

  dependency>

  <dependency>

    <groupId>org.springframeworkgroupId>

    <artifactId>spring-beansartifactId>

    <version>4.2.4.RELEASEversion>

  dependency>

  <dependency>

    <groupId>org.springframeworkgroupId>

    <artifactId>spring-contextartifactId>

    <version>4.2.4.RELEASEversion>

  dependency>

  <dependency>

    <groupId>org.springframeworkgroupId>

    <artifactId>spring-ormartifactId>

    <version>4.2.4.RELEASEversion>

  dependency>

  <dependency>

    <groupId>org.springframeworkgroupId>

    <artifactId>spring-testartifactId>

    <version>4.2.4.RELEASEversion>

  dependency>

  <dependency>

    <groupId>org.springframeworkgroupId>

    <artifactId>spring-context-supportartifactId>

    <version>4.2.4.RELEASEversion>

  dependency>

  <dependency>

    <groupId>org.springframeworkgroupId>

    <artifactId>spring-aopartifactId>

    <version>4.2.4.RELEASEversion>

  dependency>

  <dependency>

    <groupId>org.springframeworkgroupId>

    <artifactId>spring-webartifactId>

    <version>4.2.4.RELEASEversion>

  dependency>

  <dependency>

    <groupId>org.aspectjgroupId>

    <artifactId>aspectjweaverartifactId>

    <version>1.8.7version>

  dependency>

  <dependency>

    <groupId>org.apache.strutsgroupId>

    <artifactId>struts2-coreartifactId>

    <version>2.3.24version>

  dependency>

  <dependency>

    <groupId>org.apache.strutsgroupId>

    <artifactId>struts2-spring-pluginartifactId>

    <version>2.3.24version>

  dependency>

  <dependency>

    <groupId>mysqlgroupId>

    <artifactId>mysql-connector-javaartifactId>

    <version>5.1.6version>

  dependency>

  <dependency>

    <groupId>jstlgroupId>

    <artifactId>jstlartifactId>

    <version>1.2version>

  dependency>

dependencies>

(三)SSH工程搭建

1. 建立包结构

Maven详解_第25张图片

  1. 添加spring配置文件

   拷贝资源下的配置文件文件夹中的applicationContext.xml

3. 添加struts配置文件

xml version="1.0" encoding="UTF-8" ?>

DOCTYPE struts PUBLIC

    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"

    "http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>

    <package name="default" namespace="/" extends="struts-default">         

    package>

struts>

4. 修改web.xml 配置文件,添加以下配置

<listener>

    <listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>

    listener>

    <context-param>

        <param-name>contextConfigLocationparam-name>

        <param-value>classpath*:applicationContext.xmlparam-value>

    context-param>

    <filter>

       <filter-name>openSessionInViewfilter-name>

    <filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilterfilter-class>

    filter>

    <filter-mapping>

        <filter-name>openSessionInViewfilter-name>

        <url-pattern>/*url-pattern>

    filter-mapping>

    <filter>

        <filter-name>struts2filter-name>  <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilterfilter-class>

    filter>

    <filter-mapping>

        <filter-name>struts2filter-name>

        <url-pattern>/*url-pattern>

    filter-mapping>

5. 编写实体类

package cn.itcast.mavenweb.domain;

/**

 * 部门

 * @author Administrator

 *

 */

public class Dep {

 

    private Long uuid;

    private String name;

    private String tele;

       

    public Long getUuid() {

        return uuid;

    }

    public void setUuid(Long uuid) {

        this.uuid = uuid;

    }

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    public String getTele() {

        return tele;

    }

    public void setTele(String tele) {

        this.tele = tele;

    }  

}

6. 编写映射文件

在src/main/resources 下创建包cn.itcat.mavenweb.domain

Maven详解_第26张图片

在此目录下创建映射文件dep.hbm.xml ,内容如下:

xml version="1.0" encoding="utf-8"?>

DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

    <class name="cn.itcast.mavenweb.domain.Dep" table="dep" >

        <id name="uuid" >          

        id>

        <property name="name" />    

        <property name="tele" />    

    class>

hibernate-mapping>

7. 创建数据访问层接口DepDao

package cn.itcast.mavenweb.dao;

 

import java.util.List;

 

import cn.itcast.mavenweb.domain.Dep;

 

/**

 * 部门Dao

 * @author Administrator

 *

 */

public interface DepDao {

   

    public List getList();

}

8. 创建数据访问类DepDaoImpl

package cn.itcast.mavenweb.dao.impl;

import java.util.List;

import org.springframework.orm.hibernate5.support.HibernateDaoSupport;

import cn.itcast.mavenweb.dao.DepDao;

import cn.itcast.mavenweb.domain.Dep;

/**

 * 部门数据访问类

 * @author Administrator

 *

 */

public class DepDaoImpl extends HibernateDaoSupport implements DepDao {

 

    @Override

    public List getList() {

       

        return (List) getHibernateTemplate().find("from Dep");

    }

}

9. 创建业务逻辑层接口

package cn.itcast.mavenweb.service;

 

import java.util.List;

 

import cn.itcast.mavenweb.domain.Dep;

 

/**

 * 部门业务层接口

 * @author Administrator

 *

 */

public interface DepService {

 

    /**

     * 全部列表

     * @return

     */

    public List getList();

}

 

10. 创建业务逻辑类

package cn.itcast.mavenweb.service.impl;

 

import java.util.List;

 

import cn.itcast.mavenweb.dao.DepDao;

import cn.itcast.mavenweb.domain.Dep;

import cn.itcast.mavenweb.service.DepService;

/**

 * 部门业务逻辑类

 * @author Administrator

 *

 */

public class DepServiceImpl implements DepService{

 

    private DepDao depDao;

   

    public void setDepDao(DepDao depDao) {

        this.depDao = depDao;

    }

 

    /**

     * 全部列表

     */

    public List getList() {

        // TODO Auto-generated method stub

        return depDao.getList();

    }

 

}

11. 创建action类

package cn.itcast.mavenweb.web.action;

 

import java.util.List;

 

import org.apache.struts2.ServletActionContext;

 

import com.opensymphony.xwork2.ActionContext;

 

import cn.itcast.mavenweb.domain.Dep;

import cn.itcast.mavenweb.service.DepService;

 

/**

 *  部门action

 * @author Administrator

 *

 */

public class DepAction {

 

    private DepService depService;

       

    public void setDepService(DepService depService) {

        this.depService = depService;

    }

 

 

    public String list(){

        List list = depService.getList(); 

        ServletActionContext.getRequest().setAttribute("list", list);

        return "list";

    }

   

}

 

  1. 编写spring配置文件的内容

    <bean id="depDao" class="cn.itcast.mavenweb.dao.impl.DepDaoImpl">

        <property name="sessionFactory" ref="sessionFactory">property>

    bean>

   

    <bean id="depService"  class="cn.itcast.mavenweb.service.impl.DepServiceImpl">

        <property name="depDao" ref="depDao">property>

    bean>

   

    <bean id="depAction" class="cn.itcast.mavenweb.web.action.DepAction">

        <property name="depService" ref="depService">property>

    bean>

 

13. 编写struts配置文件的内容

<action name="dep_*" class="depAction" method="{1}">

      <result name="list">/index.jspresult>

action>

14. 编写index.jsp的内容

<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>测试页面title>

head>

<body>

开启神秘的Maven世界~<br>

<c:forEach var="i" items="${list}">

${i.uuid}  ${i.name}  ${i.tele}<br>

c:forEach>

body>

html>

(四)定义变量

在pom.xml中插入配置

  <properties>

    <hinernate.version>5.0.7.Finalhinernate.version>

    <spring.version>4.2.4.RELEASEspring.version>

    <struts.version>2.3.24struts.version>

  properties>

此时相当于创建了三个变量。

我们在下面可以通过el表达式引用这三个变量的值

 <dependency>

    <groupId>javax.servletgroupId>

    <artifactId>servlet-apiartifactId>

    <version>2.5version>

    <scope>providedscope>

  dependency>

  <dependency>

    <groupId>org.hibernategroupId>

    <artifactId>hibernate-coreartifactId>

    <version>${hibernate.version}version>

  dependency>

  <dependency>

    <groupId>org.springframeworkgroupId>

    <artifactId>spring-coreartifactId>

    <version>${spring.version}version>

  dependency>

  <dependency>

    <groupId>org.springframeworkgroupId>

    <artifactId>spring-beansartifactId>

    <version>${spring.version}version>

  dependency>

  <dependency>

    <groupId>org.springframeworkgroupId>

    <artifactId>spring-contextartifactId>

    <version>${spring.version}version>

  dependency>

  <dependency>

    <groupId>org.springframeworkgroupId>

    <artifactId>spring-ormartifactId>

    <version>${spring.version}version>

  dependency>

  <dependency>

    <groupId>org.springframeworkgroupId>

    <artifactId>spring-testartifactId>

    <version>${spring.version}version>

  dependency>

  <dependency>

    <groupId>org.springframeworkgroupId>

    <artifactId>spring-context-supportartifactId>

    <version>${spring.version}version>

  dependency>

  <dependency>

    <groupId>org.springframeworkgroupId>

    <artifactId>spring-aopartifactId>

    <version>${spring.version}version>

  dependency>

  <dependency>

    <groupId>org.springframeworkgroupId>

    <artifactId>spring-webartifactId>

    <version>${spring.version}version>

  dependency>

  <dependency>

    <groupId>org.aspectjgroupId>

    <artifactId>aspectjweaverartifactId>

    <version>1.8.7version>

  dependency>

  <dependency>

    <groupId>org.apache.strutsgroupId>

    <artifactId>struts2-coreartifactId>

    <version>${struts.version}version>

  dependency>

  <dependency>

    <groupId>org.apache.strutsgroupId>

    <artifactId>struts2-spring-pluginartifactId>

    <version>${struts.version}version>

  dependency>

  <dependency>

    <groupId>mysqlgroupId>

    <artifactId>mysql-connector-javaartifactId>

    <version>5.1.6version>

  dependency>

  <dependency>

    <groupId>jstlgroupId>

    <artifactId>jstlartifactId>

    <version>1.2version>

  dependency>

这样做的好处是一旦版本发生变化,直接修改属性标签里的值即可。

(五)打war包

执行命令package 即可将war工程打成war工程。

Maven详解_第27张图片

6、聚合与继承

(一)聚合

随着技术的飞速发展和各类用户对软件的要求越来越高,软件本身也变得越来越复杂,然后软件设计人员开始采用各种方式进行开发,于是就有了我们的分层架构、分模块开发,来提高代码的清晰和重用。针对于这一特性,maven也给予了相应的配置。

我们在开发过程中,创建了2个以上的模块,每个模块都是一个独立的maven project,在开始的时候我们可以独立的编译和测试运行每个模块,但是随着项目的不断变大和复杂化,我们期望能够使用简单的操作来完成编译等工作,这时Maven给出了聚合的配置方式。

所谓聚合,顾名思义,就是把多个模块或项目聚合到一起,我们可以建立一个专门负责聚合工作的Maven 工程。

建立该project的时候,我们要注意以下几点:

1.聚合模块本身也做为一个Maven项目,它必须有自己的POM

2.它的打包方式必须为: pom

3.引入了新的元素:modules---module

4.版本:聚合模块的版本和被聚合模块版本一致

5.相对目录:每个module的值都是一个当前POM的相对目录

6.目录名称:为了方便的快速定位内容,模块所处的目录应当与其artifactId一致(Maven约定而不是硬性要求),总之,模块所处的目录必须和模块所处的目录相一致。

7.习惯约定:为了方便构建,通常将聚合模块放在项目目录层的最顶层,其它聚合模块作为子目录存在。这样当我们打开项目的时候,第一个看到的就是聚合模块的POM

8.聚合模块减少的内容:聚合模块的内容仅仅是一个pom.xml文件,它不包含src/main/Java、src/test/java等目录,因为它只是用来帮助其它模块构建的工具,本身并没有实质的内容。

9.聚合模块和子模块的目录:他们可以是父子类,也可以是平行结构,当然如果使用平行结构,那么聚合模块的POM也需要做出相应的更改。

(二)继承

我们在项目开发的过程中,可能多个模块独立开发,但是多个模块可能依赖相同的元素,比如说每个模块都需要Junit,使用spring的时候,其核心jar也必须都被引入,在编译的时候,maven-compiler-plugin插件也要被引入。这时我们采用继承,就不用在每个子模块分别定义了。

如何配置继承:

1.说到继承肯定是一个父子结构,那么我们在父工程中来创建一个parent project

2.: 作为父模块的POM,其打包类型也必须为POM

3.结构:父模块只是为了帮助我们消除重复,所以它也不需要src/main/java、src/test/java等目录

4.新的元素: , 它是被用在子模块中的

5.元素的属性:: 表示父模块POM的相对路径,在构建的时候,Maven会先根据relativePath检查父POM,如果找不到,再从本地仓库查找

6.relativePath的默认值: ../pom.xml

7.子模块省略groupId和version: 使用了继承的子模块中可以不声明groupId和version, 子模块将隐式的继承父模块的这两个元素

(三)聚合与继承的区别

Maven详解_第28张图片

聚合和继承通常是结合使用的,但是其作用是不同的。聚合是将多个模块的工程汇聚到一起,而继承则是指明某个模块工程要继承另一个模块功能。

7、构建多模块Maven工程(重点)

Maven多模块项目,适用于一些比较大的项目,通过合理的模块拆分,实现代码的复用,便于维护和管理。尤其是一些开源框架,也是采用多模块的方式,提供插件集成,用户可以根据需要配置指定的模块。

拆分规则:

(1)按业务模块拆分

Maven详解_第29张图片

  1. 按层拆分

Maven详解_第30张图片

创建Maven父工程(erp_parent)

(一)创建Maven父工程

Maven详解_第31张图片

 

Maven详解_第32张图片

 

Maven详解_第33张图片

 

Maven详解_第34张图片

 

 

 

 

注意:打包方式选择pom

Maven详解_第35张图片

工程创建完成,后打开pom.xml ,添加一下内容

  <properties>

    <hinernate.version>5.0.7.Finalhinernate.version>

    <spring.version>4.2.4.RELEASEspring.version>

    <struts.version>2.3.24struts.version>

  properties>

 

  <dependencies>

    <dependency>

        <groupId>javax.servletgroupId>

        <artifactId>servlet-apiartifactId>

        <version>2.5version>

    dependency>

 

    <dependency>

        <groupId>org.hibernategroupId>

        <artifactId>hibernate-coreartifactId>

        <version>${hinernate.version}version>

    dependency>

    <dependency>

        <groupId>org.springframeworkgroupId>

        <artifactId>spring-coreartifactId>

        <version>${spring.version}version>

    dependency>

    <dependency>

        <groupId>org.springframeworkgroupId>

        <artifactId>spring-beansartifactId>

        <version>${spring.version}version>

    dependency>

    <dependency>

        <groupId>org.springframeworkgroupId>

        <artifactId>spring-contextartifactId>

        <version>${spring.version}version>

    dependency>

    <dependency>

        <groupId>org.springframeworkgroupId>

        <artifactId>spring-context-supportartifactId>

        <version>${spring.version}version>

    dependency>

    <dependency>

        <groupId>org.springframeworkgroupId>

        <artifactId>spring-webartifactId>

        <version>${spring.version}version>

    dependency>

    <dependency>

        <groupId>org.springframeworkgroupId>

        <artifactId>spring-ormartifactId>

        <version>${spring.version}version>

    dependency>

    <dependency>

        <groupId>org.aspectjgroupId>

        <artifactId>aspectjweaverartifactId>

        <version>1.7.4version>

    dependency>

    <dependency>

        <groupId>org.apache.strutsgroupId>

        <artifactId>struts2-coreartifactId>

        <version>${struts.version}version>

        <exclusions>

            <exclusion>

                <groupId>javassistgroupId>

                <artifactId>javassistartifactId>

            exclusion>

        exclusions>

    dependency>

    <dependency>

        <groupId>org.apache.strutsgroupId>

        <artifactId>struts2-spring-pluginartifactId>

        <version>${struts.version}version>

    dependency>

    <dependency>

        <groupId>mysqlgroupId>

        <artifactId>mysql-connector-javaartifactId>

        <version>5.1.6version>

    dependency>

   

    <dependency>

        <groupId>jstlgroupId>

        <artifactId>jstlartifactId>

        <version>1.2version>

    dependency>

  dependencies>

 

  <build> 

      <plugins>

          <plugin> 

              <groupId>org.apache.maven.pluginsgroupId> 

              <artifactId>maven-compiler-pluginartifactId> 

              <version>2.3.2version> 

              <configuration> 

                  <source>1.7source> 

                  <target>1.7target> 

              configuration> 

          plugin>

      plugins>     

  build>  

(二)创建Maven子模块

选择菜单file -- new -- other 

Maven详解_第36张图片

Maven详解_第37张图片

Maven详解_第38张图片

 

 

一共需要建立4个子模块

erp_domain   存放实体包

erp_dao      存放数据访问接口及实现类

erp_service   存放业务逻辑层接口及实现类

erp_web     存放action类代码和前端代码  (注意:此模块的packaging选择war

Maven详解_第39张图片

在erp_web 工程中展开src\main\webapp目录,建立WEB-INF文件夹,并将web.xml拷贝到文件夹中。

Maven详解_第40张图片

将struts2和spring配置文件放入erp_web 的 src/main/resources 下面

Maven详解_第41张图片

构建完各个模块后,会发现父工程的pom.xml中自动出现如下信息:

  <modules>

    <module>erp_domainmodule>

    <module>erp_daomodule>

    <module>erp_servicemodule>

    <module>erp_webmodule>

  modules>

这部分的配置信息是父工程聚合子模块的信息

而子模块的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/xsd/maven-4.0.0.xsd">

  <modelVersion>4.0.0modelVersion>

  <parent>

    <groupId>cn.itcast.erpgroupId>

    <artifactId>erp_parentartifactId>

    <version>0.0.1-SNAPSHOTversion>

  parent>

  <artifactId>erp_domainartifactId>

project>

(三)建立Maven子模块之间的依赖

我们将刚才我们的mavenweb工程的代码分别拷贝到各自的子模块:

将cn.itcast.mavenweb.domain包下的类拷贝到erp_domain的src/main/java下,将cn.itcast.mavenweb.domain下的映射文件拷贝到erp_domain的src/main/resources下。

Maven详解_第42张图片

将cn.itcast.mavenweb.dao和cn.itcast.mavenweb.dao.impl 下的接口和类都拷贝到erp_dao工程。

Maven详解_第43张图片

为什么出红叉了呢?这是因为数据访问层会用到实体类。而erp_dao工程是没有实体类的,实体类在erp_domain工程中,这就需要建立工程之间的依赖

各模块的依赖关系如下:

erp_dao 依赖erp_domain

erp_service 依赖erp_dao

erp_web依赖erp_service

我们现在建立erp_dao和erp_domain的依赖:

工程右键  Maven -->  Add Dependency

Maven详解_第44张图片

步骤与添加依赖jar包类似,操作后erp_dao红叉消失

erp_dao的pom.xml内容如下:

  <dependencies>

    <dependency>

        <groupId>cn.itcast.erpgroupId>

        <artifactId>erp_domainartifactId>

        <version>0.0.1-SNAPSHOTversion>

    dependency>

  dependencies>

按照同样的方法建立其它的工程依赖

(四)代码编写

(1)将cn.itcast.mavenweb.service和cn.itcast.mavenweb.service.impl下的接口和类拷贝到erp_service工程下。

(2)将cn.itcast.mavenweb.web.action下的类拷贝到erp_web工程下,将applicationContext.xml和struts.xml拷贝到erp_web工程的src/main/resources 目录下,将index.jsp拷贝到webapp目录下。

(五)配置文件拆分

(1)在erp_dao工程下创建applicationContext_datasource.xml 用于配置数据源信息

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">

        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>

        <property name="url" value="jdbc:mysql://127.0.0.1:3306/erpdb?useUnicode=true&characterEncoding=UTF8"/>

        <property name="username" value="root"/>

        <property name="password" value="123456"/>

    bean>

       

    <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">

        <property name="dataSource" ref="dataSource"/>

        <property name="hibernateProperties">

            <props>

                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialectprop>

                <prop key="hibernate.show_sql">trueprop>

                <prop key="hibernate.format_sql">falseprop>

            props>

        property>

        <property name="mappingLocations">

            <value>classpath:cn/itcast/mavenweb/domain/*.hbm.xmlvalue>

        property>

    bean>

   

创建applicationContext_dao.xml 用于存放所有的dao类的bean

    <bean id="depDao" class="cn.itcast.mavenweb.dao.impl.DepDaoImpl">

        <property name="sessionFactory" ref="sessionFactory">property>

    bean>

(2)在erp_service工程下创建applicationContext_tx.xml,用于配置声明式事务相关配置信息

   

    <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">

        <property name="sessionFactory" ref="sessionFactory"/>

    bean>

       

    <tx:advice id="advice" transaction-manager="transactionManager">

        <tx:attributes>       

          <tx:method name="do*" propagation="REQUIRED"/>

          <tx:method name="add*" propagation="REQUIRED"/>

          <tx:method name="update*" propagation="REQUIRED"/>

          <tx:method name="save*" propagation="REQUIRED"/>

          <tx:method name="delete*" propagation="REQUIRED"/>

          <tx:method name="*" read-only="true"/>

        tx:attributes>

    tx:advice>

   

    <aop:config>

        <aop:pointcut id="serviceMethod" expression="execution(* cn.itcast.mavenweb.service.impl.*.*(..))"/>

        <aop:advisor pointcut-ref="serviceMethod" advice-ref="advice" />

    aop:config>

   

编写applicationContext_service.xml 用于配置所有的业务逻辑层信息

    <bean id="depService"  class="cn.itcast.mavenweb.service.impl.DepServiceImpl">

        <property name="depDao" ref="depDao">property>

    bean>

(3)在erp_web工程下创建applicationContext_web.xml

<bean id="depAction" class="cn.itcast.mavenweb.web.action.DepAction">

        <property name="depService" ref="depService">property>

bean>

(六)运行测试及打包

选择erp_parent工程,执行命令package 进行打包(war)

这里我们需要注意一点,我们在将配置文件分到每个子模块后,打成的war包中不并包括其它jar工程的配置文件,这些jar工程的配置文件被直接打到jar包中,这时web.xml中下列配置就可以找到这些jar包中的配置文件:

<context-param>

        <param-name>contextConfigLocationparam-name>

        <param-value>classpath*:applicationContext*.xmlparam-value>

context-param>

classpath 和 classpath* 区别:

classpath:只会到你指定的class路径中查找找文件;

classpath*:不仅包含class路径,还包括jar文件中(class路径)进行查找.

8、依赖管理

(一)依赖范围

依赖范围是用来控制依赖与3种classpath(编译classpath,测试classpath,运行classpath)的关系。maven有以下几种依赖范围:

Maven详解_第45张图片

1、compile 编译、测试、运行,A在编译时依赖B,并且在测试和运行时也依赖。

       strus-core、spring-beans

       打到war包或jar包。

2、provided 编译、和测试有效,A在编译和测试时需要B。

       比如:servlet-api就是编译和测试有用,在运行时不用(tomcat容器已提供)。

       不会打到war

3、runtime:测试、运行有效。

       比如:jdbc驱动包 ,在开发代码中针对java的jdbc接口开发,编译不用。

       在运行和测试时需要通过jdbc驱动包(mysql驱动)连接数据库,需要的!!

       会打到war

4、test:只是测试有效,只在单元测试类中用。

       比如:junit

       不会打到war

如何设置依赖范围呢?

比如我们要将mysql驱动的依赖设置为runtime范围,配置如下:

    <dependency>

        <groupId>mysqlgroupId>

        <artifactId>mysql-connector-javaartifactId>

        <version>5.1.6version>

        runtime

    dependency>

将servlet依赖设置为provided

    <dependency>

        <groupId>javax.servletgroupId>

        <artifactId>servlet-apiartifactId>

        <version>2.5version>

        provided

    dependency>

如果是compile就不需要设置了,因为compile是scope的默认值。关于test范围我们在后边讲解单元测试时再做演示。

重新执行打包为war , 会发现servlet-api.jar已经不存在。

(二)依赖传递

什么是依赖传递?

A->B(compile)     第一关系: a依赖b   compile

B->C(compile)      第二关系: b依赖c   compile

我们看下图:

Maven详解_第46张图片

1、纵坐标:直接依赖

       A依赖B,B是A的直接依赖。

       在A的pom.xml中添加B的坐标。

2、横坐标:传递依赖

       B依赖C,C是A的传递依赖。

3、中间部分:传递依赖的范围,A依赖C的范围。

Maven详解_第47张图片

 

(三)依赖调节原则(了解)

情景再现:

项目A依赖于项目B,项目B依赖于项目C(v1), 项目A依赖于项目D,项目D依赖于项目E,项目E依赖于C(v2),

1、A--->B---->C(v1) ,    

2、A------>D---->E----->C(v2)

项目A隐形依赖了两个版本的C,那到底采用哪个版本呢?

分析:

依赖调解第一原则路径优先,很明显,第一种路径深度是3,第二种路径深度是4,所以,maven会采用C(v1)

依赖调解第二原则:声明优先,假设路径深度相等,那么声明在前的会被引用。

(四)版本锁定

在Maven中dependencyManagement的作用其实相当于一个对所依赖jar包进行版本管理的管理器。

       pom.xml文件中,jar的版本判断的两种途径

1.如果dependencies里的dependency自己没有声明version元素,那么maven就会倒dependencyManagement里面去找有没有对该artifactId和groupId进行过版本声明,如果有,就继承它,如果没有就会报错,告诉你必须为dependency声明一个version。

2.如果dependencies中的dependency声明了version,那么无论dependencyManagement中有无对该jar的version声明,都以dependency里的version为准。

(五)排除依赖

我们仔细观察Maven Dependencies 下的jar包,会发现存在了两个javassist包,一个是 javassist-3.18.1-GA.  ,另一个是javassist-3.11.0-GA  。这是因为我们引入三大框架的jar包,hibernate依赖javassist-3.18.1-GA  ,而struts 依赖javassist-3.11.0-GA 。这就是我们通常所说的jar包版本冲突,如果这两个jar包同时存在,会导致后续某些操作会存在问题(比如openSessionInView失效),所以需要排除低版本的jar包。

如何来排除依赖呢?添加下面红色字体的部分。作用是排除struts中依赖的javassist的jar

    <dependency>

        <groupId>org.apache.strutsgroupId>

        <artifactId>struts2-coreartifactId>

        <version>2.3.24version>

       

           

                javassist

                javassist

           

       

    dependency>

添加后发现javassist-3.11.0-GA消失。

9、单元测试

向erp_dao工程添加junit

    <dependency>

        <groupId>junitgroupId>

        <artifactId>junitartifactId>

        <version>4.9version>

        <scope>testscope>

    dependency>

在erp_dao工程src/test/java 下创建测试类

package erp_dao;

 

import org.junit.Test;

import org.junit.runner.RunWith;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.test.context.ContextConfiguration;

import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

 

import cn.itcast.mavenweb.dao.DepDao;

 

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(locations={"classpath:applicationContext_dao.xml","classpath:applicationContext_datasource.xml"})

public class TestDepDao {

 

    @Autowired

    private DepDao depDao;

       

    @Test

    public void testList(){

        System.out.println("test!!");

        System.out.println(depDao.getList().size());

    }

   

}

 

右键点击你要测试的方法

 

选择右键菜单  Run as --> JUnit test

如果是绿色的显示表示通过测试

Maven详解_第48张图片

如果是红色的显示表示未通过测试

Maven详解_第49张图片

如果有测试类未通过,直接打包,会出现以下提示

Maven详解_第50张图片

表示该工程没有成功,因为测试未通过。也就是说打包操作是要求在所有的测试用例都通过的基础上才进行。

另外,通过我们观察,发现测试类和JUnit 并不会打包到war包中

10、私服nexus

(一)nexus安装

1. 安装nexus

将资源下的私服文件夹中的nexus-2.12.0-01-bundle.zip 解压

Maven详解_第51张图片

在命令提示符下,进入此目录,敲入命令

nexus install

如有下列提示则证明安装成功。

Maven详解_第52张图片

 

如果想卸载,命令为:

nexus uninstall

2. 启动nexus

在服务中找到nexus ,右键启动

Maven详解_第53张图片

3. 进入nexus

打开浏览器输入地址:http://localhost:8081/nexus

Maven详解_第54张图片

点击右上角的Log In  ,在弹出窗口中输入username为admin , password为admin123 ,点击Log In按钮

Maven详解_第55张图片

(二)构建索引

刚刚安装好的nexus是无法直接搜索到jar包的,必须下载索引才可以正常使用。

我们到中央仓库地址 http://repo.maven.apache.org/maven2/.index/ 下载以下两个索引压缩文件

nexus-maven-repository-index.gz
nexus-maven-repository-index.properties

这两个文件一般在此页面的最后的位置,另外还需要在网上下载一个名为indexer-cli-5.1.1.jar 的jar包

将以下三个文件放入一个文件夹

Maven详解_第56张图片

cmd执行:

java -jar indexer-cli-5.1.1.jar -u nexus-maven-repository-index.gz -d indexer

执行后生成目录indexer,目录下的文件是索引文件,如下图

将D:\nexus-2.12.0-01-bundle\sonatype-work\nexus\indexer\central-ctx 目录下的文件删除,将上边的索引文件拷贝到此目录下。

拷贝后重新启动nexus,然后进入nexus搜索jar包发现可以进行搜索了。

Maven详解_第57张图片

(三)仓库类型

Maven详解_第58张图片

1、hosted:宿主仓库,自己项目的jar要放到hosted类型的仓库中。

2、proxy:代理仓库,代理中央仓库

3、virtual:虚拟仓库,存储了maven1的构件,一般不用。

4、group:仓库组,将一些仓库组成一个组,自己项目连接仓库组去下载jar包。

       平常开发中都去连接仓库组,仓库组中包括:hosted、proxy等。

仓库所在的文件夹见下面的截图:

 

Maven详解_第59张图片

(四)镜像配置

nexus已经安装好了,我们要开始使用它了。现在我们需要在maven的配置文件settings.xml中配置镜像,让maven找私服,而不是直接到中央仓库下载。

打开maven的配置文件settings.xml,添加如下配置:

   

   

      nexus

      *

      http://localhost:8081/nexus/content/groups/public/

   

mirrors为镜像组,可以配置多个mirror(镜像),我们这里配置的是nexus中的中央代理仓库。

配置好后,我们需要创建一个项目来测试一下,看看是不是可以通过nexus来下载jar包。

测试步骤:

创建maven工程(jar),在pom.xml中添加依赖,观察nexus中是否下载了相应的jar包,目录为 nexus-2.12.0-01-bundle\sonatype-work\nexus\storage\central

(五)发布自己的工程jar到nexus

1. 创建maven工程itcastutil (jar)

坐标信息:  Group Id : cn.itcast.util 

            Artifact Id: itcastutil

创建包cn.itcast.util

创建类DateUtil

package cn.itcast.util;

 

import java.util.Calendar;

import java.util.Date;

/**

 * 日期工具类

 * @author Administrator

 *

 */

public class DateUtil {

   

    /**

     * 获取当前年份

     * @return

     */

    public static int getYear(){

       

        Calendar calendar=Calendar.getInstance();

        calendar.setTime(new Date());

        return  calendar.get(Calendar.YEAR);

    }

}

在pom.xml中引入如下配置信息

<distributionManagement>

    <repository>

        <id>releasesid>

        <url>

             http://localhost:8081/nexus/content/repositories/releases/

       url>

    repository>

    <snapshotRepository>

        <id>snapshotsid>

        <url>

            http://localhost:8081/nexus/content/repositories/snapshots/

        url>

    snapshotRepository>

  distributionManagement>

2. 在Maven中配置

将以下配置信息放入maven的settings.xml中

  <servers>

    <server>

      <id>releasesid>

      <username>adminusername>

      <password>admin123password>

    server>  

    <server>

      <id>snapshotsid>

      <username>adminusername>

      <password>admin123password>

    server>

  servers>

注意:settings.xml 配置 和 pom.xml 对应!

然后执行命令  deploy  ,有如下提示表示部署成功

Maven详解_第60张图片

我们在私服中进行查询,发现可以查到刚才我们上传的jar

(六)发布第三方的工程jar到nexus

有很多jar包由于版权等问题,并不会出现在中央仓库中,比如oracle的驱动,那如何将这类jar包放在nexus中呢?我们看下列操作步骤:

(1)选择左侧菜单的Repositories,  在Repositories窗口中选择3rd party

Maven详解_第61张图片

(2)在3rd party窗口中选择Artifact Upload

Maven详解_第62张图片

 

(3)在Artifact Upload选项卡中填写坐标,并上传jar包。

Maven详解_第63张图片

上传jar包选择oracle的驱动。

Maven详解_第64张图片

 

填写坐标

Maven详解_第65张图片

有下列提示则为上传成功

Maven详解_第66张图片

上传成功后可以在3rd party库中找到此jar包

Maven详解_第67张图片

11、SVN+Maven在项目中的应用

(一)设置排除文件的类型

Maven详解_第68张图片

逐个添加以下Pattern:

.class

target

(二)SVN服务端安装配置与客户端连接

(1)安装SVN服务端

(2)新建仓库、用户与组,并为仓库分配组

(3)打开Eclipse的SVN资源库视图,右键点击空白 弹出菜单  新建 ---->资源库位置,输入服务端的URL Finish ,输入SVN用户名和密码。

(三)将Maven工程(单模块)代码签入SVN

步骤如下:

  1. 选择工程 右键  Team ---->  Share Project

Maven详解_第69张图片

弹出窗口后,next 

Maven详解_第70张图片

Maven详解_第71张图片

 

Maven详解_第72张图片

 

Maven详解_第73张图片

操作后效果如下:

Maven详解_第74张图片

 

 

 

现在此工程的内容并没有签入到SVN服务器中。

  1. 选择工程 右键  Team ---->  提交

Maven详解_第75张图片

 

Maven详解_第76张图片

操作后效果如下:

Maven详解_第77张图片

(四)从SVN中签出工程代码(单模块)

  1. 刷新SVN资源

Maven详解_第78张图片

  1. 选中要检出的项目文件夹,右键弹出菜单中选择 检出为....

Maven详解_第79张图片

  1. 弹出窗口后选择Finish

Maven详解_第80张图片

(五)Maven多模块工程签入SVN

  1. 选中父工程,右键  Team --->  Share Project

弹出窗口后的操作与签入单模块项目相同。

  1. 选中父工程,右键 Team --->  提交 。  操作后如下图:
  2. 我们看到这组工程中,erp_web 并没有svn的小图标。这时我们这样处理。

选中erp_web工程,右键  ,删除  。注意:不要选中下图的那个勾,我们只是在移除工程,并不是从磁盘删除文件。

  1. 选择菜单    文件  ---> 导入   如下图

Maven详解_第81张图片

导入Maven 下的Existing Maven Projects 

Maven详解_第82张图片

 

点击Browse ,选择erp_web工程

Maven详解_第83张图片

点击Finish 即可。

(六)从SVN中签出多模块工程

  1. 在SVN资源库中找到要签出的父工程目录

(2)在erp_parent(父工程)点右键  检出为....

Maven详解_第84张图片

点击Finish

Maven详解_第85张图片

(3)我们再次依次签出子模块项目。

你可能感兴趣的:(maven)