[关闭]
@MrXiao 2018-02-14T15:28:49.000000Z 字数 34297 阅读 966

Maven

Maven


1maven介绍
1.1项目开发中的问题及解决方案
问题1:开发人员将功能开发完成,编译、打包、运行正常,而后提交svn,测试人员从svn获取代码后编译、打包、运行报错。
解决方案:maven对项目生命周期进行定义,规范,开发人员和测试人员使用maven软件完成构建。

问题2:一个项目工程中时间长了开发人员也搞不清楚项目中的某些jar的作用,用在哪些模块,不得不每过一段时间对每个jar包梳理一遍。
解决方案:maven提供对项目依赖的第三方构件统一管理,通过规范的依赖管理来管理依赖的jar包。

问题3:项目使用的第三方框架要升级,从第三方框架官方网站下载jar包,加入工程,运行后报错,原来是第三方框架依赖的jar版本冲突了。
解决方案:maven提供对项目依赖的第三方构件统一管理,通过规范的依赖管理来管理依赖的jar包的版本。

问题4:项目的模块很多,每次启动项目需要从svn获取全部模块的项目代码编译运行,由于工程大项目启动慢,工作效率低下。
解决方案:maven对每个模块构建成一个一个独立的工程,每个模块构建成功将打成 jar包发布到maven远程仓库,工程师每次运行工程只需要从仓库下载模块jar包即可不用对全部源代码进行编译。

问题5:项目组编写了一个通用的工具类,其它项目组将类拷贝过去使用,工具类发现bug修改后,通过邮件将工具类发送给各各项目组,这不是一个好的分发机制,太多的环节可能导致出现bug。
解决方案:项目组将写的工具类通过maven构建,打成jar,将jar包发布到公司的maven仓库中,公司其它项目通过maven依赖管理从仓库自动下载jar包。

1.2maven的概念模型
Maven是Apache下的一个开源项目,它是一个项目管理工具,它用于对java项目进行项目构建、依赖管理及项目信息管理。当前使用Maven的项目在持续增长。
Maven包含了一个项目对象模型 (Project Object Model),一组标准集合,一个项目生命周期(Project Lifecycle),一个依赖管理系统(Dependency Management System),和用来运行定义在生命周期阶段(phase)中插件(plugin)目标(goal)的逻辑。

项目对象模型 (Project Object Model)
通过pom.xml定义项目的坐标、项目依赖、项目信息、插件目标等。

依赖管理系统(Dependency Management System)
通过定义项目所依赖组件的坐标由maven进行依赖管理。
比如:项目依赖struts2.3.24,通过在pom.xml中定义依赖即可将struts2的jar包自动加入工程:
pom.xml中定义依赖如下:

org.apache.struts
struts2-core
2.3.24

一个项目生命周期(Project Lifecycle)
一个软件开发人员每天都在完成项目的生命周期:清理、编译、测试、部署,有的手工完成,有的通过Ant(也是一个项目构建工具)脚本自动完成,Maven将项目生命周期抽象统一为:清理、初始化、编译、测试、报告 、打包、部署、站点生成等。

maven就是要保证一致的项目构建流程,通过执行一些简单命令即可实现上边生命周期的各各过程。

一组标准集合
maven将整个项目管理过程定义一组标准,比如:通过maven构建工程有标准的目录结构,有标准的生命周期阶段、依赖管理有标准的坐标定义等。

插件(plugin)目标(goal)
maven 管理项目生命周期过程都是基于插件完成的。

1.3maven的仓库
maven工作需要配置仓库,本地的项目A、项目B等通过maven从远程仓库(可以理解为互联网上的仓库)下载jar包并存在本地仓库,本地仓库 就是本地文件夹,当第二次需要此jar包时则不再从远程仓库下载,因为本地仓库已经存在了,可以将本地仓库理解为缓存,有了本地仓库就不用每次从远程仓库下载了。

下图描述了maven中仓库的类型:

本地仓库 :用来存储从远程仓库或中央仓库下载的插件和jar包,项目使用一些插件或jar包,优先从本地仓库查找

远程仓库:如果本地需要插件或者jar包,本地仓库没有,默认去远程仓库下载。

中央仓库 :在maven环境内部内置一个远程仓库地址http://repo1.maven.org/maven2 ,它是中央仓库,服务于整个互联网,它是由Maven自己维护,里面有大量的常用类库,并包含了世界上大部分流行的开源项目构件。
本地仓库没有的jar包Maven默认从中央仓库下载。

2maven安装与配置
2.1下载安装
下载
下载网址: http://maven.apache.org/download.cgi
本教程使用3.1.1 版本

解压不含有中文和空格的目录

bin目录 mvn.bat (以run方式运行项目)、 mvnDebug.bat(以debug方式运行项目 )
boot目录 maven运行需要类加载器 

conf目录 settings.xml 整个maven工具核心配置文件
lib目录 maven运行依赖jar包

2.2环境变量配置

电脑上 安装JDK1.4 + 版本 (将JAVA_HOME/bin 配置环境变量path )

配置 MAVEN_HOME

将 %MAVEN_HOME%/bin 加入环境变量 path

通过 mvn -v命令检查 配置是否成功

2.3本地仓库配置
本地仓库是用来存放联网下载maven的插件和jar包,maven本地仓库有的jar不再从互联网下载,所以本地仓库相当于一个缓存。
默认本地仓库位置在 {user.dir}表示windows用户目录,如下

本教程提供“repository.rar”,将repository.rar解压至,本教程本地仓库位置:
F:\develop\maven\repository

通过 MAVE_HOME/conf/settings.xml配置本地仓库位置:

2.4maven插件安装配置
2.4.1插件安装
本教程 使用STS3.7版本,此版本基于Eclipse mars,此版本自带maven插件不用单独安装。
在新建窗口中可看到maven项目的创建项:

