在乐字节学习的第13天,学习了挺多知识,下面就是我今天在乐字节学习的知识。
修改 JDK 的版本
<!-- JDN的版本修改为1.8 -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
设置单元测试的版本
<!-- junit的版本修改为4.12 -->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
删除pluginManagement标签
<!-- 将这个标签及标签中的内容全部删除 -->
<pluginManagement>
...
</pluginManagement>
添加web部署的插件
在 build 标签中添加 plugins 标签
Jetty插件
<!-- 设置在plugins标签中 -->
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.25</version>
<configuration>
<!-- 热部署,每10秒扫描一次 -->
<scanIntervalSeconds>10</scanIntervalSeconds>
<!-- 可指定当前项目的站点名 -->
<contextPath>/test</contextPath>
<connectors>
<connectorimplementation="org.mortbay.jetty.nio.SelectChannelConnector">
<port>9090</port><!-- 设置启动的端口号 -->
</connector>
</connectors>
</configuration>
</plugin>
Tomcat插件
<!-- 设置在plugins标签中 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>8081</port><!-- 启动端口 默认:8080 -->
<path>/test</path><!-- 项目的站点名,即对外访问路径 -->
<uriEncoding>UTF-8</uriEncoding><!-- 字符集编码 默认:ISO-8859-1 -->
<server>tomcat7</server><!-- 服务器名称 -->
</configuration>
</plugin>
启动项目
点击右上角的 "Add Configurations ",打开 "Run/Debug Configurations" 窗口
点击左上角的 "+" 号,选择 "Maven"
Jetty插件配置
也可以输入命令指定端口启动
jetty:run-Djetty.port=9090# 需要将插件配置中的port标签去掉
点击启动图标,启动服务
启动成功
浏览器访问效果
Tomcat插件配置
启动方式如上,启动成功
浏览器访问 http://localhost:8080/test
Maven依赖仓库:
Tomcat7插件的命令:
https://tomcat.apache.org/maven-plugin-trunk/tomcat7-maven-plugin/plugin-info.html
Maven仓库的基本概念
当第一次运行Maven命令的时候, 你需要Internet链接, 因为它需要从网上下载一些文件。 那么它从哪里下载呢? 它是从Maven默认的远程库下载的。 这个远程仓库有Maven的核心插件和可供下载的jar文件。
对于Maven来说, 仓库只分为两类: 本地仓库和远程仓库。
当Maven根据坐标寻找构件的时候,它首先会查看本地仓库,如果本地仓库存在,则直接使用; 如果本地没有,Maven就会去远程仓库查找,发现需要的构件之后,下载到本地仓库再使用。 如果本地仓库和远程仓库都没有,Maven就会报错。
远程仓库分为三种: 中央仓库,私服, 其他公共库。
中央仓库是默认配置下,Maven下载jar包的地方。
私服是另一种特殊的远程仓库,为了节省带宽和时间,应该在局域网内架设一个私有的仓库服务器,用其代理所有外部的远程仓库。 内部的项目还能部署到私服上供其他项目使用。
一般来说,在Maven项目目录下,没有诸如lib/这样用来存放依赖文件的目录。 当Maven在执行编译或测试时,如果需要使用依赖文件,它总是基于坐标使用本地仓库的依赖文件。
默认情况下, 每个用户在自己的用户目录下都有一个路径名为.m2/repository/的仓库目录。 有时候,因为某些原因(比如c盘空间不足),需要修改本地仓库目录地址。
对于仓库路径的修改,可以通过maven 配置文件conf 目录下settings.xml来指定仓库路径
<!-- 设置到指定目录中,路径的斜杆不要写反 -->
<settings>
<localRepository>D:/m2/repository</localRepository>
</settings>
中央仓库
由于原始的本地仓库是空的,maven必须知道至少一个可用的远程仓库,才能执行maven命令的时候下载到需要的构件。中央仓库就是这样一个默认的远程仓库。
maven-model-builder-3.3.9.jar maven自动的 jar 中包含了一个 超级POM。定义了默认中央仓库的位置。
中央仓库包含了2000多个开源项目,接收每天1亿次以上的访问。
私服
私服是一种特殊的远程仓库,它是架设在局域网内的仓库服务, 私服代理广域网上的远程仓库,供局域网内的maven用户使用。 当maven需要下载构件时, 它去私服当中找,如果私服没有, 则从外部远程仓库下载,并缓存在私服上, 再为maven提供。
此外,一些无法从外部仓库下载的构件也能从本地上传到私服提供局域网中其他人使用
配置方式项目pom.xml 配置
<repositories>
<repository>
<snapshots>
<enabled>true</enabled>
</snapshots>
<id>public</id>
<name>Public Repositories</name>
<url>http://192.168.0.96:8081/content/groups/public/</url>
</repository>
<repository>
<id>getui-nexus</id> <url>http://mvn.gt.igexin.com/nexus/content/repositories/releases/</url>
</repository>
</repositories>
公司内部应该建立私服:
节省自己的外网带宽
加速maven构建
部署第三方控件
提高稳定性
降低中央仓库的负荷
其他公共库
常用的阿里云仓库配置
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>central</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
Maven环境下构建多模块项目
使用maven 提供的多模块构建的特性完成maven 环境下多个模块的项目的管理与构建。
这里以四个模块为例来搭建项目,以达到通俗易懂的初衷
模块 maven_parent —– 基模块,就是常说的parent (pom)
模块 maven_dao —– 数据库的访问层,例如jdbc操作(jar)
模块 maven_service —– 项目的业务逻辑层 (jar)
模块 maven_controller —– 用来接收请求,响应数据 (war)
创建 maven_parent 项目
选择 File —> Settings —> Project
设置 GroupId 和 ArtifactId
设置项目名称及工作空间
创建 maven_dao 模块
选择项目maven_parent,右键选择 New ,选择Module
选择Maven项目的模板(普通 Java 项目)
设置子模块的的 ArtifactId
设置Maven的配置
设置子模块的名称及存放位置
创建 maven_service 模块
创建 maven_service 模块的步骤与 maven_dao模块一致。
建 maven_controller 模块
创建 maven_service 模块的步骤与 maven_dao模块基本一致,只需要将第一步选择Maven模板设置为web项目即可。(模板类型:maven-archetype-webapp)
模块全部创建完毕后,效果如下:
修改模块的配置
设置 JDK 版本
单元测试 JUnit版本
删除多余的配置
设置模块之间的依赖
maven_dao
新建包
在包中创建 UserDao类
在类中添加方法
packagecom.xxxx.dao;
publicclassUserDao{
publicstaticvoidtestDao() {
System.out.println("UserDao Test...");
}
}
maven_service
添加maven_dao的依赖
<!-- 加入maven_dao模块的依赖 -->
<dependency>
<groupId>com.xxxx</groupId>
<artifactId>maven_dao</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
在项目中添加UserService类,并添加方法
packagecom.xxxx.service;
importcom.xxxx.dao.UserDao;
publicclassUserService{
publicstaticvoidtestService() {
System.out.println("UserService Test...");
// 调用UserDao的方法
UserDao.testDao();
}
}
maven_controller
添加 maven_service 模块的依赖
<!-- 加入maven_service模块的依赖 -->
<dependency>
<groupId>com.xxxx</groupId>
<artifactId>maven_service</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
添加Servlet的依赖
<!-- Servlet的依赖 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
新建 Java 类,继承 HttpServlet 类,并重写 service方法
packagecom.xxxx.controller;
importcom.xxxx.service.UserService;
importjavax.servlet.ServletException;
importjavax.servlet.annotation.WebServlet;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
importjava.io.IOException;
@WebServlet("/user")
publicclassUserServletextendsHttpServlet{
@Override
protectedvoidservice(HttpServletRequestreq,HttpServletResponseresp)throwsServletException,IOException{
System.out.println("UserServlet Test...");
// 调用UserService层的方法
UserService.testService();
}
}
添加Tomcat插件
<!-- 添加插件 -->
<plugins>
<!-- tomcat7插件 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<!-- <port>8080</port> -->
<path>/web</path>
<uriEncoding>UTF-8</uriEncoding>
<server>tomcat7</server>
</configuration>
</plugin>
</plugins>
启动项目
访问项目
访问地址:http://localhost:8080/web/user
访问结果:
如果启动失败,请先将父项目 install
注:如果父项目 install 失败,则先将所有子模块 install 成功后,再 install 父项目。
Maven的打包操作
对于企业级项目,无论是进行本地测试,还是测试环境测试以及最终的项目上线,都会涉及项目的打包操作。对于每个环境下的项目打包,对应的项目所需要的配置资源都会有所区别,实现打包的方式有很多种,可以通过ant,或者通过idea 自带的打包功能实现项目打包,但当项目很大并且需要的外界配置很多时,此时打包的配置就会异常复杂,对于maven 项目,我们可以用过 pom.xml 配置的方式来实现打包时的环境选择,相比较其他形式打包工具,通过maven 只需要通过简单的配置,就可以轻松完成不同环境下项目的整体打包。
比如下面这样一个项目,项目中配置了不同环境下项目所需要的配置文件,这时候需要完成不同环境下的打包操作,此时通过修改pom.xml 如下:
建立对应的目录结构
使用idea创建项目,目录结构可能会缺失,需要通过手动添加对应的目录。
添加 Java 源文件夹
选择项目的 main 文件夹,右键选择New,选择Directory
输入文件夹名 "Java",如图:
选择 java 目录,右键选择 Mark Directory as,选择 Sources Root。将文件夹标记为源文件夹。
添加资源文件夹
步骤如上,创建文件夹,命名为 resources,并标记为 Resources Root
添加对应的文件夹目录,及添加不同环境下对应的配置文件。(本地环境、测试环境、正式环境)
添加Profile配置
<!-- 打包环境配置 开发环境 测试环境 正式环境 -->
<profiles>
<profile>
<id>dev</id>
<properties>
<env>dev</env>
</properties>
<!-- 未指定环境时,默认打包dev环境 -->
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>test</id>
<properties>
<env>test</env>
</properties>
</profile>
<profile>
<id>product</id>
<properties>
<env>product</env>
</properties>
</profile>
</profiles>
设置资源文件配置
<!-- 对于项目资源文件的配置放在build中 -->
<resources>
<resource>
<directory>src/main/resources/${env}</directory>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
<include>**/*.tld</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
执行打包操作
打开Run/Debug Configuarations窗口,输入对应的打包命令
此时对应打包命令
clean compile package -Dmaven.test.skip=true
打包默认环境(开发环境)并且跳过maven 测试操作
clean compile package -Ptest -Dmaven.test.skip=true
打包测试环境并且跳过maven 测试操作
clean compile package -Pproduct -Dmaven.test.skip=true
打包生产环境并且跳过maven 测试操作
打包成功
不同的项目打包的文件不一样,一般来说,普通java项目打成jar包,web项目打成war包
Maven依赖的基本概念
依赖的基本配置
根元素project下的dependencies可以包含多个 dependence元素,以声明多个依赖。每个依赖都应该包含以下元素:
groupId, artifactId, version : 依赖的基本坐标, 对于任何一个依赖来说,基本坐标是最重要的, Maven根据坐标才能找到需要的依赖。
Type: 依赖的类型,大部分情况下不需要声明。 默认值为jar
Scope: 依赖范围(compile,test,provided,runtime,system)
compile: 编译依赖范围。
如果没有指定,就会默认使用该依赖范围。使用此依赖范围的Maven依赖,对于编译、测试、运行三种classpath都有效。
test: 测试依赖范围。
使用此依赖范围的Maven依赖,只对于测试classpath有效,在编译主代码或者运行项目的使用时将无法使用此类依赖。典型的例子就是JUnit,它只有在编译测试代码及运行测试的时候才需要。
provided: 已提供依赖范围。
使用此依赖范围的Maven依赖,对于编译和测试classpath有效,但在运行时无效。典型的例子是servlet-api,编译和测试项目的时候需要该依赖,但在运行项目的时候,由于容器已经提供,就不需要Maven重复地引入一遍(如:servlet-api)。
runtime: 运行时依赖范围。
使用此依赖范围的Maven依赖,对于测试和运行classpath有效,但在编译主代码时无效。典型的例子是JDBC驱动实现,项目主代码的编译只需要JDK提供的JDBC接口,只有在执行测试或者运行项目的时候才需要实现上述接口的具体JDBC驱动。
system: 系统依赖范围。
该依赖与三种classpath的关系,和provided依赖范围完全一致。但是,使用system范围依赖时必须通过systemPath元素显式地指定依赖文件的路径。由于此类依赖不是通过Maven仓库解析的,而且往往与本机系统绑定,可能造成构建的不可移植,因此应该谨慎使用。
Optional:标记依赖是否可选
Exclusions: 用来排除传递性依赖。
依赖范围
首先需要知道,Maven在编译项目主代码的时候需要使用一套classpath。 比如:编译项目代码的时候需要用到spring-core, 该文件以依赖的方式被引入到classpath中。 其次, Maven在执行测试的时候会使用另外一套classpath。 如:junit。
最后在实际运行项目时,又会使用一套classpath, spring-core需要在该classpath中,而junit不需要。
那么依赖范围就是用来控制依赖与这三种classpath(编译classpath,测试classpath,运行时classpath)的关系, Maven有以下几种依赖范围:
Compile 编译依赖范围。 如果没有指定,就会默认使用该依赖范围。 使用此依赖范围的Maven依赖, 对于编译,测试,运行都有效。
Test: 测试依赖范围。 只在测试的时候需要。比如junit
Provided: 已提供依赖范围。 使用此依赖范围的Maven依赖,对于编译和测试有效, 但在运行时无效。 典型的例子是servlet-API, 编译和测试项目的需要, 但在运行项目时, 由于容器已经提供, 就不需要Maven重复地引入一遍。
Runtime: 运行时依赖范围。 使用此依赖范围的Maven依赖,对于测试和运行有效, 但在编译代码时无效。 典型的例子是:jdbc驱动程序, 项目主代码的编译只需要jdk提供的jdbc接口,只有在执行测试或者运行项目的时候才需要实现上述接口的具体jdbc驱动。
System: 系统依赖范围。 一般不使用。
传递性依赖
传递依赖机制, 让我们在使用某个jar的时候就不用去考虑它依赖了什么。也不用担心引入多余的依赖。 Maven会解析各个直接依赖的POM,将那些必要的间接依赖,以传递性依赖的形式引入到当前项目中。
注意: 传递依赖有可能产生冲突!!
冲突场景:
A-->B--->C (2.0)
A-->E--->C (1.0)
如果A下同时存在两个不同version的C,冲突!!(选取同时适合A、B的版本)
<dependencies>
<dependency>
<groupId>A</groupId>
<artifactId>A</artifactId>
<version>xxx</version>
<exclusions>
<exclusion>
<groupId>C</groupId>
<artifactId>C</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>B</groupId>
<artifactId>B</artifactId>
</dependency>
</dependencies>
a