1 Why?
Maven是干什么用的?这是很多同学在学完这个课程后最大的问题。之所以会提出这个问题,是因为即使不使用Maven我们仍然可以进行B/S结构项目的开发。从表述层、业务逻辑层到持久化层再到数据库都有成熟的解决方案——不使用Maven我们一样可以开发项目啊?所以我们有必要通过企业开发中的实际需求来看一看哪些方面是我们现有技术的不足。
1.1 添加第三方jar包
在今天的JavaEE开发领域,有大量的第三方框架和工具可以供我们使用。要使用这些jar包最简单的方法就是复制粘贴到WEB-INF目录下的lib目录下。但是这会导致每次创建一个新的工程就需要将jar包重复复制到lib目录下,从而造成工作区中存在大量重复的文件。
而使用Maven后每个jar包只在本地仓库中保存一份,需要jar包的工程只需要维护一个文本形式的jar包的引用——我们称之为“坐标”。不仅极大的节约了存储空间,让项目更轻巧,更避免了重复文件太多而造成的混乱。
1.2 jar包之间的依赖关系
jar包往往不是孤立存在的,很多jar包都需要在其他jar包的支持下才能够正常工作,我们称之为jar包之间的依赖关系。最典型的例子是:commons-fileupload-1.3.jar依赖于commons-io-2.0.1.jar,如果没有IO包,FileUpload包就不能正常工作。
那么问题来了,你知道你所使用的所有jar包的依赖关系吗?当你拿到一个新的从未使用过的jar包,你如何得知他需要哪些jar包的支持呢?如果不了解这个情况,导入的jar包不够,那么现有的程序将不能正常工作。再进一步,当你的项目中需要用到上百个jar包时,你还会人为的,手工的逐一确认它们依赖的其他jar包吗?这简直是不可想象的。
而引入Maven后,Maven就可以替我们自动的将当前jar包所依赖的其他所有jar包全部导入进来,无需人工参与,节约了我们大量的时间和精力。用实际例子来说明就是:通过Maven导入commons-fileupload-1.3.jar后,commons-io-2.0.1.jar会被自动导入,程序员不必了解这个依赖关系。
1.3 处理jar包之间的冲突
上一点说的是jar包不足项目无法正常工作,但其实有的时候jar包多了项目仍然无法正常工作,这就是jar包之间的冲突。
举个例子:我们现在有三个工程MakeFriend、HelloFriend、和Hello、MakeFriend依赖HelloFriend,HelloFriend依赖Hello。而Hello依赖log4j.1.2.17.jar,HelloFriend依赖log4j.1.2.14.jar。如下图所示:
那么MakeFriend工程的运行时环境中该导入log4j.1.2.14.jar呢还是log4j.1.2.17.jar呢?
这样的问题一个两个还可以手工解决,但如果系统中存在几十上百的jar包,他们之间的依赖关系会非常复杂,几乎不可能手工实现依赖关系的梳理。
使用Maven就可以自动的处理jar包之间的冲突问题。因为Maven中内置了两条依赖原则:最短路径者优先和先声明者优先,上述问题MakeFriend工程会自动使用log4j.1.2.14.jar。
1.4 获取第三方jar包
JavaEE开发中需要使用到的jar包种类繁多,几乎每个jar包在其本身的官网上的获取方式都不尽相同。为了查找一个jar包找遍互联网,身心俱疲,没有经历过的人或许体会不到这种折磨。不仅如此,费劲心血找的jar包里有的时候并没有你需要的那个类,又或者又同名的类没有你要的方法——以不规范的方式获取的jar包也往往是不规范的。
①检查JAVA_HOME环境变量。Maven是使用Java开发的,所以必须知道当前系统环境中JDK的安装目录。
C:WindowsSystem32>echo %JAVA_HOME% C:Program FilesJavajdk1.8.0_101 |
②解压Maven的核心程序。
将apache-maven-3.zip解压到一个非中文无空格的目录下。例如:
E:apache-maven-3.5.0 |
③配置环境变量。
MAVEN_HOME |
E:apache-maven-3.5.0 |
path |
%MAVEN_HOME%in或E:apache-maven-3.5.0in |
④查看Maven版本信息验证安装是否正确
C:UsersAdministrator>mvn -v Apache Maven 3.5.0 (ff8f5e7444045639af65f6095c62210b5713f426; 2017-04-04T03:39:06+08:00) Maven home: E:apache-maven-3.5.0in.. Java version: 1.8.0_101, vendor: Oracle Corporation Java home: C:Program FilesJavajdk1.8.0_101jre Default locale: zh_CN, platform encoding: GBK OS name: "windows 7", version: "6.1", arch: "amd64", family: "windows" |
⑤配置本地仓库
[1]Maven默认的本地仓库:~.m2 epository目录。
Tips:~表示当前用户的家目录。
[2]Maven的核心程序并不包含具体功能,仅负责宏观调度。具体功能由插件来完成。Maven核心程序会到本地仓库中查找插件。如果本地仓库中没有就会从远程中央仓库下载。此时如果不能上网则无法执行Maven的具体功能。为了解决这个问题,我们可以将Maven的本地仓库指向一个在联网情况下下载好的目录。
[3]Maven的核心配置文件位置:
解压目录E:apache-maven-3.5.0confsettings.xml |
[4]设置方式
<localRepository>以及准备好的仓库位置</localRepository> |
<localRepository>D: epository</localRepository> |
2 坐标
2.1 几何中的坐标
[1]在一个平面中使用x、y两个向量可以唯一的确定平面中的一个点。
[2]在空间中使用x、y、z三个向量可以唯一的确定空间中的一个点。
2.2 Maven的坐标
使用如下三个向量在Maven的仓库中唯一的确定一个Maven工程。
[1]groupId:公司或组织的域名倒序+当前项目名称
[2]artifactId:当前项目的模块名称
[3]version:当前模块的版本
<groupId>com.jinghang.maven</groupId> <artifactId>Hello</artifactId> <version>0.0.1-SNAPSHOT</version> |
2.3 统一管理目标jar包的版本
以对Spring的jar包依赖为例:Spring的每一个版本中都包含spring-core、spring-context等jar包。我们应该导入版本一致的Spring jar包,而不是使用4.0.0的spring-core的同时使用4.1.1的spring-context。
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.0.0.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.0.0.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>4.0.0.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>4.0.0.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.0.0.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.0.0.RELEASE</version> </dependency> |
问题是如果我们想要将这些jar包的版本统一升级为4.1.1,是不是要手动一个个修改呢?显然,我们有统一配置的方式:
<properties> <spring.version>4.1.1.RELEASE</spring.version> </properties> |
…… |
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</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-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> |
这样一来,进行版本调整的时候只改一改地方就行了。
3 仓库
3.1 分类
[1]本地仓库:为当前本机电脑上的所有Maven工程服务。
[2]远程仓库
(1)私服:架设在当前局域网环境下,为当前局域网范围内的所有Maven工程服务。
(2)中央仓库:架设在Internet上,为全世界所有Maven工程服务。
(3)中央仓库的镜像:架设在各个大洲,为中央仓库分担流量。减轻中央仓库的压力,同时更快的响应用户请求。
4 Maven整合Eclipse
4.1 Maven插件安装
Eclipse自Kepler版本开始内置了Maven插件,所以Maven插件不需要额外安装,使用特定版本的Eclipse即可。
4.2 Maven插件的设置
①指定Maven核心程序的位置
[1]操作路径:Window→Preferences→Maven→Installations
[2]图解
②指定用户级别的配置文件位置
将Maven解压目录下confsettings.xml文件拷贝到~.m2目录下
5 第三个Maven项目
5.1 在Eclipse中创建Maven工程,步骤如下所示
bulid:此项在pom中可选,bulid包含了多个插件plugin用来辅助项目构建。
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
早期Maven默认的Java版本是1.6,此处显式声明使用Java1.8编译,源代码使用的是UTF-8
或者在settings文件中添加
<profile>
<id>jdk-1.8</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.8</jdk>
</activation>
<properties>
<maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile>
二、log4j
打印参数: Log4J采用类似C语言中的printf函数的打印格式格式化日志信息,如下:
%m 输出代码中指定的消息
%p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL
%r 输出自应用启动到输出该log信息耗费的毫秒数
%c 输出所属的类目,通常就是所在类的全名
%t 输出产生该日志事件的线程名
%n 输出一个回车换行符,Windows平台为“ ”,Unix平台为“ ”
%d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss , SSS},输出类似:2002年10月18日 22 : 10 : 28 , 921
%l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(TestLog4.java: 10 )
Resources目录下,创建一个log4j.properties的文件
### set log levels ###
log4j.rootLogger = debug , stdout, D , E
### 输出到控制台 ###
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
### 输出到日志文件 ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = logs/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG ## 输出DEBUG级别以上的日志
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
### 保存Debug信息到单独文件 ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = logs/error.log ## 异常日志文件名
log4j.appender.D.Append = true
log4j.appender.D.Threshold = ERROR ## 只输出ERROR级别以上的日志!!!
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
### 保存异常信息到单独文件 ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File = logs/error.log
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [%p] - %m%n
使用log4j
package com.xwx.text;
import org.apache.log4j.Logger;
import org.junit.Test;
public class Test {
private static Logger log = Logger.getLogger(Test.class.getClass());
@Test
public void testLog(){
log.debug("debug");
log.error("error");
}
}