2.4.2指定maven安装目录
一些高版本的eclipse已经内置了maven的安装,下图是Sts3.7版本内置了maven3.3.3版本,通常情况项目为了统一版本不使用内置的maven,本教程使用本机安装的maven3.1.1。

2.4.3User Setting配置
maven仓库地址、私服等配置信息需要在setting.xml文件中配置。在maven安装目录下的有 conf/setting.xml文件,此setting.xml文件用于maven的所有project项目,它作为maven的全局配置。
如果用户需要特殊的maven配置则需要对setting.xml自定义,用户setting.xml的默认的位置在:{user.dir} 指windows 中的用户目录。
本教程统一使用maven安装目录下的全局setting.xml。

注意:如果修改了 setting.xml点击上图片的“update settings”,对本地仓库重建索引,点击“Reindex”。

2.4.4eclipse浏览仓库
打开eclipse仓库视图,对插件和jar包建立索引

3管理项目生命周期
3.1需求
问题1:开发人员将功能开发完成,编译、打包、运行正常,而后提交svn,测试人员从svn获取代码后编译、打包、运行报错。
解决方案:maven对项目生命周期进行定义,规范,开发人员和测试人员使用maven软件完成构建。

3.2创建maven工程(java工程)
3.2.1第一步:新建一个maven工程
新建一个maven工程:maven_first

3.2.2第二步:选择骨架
maven内置了一些maven项目的骨架快速创建项目,使用quickstart 骨架,创建简单java工程。

3.2.3第三步:定义坐标
定义groupid id、artifact id、version:
groupId:定义当前maven项目名称,为了和互联网上其它项目区别需要使用域名倒序
artifactId:定义当前maven项目的模块名称
version:定义当前项目的当前版本

3.2.4第四步:maven工程目录
创建成功目录结构不全需要补充:

完整的目录结构如下:
src/main/java —— 存放项目的.java文件
src/main/resources —— 存放项目资源文件,如spring, hibernate配置文件
src/test/java —— 存放所有测试.java文件,如JUnit测试类
src/test/resources —— 测试资源文件
Maven dependenties —— maven工程依赖的jar
src/main —— web工程存储jsp、js等,相当于WebRoot
target ——编译输出目录
pom.xml ——每个maven工程都有一个pom.xml

以相同的方法创建src/test/java、src/test/resources。

设置src/main/resources和src/test/resources的输出目录:
src/test输出至target/test-classes
src/main输出至target/classes

完整的目录如下:

3.2.5第五步:设置编译版本
本教程 使用jdk1.7,设置maven编译版本为1.7
在pom.xml中加入:




org.apache.maven.plugins
maven-compiler-plugin

1.7
1.7
UTF-8



执行update:

执行update后查看jar版本为1.7:

3.2.6第六步:测试maven命令(eclipse下)

Run as 采用 mvn 命令运行 ,Debug as 采用 mvnDebug 命令调试方式运行(可打断点)
Maven clean 清理target目录
Maven test 执行单元测试
Maven install将工程打包后发布到本地仓库

Maven build 使用之前操作过的命令
Maven build … 手动输入命令内容,如下图:

编译命令 mvn compile
编译后 .class文件在 target/classes 下 (这个命令只会对java源程序编译, 不会编译测试代码 , 编译测试类 mvn test-compile , 编译后.class 文件在 target\test-classes )

测试命令 mvn test
执行所有测试用例方法, 重新编译

清除命令 mvn clean
清除target目录 (清除所有编译结果或者打包结果 ),清理后编译。

打包命名 mvn package
java项目生成 jar包, web项目生成war包
默认生成jar包名称 : artifactId-version.jar

安装命令
安装命令 mvn install 将工程打包后发布到本地仓库
---- 安装到仓库/groupId/artifactId/version 目录
3.2.7第六步:测试maven命令(命令行下)
cmd进入工程目录执行maven命令需要加前缀mvn。
注意:进入工程目录,当前目录下必须的pom.xml方可执行。

3.2.8注意本地仓库的配置
如果setting.xml中本地仓库不配置或配置错误,由于仓库中不包括创建工程所使用的插件包会自动从互联网下载:

配置本教程 提供的本地仓库,由于仓库中有插件包不再从互联网下载:

3.3pom基本配置

pom.xml是Maven项目的核心配置文件,位于每个工程的根目录,基本配置如下:

:文件的根节点 .
: pom.xml使用的对象模型版本 .
:项目名称,一般写项目的域名
:模块名称,子项目名或模块名称
:产品的版本号 .
:打包类型,一般有jar、war、pom 等
:项目的显示名,常用于 Maven 生成的文档。
:项目描述,常用于 Maven 生成的文档
:项目依赖构件配置,配置项目依赖构件的坐标
:项目构建配置,配置编译、运行插件等。

3.4pom详细配置(了解)
POM即项目对象模型 (Project Object Model),在POM中定义项目依赖的坐标、项目信息、项目构建等配置,一个pom.xml文件定义了一个Maven项目。
POM中包含了四类描述和配置,如下图:

第一部分: POM Relationships 关系
Coordinates 坐标: 在仓库中唯一标识项目位置三个参数
项目名称
模块名称
版本号

Aggregation 聚合(多模块) : 将项目分解为多个不同模块 
Inheritance 继承 : 项目之间继承,实现POM复用 
Dependencies 依赖: 项目依赖另一个项目进行编译或者运行 

第二部分: Project Information 项目信息
name :项目名称
desciption: 项目描述

第三部分: Build settings 构建配置
properties : 配置属性
build :构建项目需要插件配置
packaging :打包方式 jar、war、pom (使用继承)
reporting : 报表

第四部分: Build Environment 构建环境 (在依赖、构建、运行 生效配置 )
Distribution Management :版本锁定
Profile : 灵活自定义配置,在特定情况激活

3.5项目生命周期(了解)
Maven有三套相互独立的生命周期,请注意这里说的是“三套”,而且“相互独立”,这三套生命周期分别是:

Clean Lifecycle 在进行真正的构建之前进行一些清理工作。
Default Lifecycle 构建的核心部分,编译,测试,打包,部署等等。
Site Lifecycle 生成项目报告,站点,发布站点。
3.5.1生命周期clean
clean生命周期每套生命周期都由一组阶段(Phase)组成,我们平时在命令行输入的命令总会对应于一个特定的阶段。比如,运行mvn clean ,这个的clean是Clean生命周期的一个阶段。有Clean生命周期,也有clean阶段。Clean生命周期一共包含了三个阶段:
pre-clean 执行一些需要在clean之前完成的工作
clean 移除所有上一次构建生成的文件
post-clean 执行一些需要在clean之后立刻完成的工作
mvn clean 中的clean就是上面的clean,在一个生命周期中,运行某个阶段的时候,它之前的所有阶段都会被运行,也就是说,mvn clean 等同于 mvn pre-clean clean ,如果我们运行 mvn post-clean ,那么 pre-clean,clean 都会被运行。这是Maven很重要的一个规则,可以大大简化命令行的输入。

3.5.2生命周期default
Default生命周期Default生命周期是Maven生命周期中最重要的一个,绝大部分工作都发生在这个生命周期中:

validate
generate-sources
process-sources
generate-resources
process-resources     复制并处理资源文件,至目标目录,准备打包。
compile     编译项目的源代码。
process-classes
generate-test-sources 
process-test-sources
generate-test-resources
process-test-resources     复制并处理资源文件,至目标测试目录。
test-compile     编译测试源代码。
process-test-classes
test     使用合适的单元测试框架运行测试。这些测试代码不会被打包或部署。
prepare-package
package     接受编译好的代码,打包成可发布的格式,如 JAR 。
pre-integration-test
integration-test
post-integration-test
verify
install     将包安装至本地仓库,以让其它项目依赖。
deploy     将最终的包复制到远程的仓库,以让其它开发人员与项目共享。

3.5.3生命周期site
Site生命周期pre-site 执行一些需要在生成站点文档之前完成的工作
site 生成项目的站点文档
post-site 执行一些需要在生成站点文档之后完成的工作,并且为部署做准备
site-deploy 将生成的站点文档部署到特定的服务器上
这里经常用到的是site阶段和site-deploy阶段,用以生成和发布Maven站点,这可是Maven相当强大的功能,Manager比较喜欢,文档及统计数据自动生成,很好看。

4Maven依赖管理
4.1需求
问题2:一个项目工程中时间长了开发人员也搞不清楚项目中的某些jar的作用,用在哪些模块,不得不每过一段时间对每个jar包梳理不遍。
解决方案:maven提供对项目依赖的第三方构件统一管理,通过规范的依赖管理来管理依赖的jar包。

问题3:项目使用的第三方框架要升级,从第三方框架官方网站下载jar包,加入工程,运行后报错,原来是第三方框架依赖的jar版本冲突了。
解决方案:maven提供对项目依赖的第三方构件统一管理,通过规范的依赖管理来管理依赖的jar包的版本。

4.2坐标管理
4.2.1坐标定义
maven通过坐标定义每一个构件,在pom.xml中定义坐标:

groupId:定义当前Maven项目名称
artifactId:定义项目模块
version:定义当前项目的当前版本

4.2.2查找坐标
方法一:使用网站搜索
http://search.maven.org/
http://mvnrepository.com/
网站搜索示例:

方法二:使用maven插件的索引功能

4.3依赖管理
4.3.1添加依赖
4.3.1.1通过坐标导入依赖

在pom.xml中定义dependency标签,导入依赖

通过eclipse导入:

4.3.1.2依赖范围scope
A依赖B,需要在A的pom.xml文件中添加B的坐标,添加坐标时需要指定依赖范围,依赖范围包括:
compile:编译范围,指A在编译时依赖B,此范围为默认依赖范围。编译范围的依赖会用在编译、测试、运行,由于运行时需要所以编译范围的依赖会被打包。

provided:provided依赖只有在当JDK或者一个容器已提供该依赖之后才使用, provided依赖在编译和测试时需要,在运行时不需要,比如:servlet api被tomcat容器提供。

runtime:runtime依赖在运行和测试系统的时候需要,但在编译的时候不需要。比如:jdbc的驱动包。由于运行时需要所以runtime范围的依赖会被打包。

test:test范围依赖 在编译和运行时都不需要,它们只有在测试编译和测试运行阶段可用,比如:junit。由于运行时不需要所以test范围依赖不会被打包。

system:system范围依赖与provided类似,但是你必须显式的提供一个对于本地系统中JAR文件的路径,需要指定systemPath磁盘路径,system依赖不推荐使用。

测试总结:
默认引入 的jar包 ------- compile 【默认范围 可以不写】(编译、测试、运行 都有效 )
servlet-api 、jsp-api ------- provided (编译、测试 有效, 运行时无效 防止和tomcat下jar冲突)
jdbc驱动jar包 ---- runtime (测试、运行 有效 )
junit ----- test (测试有效)

依赖范围由强到弱的顺序是:compile>provided>runtime>test

4.3.2传递依赖
4.3.2.1什么是传递依赖
A 依赖B、B依赖C,将A中导入B后会自动导入C,C是A的传递依赖,如果C依赖D则D也是A的传递依赖。

测试:
加入 struts2-spring-plugin 的依赖,如下:


org.apache.struts
struts2-spring-plugin
2.3.24

struts2-spring-plugin依赖struts和spring,基于传递依赖的原理会工程会自动添加struts和spring的依赖。

测试结果如下:

4.3.2.2传递依赖与范围(了解)
依赖会有依赖范围,依赖范围对传递依赖也有影响,有A、B、C,A依赖B、B依赖C,C可能是A的传递依赖,如下图:

最左边一列为直接依赖,理解为A依赖B的范围,最顶层一行为传递依赖,理解为B依赖C的范围,行与列的交叉即为A传递依赖C的范围。

举例:
比如 A对 B 有 compile 依赖,B 对C有 runtime 依赖,那么根据表格所示A对C 有 runtime 依赖。

总结:
每个单元格都对应行列中最弱的那个,当 p1 依赖 p2,p2 依赖 p3……,最终,p1 传递依赖了pn 的时候,p1 对 pn 的依赖性取决于依赖链中最弱的一环。

测试:
本工程加入struts2-spring-plugin的依赖,如下:


org.apache.struts
struts2-spring-plugin
2.3.24

struts2-spring-plugin所依赖的构件也自动加入本工程中,从仓库查看struts2-spring-plugin的pom文件得知,struts2-spring-plugin依赖spring-test,但是范围为test,根据上边依赖范围表格所示本工程依赖struts2-spring-plugin的范围为compile,struts2-spring-plugin依赖spring-test的范围为test,本工程不传递依赖spring-test,查看下图红色框内所示:

所以spring-test的jar没有加入本工程,如果修改仓库中struts2-spring-plugin的pom文件中spring-test的依赖范围为compile,则发现spring-test的jar包也加入本工程,符合上边表格所示,查看下图红色框内所示:

4.3.3依赖版本冲突解决
4.3.3.1问题
当一个项目依赖的构件比较多时,它们相互之前存在依赖,当你需要对依赖版本统一管理时如果让maven自动来处理可能并不能如你所愿,如下例子:

同时加入以下依赖,观察依赖:


org.apache.struts
struts2-spring-plugin
2.3.24

    <!-- spring-context依赖spring-beans-4.2.4 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.2.4.RELEASE</version>
</dependency>

org.apache.struts依赖spirng-beans-3.0.5,spring-context依赖spring-beans-4.2.4,但是发现spirng-beans-3.0.5加入到工程中,而我们希望spring-beans-4.2.4加入工程。

4.3.3.2依赖调解原则
maven自动按照下边的原则调解:
1、第一声明者优先原则
在pom文件中谁先声明以谁为准。

测试:
如果将上边struts-spring-plugins和spring-context顺序颠倒,系统将导入spring-beans-4.2.4。

2、路径近者优先原则
例如:A-> spirng-beans-4.2.4,A->B-> spirng-beans-3.0.5,则spirng-beans-4.2.4优先
测试:
在本工程中的pom中加入spirng-beans-4.2.4的依赖,根据路径近者优先原则,系统将导入spirng-beans-4.2.4:


org.springframework
spring-beans
4.2.4.RELEASE

4.3.3.3排除依赖
可以通过排除依赖方法辅助依赖调解:

比如struts2-spring-plugin中添加排除spring-beans:

<!-- struts2-spring-plugin依赖spirng-beans-3.0.5 -->
<dependency>
    <groupId>org.apache.struts</groupId>
    <artifactId>struts2-spring-plugin</artifactId>
    <version>2.3.24</version>
    <!-- 排除 spring-beans-->
    <exclusions>
        <exclusion>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
        </exclusion>
    </exclusions>
</dependency>

4.3.3.4锁定版本(推荐使用)
面对众多的依赖,有一种方法不用考虑依赖路径、声明优化等因素可以采用直接锁定版本的方法确定依赖构件的版本,此方法在企业开发中常用:





org.springframework
spring-beans
4.2.4.RELEASE


5maven构建ssh工程
5.1需求
通过maven完成ssh工程构建。
规范依赖管理。

5.2创建maven 工程
根据需求要实现ssh工程构建,将来可以将工程发布成war包,这里需要基于maven的方式创建一个web工程。
5.2.1第一步:创建maven工程

5.2.2第二步:选择骨架
本工程最终要打包war包发布,这里选择骨架webapp

5.2.3第三步:定义坐标

5.2.4第四步:将maven工程目录补充完整
参考创建java工程部分

5.2.5第五步:设置编译版本
参考创建java工程部分

5.2.6第六步:修改web.xml版本
将web.xml修改为:


xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">

5.2.7第七步:加入servlet/jsp依赖

在pom.xml中引入servlet的坐标依赖,注意scop调为provided:



javax.servlet
servlet-api
2.5
provided


javax.servlet
jsp-api
2.0
provided

5.2.8Cannot change version of project facet
查看Problems视图,报错:
Cannot change version of project facet Dynamic Web Module to 2.5
参考:Dynamic web module to 2.5.docx解决

5.3ssh工程构建
5.3.1准备环境
创建数据库:maven
导入sql/cst_customer.sql

5.3.2定义pom.xml
在pom.xml添加工程依赖:
本工程为ssh整合工程,依赖struts2.3.24、 spring4.2.4、hibernate5.0.7等,如下:

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">
4.0.0

<groupId>cn.itcast.maven</groupId>
<artifactId>maven-ssh</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>maven-ssh Maven Webapp</name>
<url>http://maven.apache.org</url>
<!-- 属性 -->
<properties>
    <spring.version>4.2.4.RELEASE</spring.version>
    <hibernate.version>5.0.7.Final</hibernate.version>
    <struts.version>2.3.24</struts.version>
</properties>
<dependencyManagement>
    <dependencies>
        <!-- 锁定版本为 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
			</dependency>
			<dependency>
				<groupId>org.springframework</groupId>
				<artifactId>spring-aspects</artifactId>
				<version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${spring.version}</version>
			</dependency>
			<dependency>
				<groupId>org.springframework</groupId>
				<artifactId>spring-test</artifactId>
				<version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
			</dependency>
			<dependency>
				<groupId>org.hibernate</groupId>
				<artifactId>hibernate-core</artifactId>
				<version>${hibernate.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.struts</groupId>
            <artifactId>struts2-core</artifactId>
            <version>${struts.version}</version>
			</dependency>
			<dependency>
				<groupId>org.apache.struts</groupId>
				<artifactId>struts2-spring-plugin</artifactId>
				<version>${struts.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.struts</groupId>
            <artifactId>struts2-json-plugin</artifactId>
            <version>${struts.version}</version>
        </dependency>
    </dependencies>
</dependencyManagement>
<dependencies>
    <!-- spring -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-orm</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
    </dependency>
    <!-- hibernate -->
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
    </dependency>

    <!-- 数据库驱动 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.6</version>
        <scope>runtime</scope>
    </dependency>
    <!-- c3p0 -->

    <dependency>
        <groupId>c3p0</groupId>
        <artifactId>c3p0</artifactId>
        <version>0.9.1.2</version>
    </dependency>
    <!-- 导入 struts2 -->
    <dependency>
        <groupId>org.apache.struts</groupId>
        <artifactId>struts2-core</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.struts</groupId>
        <artifactId>struts2-spring-plugin</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.struts</groupId>
        <artifactId>struts2-json-plugin</artifactId>
    </dependency>

    <!-- servlet jsp -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.0</version>
        <scope>provided</scope>
    </dependency>
    <!-- 日志 -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.7.2</version>
    </dependency>
    <!-- junit -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.9</version>
        <scope>test</scope>
    </dependency>
    <!-- jstl -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>
</dependencies>
<build>
    <finalName>maven-ssh</finalName>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.7</source>
                <target>1.7</target>
                <encoding>UTF-8</encoding>
            </configuration>
        </plugin>
    </plugins>
</build>

5.3.3src/main/java
在src/main/java中创建dao、domian、pojo、service、action等,注意此目录只包括java文件不包括配置文件:

5.3.3.1dao

@Repository("customerDao")
public class CustomerDaoImpl extends HibernateDaoSupport implements CustomerDao {

@Override
public DetachedCriteria createDetachedCriteria() {
    return DetachedCriteria.forClass(CstCustomer.class);
}

@Autowired
public void setHT(HibernateTemplate hibernateTemplate){
    this.setHibernateTemplate(hibernateTemplate);
}
@Override
public CstCustomer findCustomerById(Long custId) {
    return this.getHibernateTemplate().get(CstCustomer.class, custId);
}

}

5.3.3.2service

@Service("customerService")
public class CustomerServiceImpl implements CustomerService {

// 定义dao属性
@Autowired
private CustomerDao customerDao;

@Override
public CstCustomer findCustomerById(Long custId) {
    return customerDao.findCustomerById(custId);
}

}

5.3.3.1action

@Controller
@Scope("prototype")
public class CustomerAction extends ActionSupport {

//依赖注入
@Autowired
private CustomerService customerService;

//客户id
private Long custId;

//客户信息
private CstCustomer customer;

//根据主键获取客户信息
public String getCustomerById(){

    customer = customerService.findCustomerById(custId);
    return SUCCESS;
}

public Long getCustId() {
    return custId;
}

public void setCustId(Long custId) {
    this.custId = custId;
}

public CstCustomer getCustomer() {
    return customer;
}

public void setCustomer(CstCustomer customer) {
    this.customer = customer;
}

}

5.3.4src/main/resources
创建配置文件:

5.3.4.1db.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/maven
jdbc.username=root
jdbc.password=root

5.3.4.1log4j.properties

direct log messages to stdout

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

direct messages to file mylog.log

log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=d:/mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

log JDBC bind parameters

log4j.logger.org.hibernate.type=TRACE

set log levels - for more verbose logging change 'info' to 'debug'

log4j.rootLogger=debug, stdout

5.3.4.1CstCustomer.xml


"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">


catalog="crm" optimistic-lock="version">



    <property name="custName" type="string">
        <column name="cust_name" length="32" not-null="true"></column>
    </property>
    <property name="custLinkman" type="string">
        <column name="cust_linkman" length="64"></column>
    </property>
    <property name="custPhone" type="string">
        <column name="cust_phone" length="64"></column>
    </property>
    <property name="custMobile" type="string">
        <column name="cust_mobile" length="16"></column>
    </property>
    <property name="custCreatetime" type="timestamp">
        <column name="cust_createtime" length="19"></column>
    </property>

</class>

5.3.4.2hibernate.cfg.xml


"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">



    <!-- 数据库方言,根据数据库选择 -->
    <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>


    <!--为了方便调试是否在运行hibernate时在日志中输出sql语句 -->
    <property name="hibernate.show_sql">true</property>
    <!-- 是否对日志中输出的sql语句进行格式化 -->
    <property name="hibernate.format_sql">true</property>

    <property name="hibernate.hbm2ddl.auto">none</property>

    <!-- 事务管理 -->
    <!-- 事务隔离级别 -->
    <property name="hibernate.connection.isolation">4</property>
    <!-- 配置session绑定本地线程 -->
    <!-- <property name="hibernate.current_session_context_class">thread</property> -->
    <!-- 使用spring与hibernate整合类SpringSessionContext  -->
    <property name="hibernate.current_session_context_class">org.springframework.orm.hibernate5.SpringSessionContext</property> 
    <!-- 加载映射文件 -->
    <mapping resource="cn/itcast/crm/domain/CstCustomer.hbm.xml"/>
</session-factory>

5.3.4.3applicationContext.xml

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">

<!-- 将db.properties文件属性值(key/value)加载到容器中 -->
<context:property-placeholder location="classpath:db.properties" />

<!-- 组件扫描 -->
<context:component-scan base-package="cn.itcast.crm"/>

<!-- c3p0从属性中获取连接参数 ${jdbc.driver}表示从属性中取值,jdbc.driver就是属性中的key -->
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="${jdbc.driver}" />
    <property name="jdbcUrl" value="${jdbc.url}" />
		<property name="user" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />
</bean>

<!-- sesionFactory 注入数据源 -->
<bean id="sessionFactory"
    class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
    <!-- 数据源 -->
    <property name="dataSource" ref="dataSource" />
    <!-- 加载hibernate的全局配置文件 -->
    <property name="configLocations" value="classpath:hibernate/hibernate.cfg.xml" />
</bean>
<!-- HibernateTemplate -->
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate">
    <!-- 如果设置为不检查事务可写性则可以在没有事务时自动提交数据 -->
    <property name="checkWriteOperations" value="false"/>
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>

5.3.4.4applicationContext-transaction.xml

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
















proxy-target-class="true"表示 使用cglib代理,为false使用jdk -->

<aop:config>
    <aop:advisor advice-ref="txAdvice" pointcut="execution(* cn.itcast.crm.service.impl.*.*(..))"/>
</aop:config>

5.3.4.5struts.xml


"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
 <include file="struts/struts-common.xml"></include>
 <include file="struts/struts-customer.xml"></include>
</struts>

5.3.4.1struts-common.xml


"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>

    <!-- 配置常量  -->
    <!-- 字符集 -->
    <constant name="struts.i18n.encoding" value="UTF-8"></constant>
    <!-- 开发模式 -->
    <constant name="struts.devMode" value="true"></constant>
    <!-- 主题 -->
    <constant name="struts.ui.theme" value="simple"></constant>
    <!-- 扩展名 -->
    <constant name="struts.action.extension" value="action"></constant>
    <!-- 动态方法访问 -->
    <constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>

    <!-- 上传文件大小最大为4M -->
    <constant name="struts.multipart.maxSize" value="4194304"></constant>

    <!-- 通用package -->
    <package name="common" extends="struts-default">



    </package>

</struts>

5.3.4.2struts-customer.xml


"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>

    <package name="customer" extends="common" namespace="/customer" >
        <action name="getcustomer" class="customerAction" method="getCustomerById">
            <result>/views/getcustomer.jsp</result>
        </action>

    </package>

</struts>

5.3.5src/test/java
创建dao和service单元测试类:

@ContextConfiguration(locations = { "classpath:spring/applicationContext.xml",
"classpath:spring/applicationContext-*.xml" })
@RunWith(SpringJUnit4ClassRunner.class)
public class CustomerDaoImplTest {

@Autowired
private CustomerDao customerDao;

@Before
public void setUp() throws Exception {
}

@Test
public void testFindCustomerById() {
    CstCustomer customer = customerDao.findCustomerById(1l);
    System.out.println(customer);
}

}

5.3.6Jsp

getcustomer.jsp如下:

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




测试



${customer.custName}

5.3.7web.xml


xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">

<!-- 配置加载spring容器 -->
<listener>
    <!-- 默认从/WEB-INF/applicationContext.xml加载配置文件 -->
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
    <param-name>contextConfigLocation</param-name>
    <!-- spring配置文件 可以采用加载多个文件,中间以半角逗号分隔,也可以使用通配符号 -->
    <param-value>classpath:spring/applicationContext.xml,classpath:spring/applicationContext-*.xml</param-value>
</context-param>
<!-- OpenSessionInView -->
<filter>
    <filter-name>OpenSessionInView</filter-name>
    <filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>OpenSessionInView</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<!-- 配置struts2的 前端控制器 作用:加载struts.xml中action,处理action的请求 -->
<filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

5.3.8运行
使用maven的tomcat插件运行项目:

5.3.8.1端口占用
重新执行tomcat:run命令重启工程,重启之前需手动停止 tomcat,否则报下边的错误:
Caused by: java.net.BindException: Address already in use: JVM_Bind

5.3.9断点调试
maven工程断点调试必须采用“Debug As”方式启动,并且需要引入源码才可源码跟踪:

引入源码:

添加,选择本工程:

以debug方式运行:

6分模块构建工程
6.1需求
6.1.1需求描述
将ssh工程拆分为多个模块开发:
dao
service
web

6.1.2理解继承和聚合
通常继承和聚合同时使用。

何为聚合?
项目开发通常是分组分模块开发,每个模块开发完成需要将模块聚合在一起运行

何为继承?
继承为了消除重复,我们把很多相同的配置提取出来,子模块继承父模块。

6.2案例实现
6.2.1maven-parent父模块

6.2.1.1创建父工程

这里选择“跳过骨架选择”

定义坐标:

6.2.1.2定义pom.xml
在pom.xml中统一依赖构件的版本、规范编译版本、子模块聚合。

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">
4.0.0
cn.itcast.maven
maven-parent
0.0.1-SNAPSHOT
pom
父工程



4.2.4.RELEASE
5.0.7.Final
2.3.24





org.springframework
spring-context
{spring.version}


org.springframework
spring-orm
{spring.version}


org.springframework
spring-web
{hibernate.version}


org.apache.struts
struts2-core
{struts.version}


org.apache.struts
struts2-json-plugin
${struts.version}


<build>
    <finalName>maven-ssh</finalName>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.7</source>
                <target>1.7</target>
                <encoding>UTF-8</encoding>
            </configuration>
        </plugin>
    </plugins>
</build>

6.2.1.3将父工程发布至仓库
执行maven-install将父工程发布到仓库:

6.2.2maven -dao子模块
6.2.2.1创建dao子模块
选择maven模块:

这里指定模块名称,选择“跳过骨架选择”:

6.2.2.2定义pom.xml
dao模块的pom.xml文件中需要继承父模块,添加持久层需要的依赖坐标:

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">
4.0.0

cn.itcast.maven
maven-parent
0.0.1-SNAPSHOT

maven-dao
jar


org.hibernate
hibernate-core


org.springframework
spring-context


org.springframework
spring-aspects


org.springframework
spring-orm


org.springframework
spring-test


org.springframework
spring-web

    <!-- 数据库驱动 -->

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.6</version>
        <scope>runtime</scope>
    </dependency>
    <!-- c3p0 -->

    <dependency>
        <groupId>c3p0</groupId>
        <artifactId>c3p0</artifactId>
        <version>0.9.1.2</version>
    </dependency>
    <!-- 日志 -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.7.2</version>
    </dependency>
    <!-- junit -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.9</version>
        <scope>test</scope>
    </dependency>
</dependencies>

6.2.2.3dao接口

将maven-ssh工程中的dao接口及domain类拷贝到src/main/java中:

6.2.2.4配置文件
拷贝maven-ssh工程中如下配置文件:

6.2.2.5单元测试

@ContextConfiguration(locations = { "classpath:spring/applicationContext.xml",
"classpath:spring/applicationContext-*.xml" })
@RunWith(SpringJUnit4ClassRunner.class)
public class CustomerDaoImplTest {

@Autowired
private CustomerDao customerDao;

@Before
public void setUp() throws Exception {
}

@Test
public void testFindCustomerById() {
    CstCustomer customer = customerDao.findCustomerById(1l);
    System.out.println(customer);
}

}

6.2.3maven -service子模块

6.2.3.1创建service子模块
方法同maven-dao模块创建方法,模块名称为maven-service。

6.2.3.2定义pom.xml
service模块的pom.xml文件中需要继承父模块,service依赖dao模块:

http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0

cn.itcast.maven
maven-parent
0.0.1-SNAPSHOT

maven-service
jar




junit
junit
4.9
test



cn.itcast.maven
maven-dao
0.0.1-SNAPSHOT

6.2.3.3service接口
将maven-ssh工程中的service接口拷贝到src/main/java中:

6.2.3.1配置文件
拷贝maven-ssh工程中如下配置文件:

6.2.3.1单元测试

@ContextConfiguration(locations = { "classpath:spring/applicationContext.xml",
"classpath:spring/applicationContext-*.xml" })
@RunWith(SpringJUnit4ClassRunner.class)
public class CustomerServiceImplTest {

@Autowired
private CustomerService customerService;

@Before
public void setUp() throws Exception {
}

@Test
public void testFindCustomerById() {
    CstCustomer customer = customerService.findCustomerById(1l);
    System.out.println(customer);
}

}

6.2.4ssh-web子模块

6.2.4.1创建web子模块
方法同maven-dao模块创建方法,模块名称为maven-web。

6.2.4.1定义pom.xml
web模块的pom.xml文件中需要继承父模块,web依赖service模块:

http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0

cn.itcast.maven
maven-parent
0.0.1-SNAPSHOT

maven-web
war
web工程




junit
junit
4.9
test

    <!-- 依赖service -->
    <dependency>
        <groupId>cn.itcast.maven</groupId>
        <artifactId>maven-service</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>


    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
    </dependency>
    <!-- 导入 struts2 -->
    <dependency>
        <groupId>org.apache.struts</groupId>
        <artifactId>struts2-core</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.struts</groupId>
        <artifactId>struts2-spring-plugin</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.struts</groupId>
        <artifactId>struts2-json-plugin</artifactId>
    </dependency>

            <!-- servlet jsp -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.0</version>
        <scope>provided</scope>
    </dependency>
            <!-- jstl -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>
</dependencies>

6.2.4.2action
将maven-ssh工程中的action拷贝到src/main/java中:

6.2.4.1配置文件
拷贝maven-ssh工程中如下配置文件:

6.2.5模块聚合

修改父工程的pom.xml,添加:



maven-dao
maven-service
maven-web

父工程执行package命令,在maven-web工程生成一个war包。

6.2.6编译运行
方法1:运行maven-web工程,执行tomcat:run
方法2:在父工程执行package,生成war包,将war包拷贝到tomcat运行

6.2.6.1配置tomcat6插件

在pom.xml中通过配置tomcat6插件,可以灵活设置服务端口及访问路径:





org.codehaus.mojo
tomcat-maven-plugin


8088
如果不指定则Context Path为build标签中finalName指定的名称,若没指定,则为artifactId的值
-->
/ssh

UTF-8

    </plugins>

</build>

执行如下命令:
mvn tomcat:run

访问:http://localhost:8088/ssh

6.2.6.2配置tomcat7插件
通过配置tomcat插件灵活设置服务端口及访问路径:



org.apache.tomcat.maven
tomcat7-maven-plugin


8081

/

执行命令:
mvn tomcat7:run

访问:http://localhost:8081/

7maven私服
7.1需求
问题5:项目组编写了一个通用的工具类,其它项目组将类拷贝过去使用,当工具类修改bug后通过邮件发送给各各项目组,这种分发机制不规范可能导致工具类版本不统一。
解决方案:项目组将写的工具类通过maven构建,打成jar,将jar包发布到公司的maven仓库中,公司其它项目通过maven依赖管理从仓库自动下载jar包。

7.2分析
公司在自己的局域网内搭建自己的远程仓库服务器,称为私服,私服服务器即是公司内部的maven远程仓库,每个员工的电脑上安装maven软件并且连接私服服务器,员工将自己开发的项目打成jar并发布到私服服务器,其它项目组从私服服务器下载所依赖的构件(jar)。
私服还充当一个代理服务器,当私服上没有jar包会从互联网中央仓库自动下载,如下图:

7.3搭建私服环境
7.3.1下载nexus

Nexus 是Maven仓库管理器,通过nexus可以搭建maven仓库,同时nexus还提供强大的仓库管理功能,构件搜索功能等。
下载Nexus, 下载地址:http://www.sonatype.org/nexus/archived/

下载:nexus-2.12.0-01-bundle.zip

7.3.2安装nexus
解压nexus-2.12.0-01-bundle.zip,本教程将它解压在F盘,进入bin目录:

cmd进入bin目录,执行nexus.bat install

安装成功在服务中查看有nexus服务:

7.3.3卸载nexus
cmd进入nexus的bin目录,执行:nexus.bat uninstall

查看window服务列表nexus已被删除。

7.3.4启动nexus
方法1:
cmd进入bin目录,执行nexus.bat start
方法2:
直接启动nexus服务

查看nexus的配置文件conf/nexus.properties

Jetty section

application-port=8081 # nexus的访问端口配置
application-host=0.0.0.0 # nexus主机监听配置(不用修改)
nexus-webapp=${bundleBasedir}/nexus # nexus工程目录
nexus-webapp-context-path=/nexus # nexus的web访问路径

Nexus section

nexus-work={bundleBasedir}/../sonatype-work/nexus   # nexus仓库目录
runtime=
{bundleBasedir}/nexus/WEB-INF # nexus运行程序目录

访问:
http://localhost:8081/nexus/

使用Nexus 内置账户admin/admin123登陆:
点击右上角的Log in,输入账号和密码 登陆

登陆成功:

7.3.5仓库类型
nexus
查看nexus的仓库:

nexus的仓库有4种类型:

1.hosted,本地仓库,部署自己的jar到这个类型的仓库,包括releases和snapshot两部分,Releases公司内部发布版本仓库、 Snapshots 公司内部测试版本仓库

2.proxy,代理仓库,用于代理远程的公共仓库,如maven中央仓库,用户连接私服,私服自动去中央仓库下载jar包或者插件。

3.group,仓库组,用来合并多个hosted/proxy仓库,通常我们配置自己的maven连接仓库组。
4.virtual(虚拟):兼容Maven1 版本的jar或者插件

nexus仓库默认在sonatype-work目录中:

central:代理仓库,代理中央仓库

apache-snapshots:代理仓库
存储snapshots构件,代理地址https://repository.apache.org/snapshots/
central-m1:virtual类型仓库,兼容Maven1 版本的jar或者插件
releases:本地仓库,存储releases构件。
snapshots:本地仓库,存储snapshots构件。
thirdparty:第三方仓库
public:仓库组

7.4使用私服
7.4.1搜索构件
私服可以作为代理仓库,比如代理中央仓库,通过私服可以搜索中央仓库中的构件, nexus提供搜索中央仓库构件的功能,比如:输入junit可以搜索出所有junit的版本。
7.4.1.1创建索引
nexus是基于全文检索技术搜索构件,全文检索需要索引文件才可搜索,首先需要创建索引,创建索引方法如下:
1、自动下载
将central 中央仓库自动创建索引开关打开,这样nexus自动可以从中央仓库下载索引文件。

执行:
update index

2、手动下载
从中央仓库下载索引,手动拷贝到nexus工作目录。
下载地址:http://repo.maven.apache.org/maven2/.index/
下载如下文件:

从网上下载:indexer-cli-5.1.0.jar

将这三者放在一个文件夹,cmd执行:
java -jar indexer-cli-5.1.0.jar -u nexus-maven-repository-index.gz -d indexer
会自动在本目录生成索引文件目录,如下图:

将上图的索引文件目录拷贝至:sonatype-work\nexus\indexer\central-ctx

重启nexus:

7.4.1.1搜索构件
索引创建完毕,进入nexus界面搜索构件:

查看构件的坐标:

7.4.2将项目发布到私服
企业中多个团队协作开发通常会将一些公用的组件、开发模块等发布到私服供其它团队或模块开发人员使用。

第一步: 需要在客户端 maven环境 settings.xml 配置连接私服的用户和密码

<server>
  <id>releases</id>
  <username>admin</username>
  <password>admin123</password>
</server>
<server>
  <id>snapshots</id>
  <username>admin</username>
  <password>admin123</password>
</server>

releases 连接发布版本项目仓库
snapshots 连接测试版本项目仓库

第二步: 配置项目pom.xml



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


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

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

第三步: 将项目发布到私服 mvn deploy 命令
1、首先启动nexus
2、将项目发布到nexus,执行deploy

根据本项目pom.xml中version定义决定发布到哪个仓库,如果version定义为snapshot,执行deploy后查看nexus的snapshot仓库,如果version定义为release则项目将发布到nexus的release仓库,本项目将发布到snapshot仓库:

也可以通过http方式查看:

7.4.3从私服下载jar包
没有配置nexus之前,如果本地仓库没有,去中央仓库下载,通常在企业中会在局域网内部署一台私服服务器,程序员连接私服从私服下载jar包,这样做的好处是一方面由私服对公司项目的依赖统一管理,一方面提高下载速度,毕竟局域网速度比公网快。
7.4.3.1管理仓库组
nexus中包括很多仓库,hosted中存放的是企业自己发布的或第三方的jar,proxy中存放的是中央仓库的jar,为了方便从私服下载jar包可以将多个仓库组成一个仓库组,项目通过连接nexus的仓库组下载jar包。
打开nexus配置仓库组:

上图中仓库组包括了本地仓库、代理仓库等。

7.4.3.2配置镜像
在maven的setting.xml文件中配置mirror镜像,镜像地址为nexus仓库组的地址,本地项目当需要下载依赖时,先查看本地仓库如果没有则从镜像下载,镜像没有从中央仓库下载,镜像相当于一个代理。

在setting.xml文件中配置 镜像:

镜像地址为nexus仓库组的地址:
http://localhost:8081/nexus/content/groups/public/

配置如下:

 <mirror>
  <!--镜像id,mirrors中可以配置多个镜像,保证id不重复-->
  <id>nexus</id>
  <!--mirrorOf指定仓库id,仓库组包括了id为 releases、snapshots、thirdparty 、central 的仓库,可以配置具体的id,如果镜像所有的仓库则设置为*-->
  <mirrorOf>*</mirrorOf>
  <!--镜像地址-->
  <url>http://localhost:8081/nexus/content/groups/public/</url>
</mirror>

测试:
项目pom.xml添加依赖一个本地仓库和私服都没有jar包,maven先从本地仓库找,本地仓库没有再从私服找,私服没有再去中央仓库下载,下载成功jar在私服、本地仓库分别存储一份。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注