本文章是结合轻量级JavaWeb企业级应用实战所写的学习总结记录文章,开发环境部署文章仍然使用的是我的旧文章习惯,在下一章我会使用新的文章书写习惯来更清晰和简便的记录

Tomcat的安装

tomcat的安装
所选版本是9.0.26
进入官网:http://tomcat.apache.org/
点击左侧Download的9.0下载,选择Archives(档案),来选择旧版本
9.0.26大概是2019-09-19时间,点击该文件夹目录然后点击bin目录
进入到bin目录后下滑找到apache-tomcat-9.0.26.zip一项,点击下载,大小为12M
然后进入系统环境变量
新建系统变量 CATALINA_BASE和CATALINA_HOME变量值为Tomcat存放目录
双击Path,点击新建输入
%CATALINA_HOME%\bin
%CATALINA_HOME%\lib
进入到Tomcat存放目录进入到bin中找到startup.bat来启动tomcat
只要弹出命令行窗口并且有代码不断执行就表示启动成功了
打开浏览器输入URL:http://localhost:8080/
如果打开了Tomcat首页,表示服务器启动成功了
Tomcat目录解析

  • bin:存放启动和关闭Tomcat的命令的路径
  • conf:存放Tomcat的配置,所有Tomcat的配置都在该路径下设置
  • lib:存放Tomcat服务器的核心类库(JAR文件),如果需要扩展Tomcat功能,也可将第三方类库复制到该路径下
  • logs:这是一个空路径,该路径用于保存Tomcat每次运行后产生的日志
  • temp:保存web应用运行过程中生成的临时文件
  • webapps:该路径用于自动部署Web应用,将Web应用赋值到该路径下,Tomcat会将该应用自动部署在容器中
  • work:保存Web应用在运行过程中编译生成的class文件。该文件夹可以删除,但每次启动Tomcat服务器时,系统将再次建立该文件夹
  • LICENSE等相关文档

注意:此处JAVA_HOME环境变量应该指向JDK的安装路径,不是JRE安装路径。在JDK安装路径下应该包含bin目录,在该目录下应该有javac.exe、javadoc.exe等程序

配置Tomcat的服务器端口

Tomcat默认端口号为8080,可以通过Tomcat配置文件来改变该服务端口,升值可以通过修改配置文件让Tomcat同时在多个端口提供服务
Tomcat的配置文件都放在conf目录下,控制端口的配置文件也放在该目录下。打开conf下的server.xml文件,定位到69行处,看到如下代码:

<Connector port="8080" protocol="HTTP/1.1"connectionTimeout="20000"redirectPort="8443" />

port="8080"就是Tomcat提供Web服务的端口,将8080修改成任意端口,建议使用1024以上的端口,避免与公用端口冲突。此处修改为8888,即Tomcat的Web服务的提供端口为8888。
经过修改port的配置,服务器端口更改为8888,此处就无法再通过原来的路径来访问Tomcat主页

使用新的端口号进入Tomcat服务器

如果要让Tomcat运行多个服务,只需要复制server.xml文件中的Service元素,并修改相应的参数,便可以实现Tomcat运行多个服务。当然,必须在不同的端口提供服务。

启动窗口乱码解决方案
原因是WIN10默认语言不匹配,去控制面板的语言选项中管理更改为Beat版,重新启动即可。

在Web应用的开发阶段,通常希望Tomcat能列出Web应用根路径下的所有页面,这样能更方便地选择需要调试的JSP页面。在默认情况下,出于安全考虑,Tomcat并不会列出Web应用根路径下的所有页面。为了让Tomcat列出Web应用根路径下的所有页面,可以打开Tomcat的conf目录下的web.xml文件,在该文件的121和第122两行,看到一个listings参数,该参数的值默认是false,将该参数的值改为true,即可让Tomcat列出Web应用根路径下的所有页面,listings翻译为列表的意思
即将这两行改为如下形式:

<init-param><param-name>listings</param-name><param-value>true</param-value>
</init-param>

进入控制台


上图所示右上角显示有三个控制台:一个是Server Status控制台,另一个是Manager App控制台,还有一个是Host Manager控制台。Server Status控制台用于监控服务器的状态,而Manager App控制台可以部署、监控Web应用,因此通常只需要使用Manager App控制台即可
上图右边的第二个按钮,就是进入Manager App控制台的连接,单击该按钮将出现登入界面

这个控制台必须输入用户名和密码才可以登入,控制台的用户名和密码是通过Tomcat的JAAS控制的

JASS的全称是Java Authentication Authorization Service(Java验证和授权API),它用于控制对Java Web应用的权限访问。

<security-constraint><!-- 访问/html/*资源需要manager-gui角色 --><web-resource-collection><web-resource-name>HTML Manager interface (for humans)</web-resource-name><url-pattern>/html/*</url-pattern></web-resource-collection><auth-constraint><role-name>manager-gui</role-name></auth-constraint></security-constraint><security-constraint><!-- 访问/text/*资源需要manager-script 角色 --><web-resource-collection><web-resource-name>Text Manager interface (for scripts)</web-resource-name><url-pattern>/text/*</url-pattern></web-resource-collection><auth-constraint><role-name>manager-script</role-name></auth-constraint></security-constraint><security-constraint><web-resource-collection><!-- 访问/jmxproxy/*资源需要manager-jmx角色 --><web-resource-name>JMX Proxy interface</web-resource-name><url-pattern>/jmxproxy/*</url-pattern></web-resource-collection><auth-constraint><role-name>manager-jmx</role-name></auth-constraint></security-constraint><security-constraint><!-- 访问/status/*资源可以使用以下任意一个角色 --><web-resource-collection><web-resource-name>Status interface</web-resource-name><url-pattern>/status/*</url-pattern></web-resource-collection><auth-constraint><role-name>manager-gui</role-name><role-name>manager-script</role-name><role-name>manager-jmx</role-name><role-name>manager-status</role-name></auth-constraint></security-constraint><!-- Define the Login Configuration for this Application --><!-- 确定JAAS的登入方式 --><login-config><auth-method>BASIC</auth-method><realm-name>Tomcat Manager Application</realm-name></login-config>

通过上面的配置文件可以知道,登录Manager App控制台可能需要不同的manager角色。对于普通开发者来说,通常需要访问匹配/html/*、/status/*的资源,因此为该用户分配一个manager-gui角色即可
Tomcai默认采用文件安全域,急用文件存放用户名和密码,Tomcat的用户由conf路径下的tomcat-users.xml文件控制。打开该文件,发现有如下内容:

<?xml version="1.0" encoding="UTF-8"?>
<tomcat-users>
</tomcat-users>

将其内容修改如下:

<?xml version="1.0" encoding="UTF-8"?>
<tomcat-users>
<!-- 增加一个角色,指定角色名即可 --><role rolename="manager-gui"/><!-- 增加一个用户,指定用户名、密码和角色即可 --><user username="manager" password="manager" roles="manager-gui"/>
</tomcat-users>

通过上面设置的信息,再去控制台Manager App输入信息登录

上图所示的控制台可以监控所有部署在该服务器下的Web应用,左边列出了所有部署在该Web容器内的Web应用程序,右边的5个按钮则用于控制,包括启动、停止、重新加载等
控制台下方的“部署”区则用于部署Web应用。Tomcat控制台提供两种方式部署Web应用:一种是将整个路径部署成Web应用;另一种是将WAR文件部署成Web应用(上图中看不到这种方式,在“部署”区下面,还有一个“服务器上部署的目录或WAR文件”区,用于部署WAR文件)

部署Web应用

在Tomcat中部署Web应用的方式主要有如下几种。

  • 利用Tomcat的自动部署
  • 利用控制台部署
  • 增加自定义的Web部署文件
  • 修改server.xml文件部署Web应用

利用Tomcat的自动部署是最简单、最常用的方式,只要将Web应用复制到Tomcat的webapps目录下,系统就会把应用部署到Tomcat中
利用控制台部署Web应用也很简单,只要在部署Web应用的控制台输入即可,本质依然是利用Tomcat的自动部署

第三种方式则无须将Web应用复制到Tomcat安装路径下,只是部署方式稍微复杂一点,需要在conf目录下新建Catalina目录,再在Catalina目录下创建localhost目录,最后在该目录下新建一个名字任意的XML文件——该文件就是部署Web应用的配置文件,该文件的主文件名将作为Web应用的虚拟路径。例如在conf/Catalina/localhost下增加一个dd.xml文件,该文件的内容如下:

<Context docBase="G:/publish/codes/01/aa" debug="0" privileged="true">
</Context>

上面配置文件中的粗体字代码指定了Web应用的绝对路径,再次启动Tomcat,Tomcat将会把G:/publish/codes/01/aa路径下的webDemo文件夹部署成Web应用。该应用的URL地址为:

http://<server_address>:<port>/dd

其中,URL中的dd就是Web部署文件的主名
还有一种方式是修改conf目录下的server.xml文件,修改该文件可能破坏Tomcat的系统文件,因此不建议采用

配置Tomcat的数据源

从Tomcat5.5开始,Tomcat内置了DBCP的数据源实现,所以可以非常方便地配置DBCP数据源
Tomcat提供了两种配置数据源的方式,这两种方式所配置的数据源的访问范围不同:一种是数据源可以让所有的Web应用都访问,被称为全局数据源;另一种数据源只能在单个的Web应用中访问,被称为局部数据源。
不管配置哪种数据源,都需要提供特定数据库的JDBC驱动。该书以MySQL为例来配置数据源,所以必须将MySQL的JDBC驱动程序复制到Tomcat的lib路径下
局部数据源无须修改系统的配置文件,只需要修改用户自己的Web部署文件,不会造成系统的混乱,而且数据源被封装在一个Web应用内,防止被其他Web应用访问,提供了更好的封装性
局部数据源只与特定的Web应用相关,因此在该Web应用对应的部署文件中配置,例如,为上面的Web应用增加局部数据源,修改Tomcat下的conf/Catalina/localhost中的dd.xml文件即可。为Context元素增加一个Resource子元素,增加局部数据源后的dd.xml文件内容如下:

<Context docBase="G/publish/codes/01/aa" debug="0" privileged="true"><!-- 其中,name指定数据源在容器中的JNDI名driverClassName指定连接数据库的驱动url指定数据库服务的URLusername指定连接数据库的用户名password指定连接数据库的密码maxActive指定数据源最大活动连接数maxIdle指定数据池中最大的空闲连接数maxWait指定数据池中最大等待获取连接的客户端--><Resource name="jdbc/dstest" auth="Container"type="java.sql.DataSource"driverClassName="com.mysql.cj.jdbc.Driver"url="jdbc:mysql://localhost:3306/javaee?serverTimezone=UTC"username="root" password="password" maxActive="5"maxIdel="2" maxWait="10000"/><Context/>

上面配置文件中的粗体字代码标出的Resource元素就为该Web应用配置了一个局部数据源,该元素的各属性指定了数据源的各种配置信息
JNDI的全称是Java Naming Directory Interface,即Java命名和目录接口,听起来非常专业,其实很简单:就是为某个Java对象起一个名字。例如,以上JNDI的用途就是为Tomcat容器中的数据源起一个名字:jdbc/dstest,从而让其他程序可以通过该名字访问该数据源对象
再次启动Tomcat,该Web应用即可通过该JNDI名字来访问数据源。下面是测试访问数据源的JSP页面代码片段

//初始化Context,使用InitialContext初始化ContextContext ctx = new InitialContext();/*通过JNDI查找数据源,该JNDI为java:comp/env/jdbc/dstest,分为两个部分java:comp/env是Tomcat固定的,Tomcat提供的JNDI绑定都必须加该前缀jdbc:dstest是定义数据源的数据源明*/DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/dstest");//获取数据库连接Connection conn = ds.getConnection();//获取StatementStatment stmt = conn.createStatement();//执行查询,返回ResultSet对象ResultSet rs = stmt.executeQuery("select*from news_inf");while(rs.next()){out.println(rs.getString(1)+"\t"+rs.getString(2)+"<br>");}

上面的DataSource代码实现了JNDI查找数据源对象,一旦获取了查找数据源对象一大,一旦获取了该数据源对象,程序就可以通过该数据源取得数据库连接,从而访问数据库
上面的方式是配置局部数据源,如果需要配置全局数据源,则应该通过的修改server,xml文件来实现,全局数据源的配置与局部数据源的配置基本类似,只是修改的文件不同。局部数据源只需要修改Web应用的配置文件,而全局数据源需要修改Tomcat的server.xml文件
使用全局数据源需要修改Tomcat原有的server.xml文件所以可能导致破坏Tomcat系统,因而尽量避免使用全局数据源

Eclipse的安装和使用

Eclipse平台是IBM向开源社区捐赠的开发框架,IBM官宣为开发Eclipse投入了4千万美元,这种巨大投入开发出了一个成熟的、精心设计的、可扩展的开发工具。Eclipse允许增加新工具来扩展Eclipse的功能,这些新工具就是Eclipse插件。

安装插件的方式

在线安装Eclipse插件

在线安装简单、方便,适合网络畅通的场景。在线安装可以保证插件的完整性,并可自由选择最新的版本。

在线安装的步骤:
一、 单击Eclipse的"Help"菜单,选择"Install New Software…"菜单项,如下图所示

二、弹出如下对话框,该对话框用于选择安装新插件或升级已有插件。该对话框的上面有一个“Work With”下拉列表框,通过该列表框可以选择Eclipse已安装过的插件。选择指定的插件项后,该对话框的下面将会列出插件所有的可升级的项目。

一定要保证网络畅通,而且Eclipse可以访问网络,否则选择指定的插件项后将看不到可升级的项目

三、如果需要升级已有插件,则通过“Work with”下拉列表选择指定插件,然后在下面勾选需要更新的插件项,单击“Next”按钮,Eclipse将出现升级界面
四、如果需要安装新插件,则通过点击“Add”按钮

五、在“Name”文本框中输入插件名(该名称是任意的,只用于标识该安装项),在“Location”文本框中输入插件的安装地址,输入完成后点击“OK”按钮
Eclipse插件的安装地址需要从各插件的官方站点查询

从本地压缩包安装插件

从本地压缩包安装插件,请按如下步骤进行
一、按前面步骤打开安装插件的对话框,单击“Archive…”按钮,系统弹出一个普通的文件选择对话框,用于选择Eclipse插件的本地压缩包
二、选择指定的插件压缩包,然后返回上图,此时将会看到“Location”文本框内已经插入了压缩包的位置。单击“OK”按钮,系统返回第一次打开的对话框按钮
三、勾选需要安装或升级的插件项,单击“Next”按钮,等待插件安装完成即可

手动安装Eclipse插件

手动安装只需要已经下载的插件文件,无须网络支持。手动安装适合没有网络支持的环境,手动安装的适应性广,但需要开发者自己保证插件版本与Eclipse版本的兼容性
手动安装也分两种安装方式

  • 直接安装
  • 扩展安装

直接安装
将插件中包含的plugins和features文件夹的内容直接复制到Eclipse的plugins和features文件夹内,重新启动Eclipse即可
直接安装简单、易用,但效果非常不好,因为容易导致混乱:如果安装的插件非常多,可能导致用户无法精准判断哪些是Eclipse默认的插件,哪些是后来扩展的插件
如果需要停用某些插件,则需要从Eclipse的plugins和features文件夹内删除这些插件的内容,安装和卸载的过程较为复杂
扩展安装
通常推荐使用扩展安装,扩展安装步骤
一、在Eclipse安装路径下新建links文件夹
二、在links文件夹中建立xxx.link文件,该文件的文件名是任意的,但为了有较好的可读性,通常推荐该文件的主文件名与插件名相同,文件名后缀为.link
三、编辑xxx.link内容,该文件内通常只需要如下一行:

path=<pluginPath>

上面内容中的path=是固定的,而<,pluginPath>是插件的扩展安装路径
四、在xxx.link文件中的<,pluginPath>路径下新建eclipse文件夹,然后在eclipse文件夹内建立plugins和features文件夹
五、将插件中包含的plugins和features文件夹中的内容,复制到上面建立的plugins和features文件夹中,重启Eclipse即完成安装
扩展安装的方式使得每个插件都被放在单独的文件夹内,因而结构非常清晰。如果需要卸载某个插件,只需要将该插件对应的link文件删除即可

使用Eclipse开发Java Web应用

为了开发Web应用,必须现在Eclipse中配置Web服务器,这里以Tomcat位例来介绍如何在Eclipse中配置Web服务器。在Eclipse中配置Tomcat按如下步骤进行
一、单击Eclipse主界面下方的“Servers”面板,在该面板的空白处单击鼠标右键,在弹出的快捷菜单中选择“New”->“Server”菜单项

添加Servlet9并且遵循Servlet4.0的开发规范,指定Tomcat路径后,在WebContext中新建一个JSP文件




将需要部署的项目移动到右边列表框内

导入Eclipse项目

很多时候,可能需要向Eclipse中导入其他项目。比如实际开发中可能需要导入其他开发者提供的Eclipse项目,在学习过程中可能需要导入网络、书籍中提供的示例项目。
向Eclipse中导入一个Eclipse项目比较简单
一、单击“File”->“Import…”菜单项

二、选择“General”->“Existing Projects into Workspace”节点,单击“Next”按钮,系统将弹出下图

三、输入项目保存位置,也可以通过Browse按钮来选择项目保存的位置,输入完成后,将看到“Projects”文本域内列出了所有可导入的项目,勾选需要导入的项目后,单击“Finish”按钮即可

导入非Eclipse项目

有些时候,也可能需要导入非Eclipse项目到Eclipse中、一、新建一个普通的Eclipse项目
二、单击“File”->“Import…”菜单项
三、选择“General”->“File System”节点,单击“Next”按钮
此对话框的左边有三个按钮,它们的作用分别是

  • Filter Types…:根据指定文件后缀来导入文件
  • Select All:导入指定目录下的所有文件
  • Deselect All:取消全部选择

四、输入需要导入文件的路径

不要指望将一个非Eclipse项目整体导入Eclipse工具中!毕竟,不同IDE工具对项目文件的组织方式完全不同!如果需要导入非Eclipse项目,只能采用导入文件的方式依次导入
将其他项目导入Eclipse中还有一种方式:直接进入需要被导入的项目路径下,将相应的文件赋值到Eclipse项目的路径下即可
以Eclipse的一个Web项目为例,将Web项目导入Eclipse下只需如下三步
一、将其他Web项目的所有Java源文件(通常位于src目录下)所在路径下的全部内容一起复制到Eclipse Web项目的src目录下
二、将其他Web项目的JSP页面、WEB-INF整个目录一起复制到Eclipse Web 项目的WebContent目录下
三、返回Eclipse主界面,选择Eclipse主界面左边项目导航树中指定项目对应的节点

Ant的安装和使用

Ant是一种基于Java的生成工具。从作用上看,它有些类似于C编程(UNIX平台上使用较多)中的Make工具,C/C++项目经常使用Make工具来管理整个项目的编译、生成
Make使用Shell命令来定义生成任务,并定义任务之间的依赖关系,以便它们总是以必需的顺序来执行
Make工具主要有如下两个缺陷

  • Make工具的本质还是依赖UNIX平台的Shell语言,所以Make工具无法跨平台
  • Make工具的生成文件的格式比较严格,容易导致错误

Ant是基于Java语言的生成工具,所以具有跨平台的能力;而且Ant工具使用XML来编写生成文件,因而具有更好的适应性
由此可见,Ant是Java世界的Make工具,而且这个工具是跨平台的,并且具有简单、易用的特性
由于Ant具有跨平台性,所以编写Ant生成文件时可能会失去一些灵活性。为了弥补这个不足,Ant提供了一个“exec”核心任务,这个任务允许执行特定操作系统上的命令

Ant的下载和安装

https://archive.apache.org/dist/ant/source/

先找到官网然后进行搜索

下载后解压到一个位置
为环境变量中添加以下配置

JAVA_HOME -> JDKPath
ANT_HOME -> ANTPath
Path add -> %ANT_HOME%\bin

配置完毕后在命令行输入命令ant.bat
出现以下信息则表示安装成功

ant目录

  • bin:启动和运行Ant的可执行命令
  • etc:包含一些样式单文件,通常无须理会该目录下的文件
  • lib:包含Ant的核心类库,以及编译和运行Ant所依赖的第三方类库
  • manual:Ant工具的相关文档,这些文档对学习使用Ant有很大的作用
  • LICENSE等说明性文档

使用Ant工具

使用Ant非常简单,当正确安装Ant后,只要输入ant或ant.bat即可,如果运行ant命令时没有指定任何参数,Ant会在当前目录下搜索build.xml文件。如果找到了就以该文件作为生成文件,并执行默认的target
如果运行时使用-find或者-s选项(这两个选择的作用完全相同),Ant就会到上级目录中搜索生成文件,直至到达系统文件的根路径
要想让Ant使用其他生成文件,可以用-buildfile<生成文件>选项,其中buildfile可以使用-file或-f来替代,这三个选项的作用完全一样。例如以下命令:

ant -f a.xml //显式指定使用a.xml作为生成文件
ant -file b.xml //显式指定使用b.xml作为生成文件

如果希望Ant运行时只输出少量的必要信息,则可以使用-quiet或-q选项;如果希望Ant运行时输出更多的提示信息,则可以使用-verbose或-v选项
如果希望Ant运行时将提示信息输出到指定文件中,而不是直接输出到控制台,则可使用-logfile<,file>或-l<,file>选项

ant -verbose -l a.log //运行Ant时生成更多的提示信息,并将提示信息输出到a.log文件中

除此之外,Ant还允许运行时指定一些属性来覆盖生成文件中指定的属性值(使用Property task来指定)。比如使用-D<,property>=<,value>,则此处指定的value将会覆盖生成文件中property的属性值

ant -Dbook=Spring5 //该命令将会覆盖生成文件中的book属性值

通过该方法可以操作系统的环境变量值传入生成文件中。例如,在运行Ant工具时使用如下命令

ant -Denv1=%ANT_HOME%

上面命令用于向生成文件传入一个env1属性,而该属性的值并没有直接给出,而是用%ANT_HOME%的形式给出——这是Windows下访问环境变量的方式。通过这种方式,就可以将Windows环境变量值传入生成文件中了。如果希望在生成文件中访问到该环境变量的值,则使用$env1即可。
在默认情况下,Ant将会运行生成文件中指定的默认target,如果运行Ant时显式指定希望运行的target,则可采用如下命令格式:

ant [target[target2[target3]...]]

可以通过

ant -help

定义生成文件

实际上,使用Ant的关键就是编写生成文件,生成文件定义了项目的各个生成任务(以target来表示,每个target表示一个生成任务),并定义了生成任务之间的依赖关系
Ant生成文件的默认名为bulid.xml,也可以取其他名字。但如果以该生成文件起了其他名字,则意味着要将这个文件名作为参数传给Ant工具。生成文件可以放在项目的任何位置,但通常放在项目的顶层目录中,这样有利于保持项目的简洁和清晰
下面是一个典型的项目层次结构
project:该文件夹存放了整个项目的全部资源
->src:存放源文件,各种配置文件
->classes:存放编译后的class文件
->lib:存放第三方JAR包
->dist:存放项目打包
->build.xml:Ant生成文件

Ant生成文件的根元素是<project./>,每个项目可以定义多个生成目标,每个生成目标以一个<target…/>元素来定义,它是<project…/>元素的子元素

<project…/>元素可以有多个属性,该元素的常用属性如下

  • default:指定默认target,这个属性是必须的。如果运行ant.bat命令时没有显式指定项执行的target,Ant将执行该target
  • basedir:指定项目的基准路径,生成文件中的其他相对路径都是基于该路径的
  • name:指定项目名,该属性仅指定一个名字,对编译、生成项目没有太大的实际作用
  • description:指定项目的描述信息,对编译、生成项目没有太大的实际作用

例如,如下代码片段

<?xml version="1.0" encoding="utf-8" ?>
<!-- 下面的配置信息指定基准路径是当前路径,默认target为空
<project name="spring" description="demo" basedir="." default="">
...
</project>
-->

每个生成目标对应一个<target…/>,该元素可指定如下属性

  • name:指定该target的名称,该属性是必须的。该属性非常重要,当希望Ant执行指定的生成目标时,就是根据该name来确定生成目标的,因此可以得出一个结论——在同一个生成文件中不能有两个同名的target元素
  • depends:该属性可指定一个或多个target名,表示在执行该target之前应先执行该depends属性所指定的一个或多个target
  • if:该属性指定一个属性名,用属性表示仅当前设置了该属性时才执行此target
  • unless:该属性指定一个属性名,用属性表示仅当没有设置该属性时才执行多次target
  • description:指定该target的描述信息

例如,如下配置片段

<!-- 下面表示执行run target之前,必须先执行compile target -->
<target name="run" depends="compile"/>
<!-- 只有设置了prop1属性,才会执行exA target -->
<target name="exA" if="prop1"/>
<!-- 只要没有设置prop2属性,就可以执行exB target -->
<target name="exB" unless="prop2"/>

每个生成目标又可能由一个或多个任务序列组成,当执行某个生成目标时,实际上就是依次完成该目标所包含的全部任务。每个任务由一段可执行的代码组成
定义任务的代码格式如下

<name attribute1="value1" attribute2="value2" .../>

上面代码中name是任务的名称,attributeN和valueN用于指定执行该任务所需的属性名和属性值
简而言之,Ant生成文件的基本结构是 project/> 元素里包含多个 target/>元素,而每个 target/>元素里包含多个任务,看下图结构示意

Ant的任务可以分为如下三类

  • 核心任务:Ant自带的任务

  • 可选任务:来自第三方的任务,因此需要一个附加的JAR文件

  • 用户自定义的任务:用户自己开发的任务
    此外,<project…/>元素还拥有如下两个重要的子元素

  • <project…/>:用于定义一个或多个属性

  • <path…/>:用于定义一个或多个文件和路径

一、property元素
<property…/>元素用于定义一个或多个属性,Ant生成文件中的属性类似于编程语言中的宏变量,它们都具有名称和值。与编程语言不同的是,Ant生成的文件中的属性值不可改变
定义一个属性的最简单形式如下:

<!-- 下面代码定义了一个名为builddir的属性,其值为dd -->
<project name="builddir" value="dd"/>

如果需要获取属性值,则使用${propName}的形式。例如,如下代码即可获取builddir属性值

<!-- 输出builddir属性值 -->
${builddir}

由此可见,"$"符号在Ant沙僧陈文件中具有特殊的意义,如果希望Ant将生成文件中的美元符号当成普通字符,可以使用“两个美元符号”。例如,如下配置片段

<echo>$${builddir}=${builddir}</echo>

上面代码中的$${builddir}不会获取builddir属性值,而美元符号{builddir}才会获取builddir属性值,执行上面任务,将会输出

[echo] ${builddir}=dd

echo是Ant的核心任务之一,该任务直接输出某个字符串,通常用于输出某些提示信息

实际上,<project…/>元素可以接受如下几个常用属性

  • name:指定需要设置的属性名
  • value:指定需要设置的属性值
  • resource:指定属性文件的资源名称,Ant将负责从属性文件中读取属性名和属性值
  • file:指定属性文件的文件名,Ant将负责从属性文件中读取属性名和属性值
  • url:指定属性文件的URL地址,Ant将负责从属性文件中读取属性名和属性值
  • environment:指定系统环境变量的前缀。通过这种方式允许Ant访问系统环境变量
  • classpath:指定搜索属性文件的classpath
  • classpathref:指定搜索属性文件的classpath引用,该属性并不是直接给出classpath值,而是引用了<path…/>元素定义的文件集或路径集

关于文件集合和路径集以及文件集合路径集引用的知识,请参考<path…/>元素和<classpath…/>元素

下面给出几个使用<project…/>元素的例子

<!-- 指定读取foo.properties属性文件中的属性名和属性值 -->
<property file="foo.properties"/>

从网络中读取属性名和属性值

<!-- 指定从指定URL处读取属性名和属性值 -->
<property url="http://www.crazyit.org/props/foo.properties" />

通过<property…/>元素所读取的属性文件就是普通的属性文件,该文件的内容由一系列的name=value组成,如下面的配置片段所示

author=Yeeku.H.Lee
book=Light Weight Java EE
price=128

此外,通过<property…/>元素可以让Ant生成文件访问到操作系统的环境变量值,例如以下代码:

<!-- 定义访问操作系统环境变量的前缀是env -->
<property environment="env" />

定义了上面的<property…/>元素之后,就可以在Ant生成文件中通过如下形式来访问操作系统的环境变量

<!-- 输入JAVA_HOME环境变量的值 -->
<echo>${env.JAVA_HOME}</echo>

在我们的机器上运行上面的任务,即可看到输出:[echo]D:\Java\jdk-11.0.1,这就是该机器上JAVA_home环境变量的值
二、path元素和classpath元素
使用Ant编译、运行Java文件时常常需要引入第三方JAR包,这就是需要使用<classpath…/>元素了。<path…/>元素和<classpath…/>元素都用于定义文件集合路径集,区别是<classpath…/>元素通常作为其他任务的子元素,即可引用已有的文件集和路径集,也可临时定义一个文件集和路径集;而<path…/>元素则作为<project…/>元素的子元素,用于定义一个独立的、有名称的文件集和路径集,用于被引用
因为<path…/>和<classpath…/>都用于定义文件集和路径集,所以也将<path…/>和<classpath…/>元素定义的内容称为Path-likeStructure(似目录结构)
<path…/>和<classpath…/>元素都用于收集文件集和路径集,这两个元素都可接受如下子元素

  • <dirset…/>:采用模式字符串的方式指定系列目录

  • <fileset…/>:采用模式字符串的方式指定系列文件

  • <filelist…/>:采用直接列出系列文件名的方式指定系列文件

  • <pathelement…/>:用于指定一个或多个目。该元素可以指定如下两个属性中的一个

    • path:指定一个或多个目录(或者JAR文件),多个目录或JAR文件之间以英文冒号(:)或英文分号(;)分开
  • location:指定一个目录和JAR文件

因为JAR文件还可以包含更多层次的文件结构,所以可以将JAR文件看成一个文件路径

例如下面配置片段

<!-- 定义/path/to/file2jar、/path/to/class2和/path/to/class3所组成的路径集 -->
<pathelement path="/path/to/file2.jar:/path/to/class2;/path/to/class3"/>
<!-- 定义由lib/helper.jar单个文件对应的目录 -->
<pathelement location="lib/helper.jar"/>

如果需要指定路径集,则应该使用<dirset…/>元素,该元素需要一个dir属性,该属性指定该路径集的根路径。此处之外,<dirset…/>还可以使用<inclubde…/>和<exclubde…/>两个子元素来指定包含和不包含哪些目录。例如下面的配置片段

<!-- 指定该路径集的根路径是build目录 -->
<dirset dir="build"><!-- 指定包含apps目录下的所有classes目录 --><include name="apps/**/classes" /><!-- 指定排除目录名中有Test子串的目录 --><exclude name="apps/**/*Test*"/>
</dirset>

上面的配置文件代表build/apps目录下所有名为classes且文件名中不包含Test子串的目录
如果希望配置多个文件,则可用<fileset…/>或<filelist…/>元素,通常<fileset…/>使用模式字符串来匹配文件集,而<filelist…/>则通过列出文件名的方式来指定文件集
<filelist…/>元素需要指定如下两个属性

  • dir:必须属性,指定文件集里多个文件所在的基准路径
  • files:文件列表,多个文件之间以英文逗号(,)或空白隔开

例如下面的配置片段

<!-- 配置src/foo.xml和src/bar.xml文件组成的文件集 -->
<filelist id="docfiles" dir="src" files="foo.xml,bar.xml"/>

几乎所有的Ant元素都可以指定两个属性:id和refid其中id用于为该元素指定一个唯一标识,而refid用于指定引用另一个元素。例如下面的filelist配置

<filelist refid="docfiles"/>

该<filelist…/>元素所包含的文件和前面docfiles文件集里包含的文件完全一样
实际上,<filelist…/>还允许使用多个<file…/>子元素来指定文件列表,例如下面的配置片段

<filelist id="docfiles" dir="${doc.src}"><!-- 通过两个file子元素指定的文件列表和通过files属性指定的文件列表完全一样 --><file name="foo.xml"/><file name="bar.xml"/>
</filelist>

<fileset…/>元素可指定如下两个属性

  • dir:必需属性,指定文件集里多个文件所在的基准路径
  • casesensitive:指定是否区分大小写

此外,<filest…/>元素还可以使用<include…/>和<exclude…/>两个子元素来指定包含和不包含哪些文件。例如下面的配置片段

<!-- 定义src路径下的文件集 -->
<fileset dir="src" casesensitive="yes"><!-- 包含所有的*.java文件 --><include name="**/*.java"/><!-- 排除文件名中有Test子串的文件 --><exclude name="**/*Test*"/>

掌握了<pathelement…/>、<dirset…/>、<filelist…/>和<fileset…/>4个元素的用法之后,就可以使用<path…/>或者<classpath…/>将它们组合在一起使用了,例如下面的配置片段

<path id="classpath"><!-- 定义classpath属性值所代表的路径 --><pathelement path="${classpath}"/><!-- 定义lib路径下的所有*.jar文件 --><fileset dir="lib"><include name="**/*.jar"/></fileset><!-- 定义classes路径 --><pathelement location="classes"/><!-- 定义build/apps路径下的所有classes路径 --><dirset dir="build"><include name="apps/**/classes"/><exclude name="apps/**/*Test*"/></dirset>    <!-- 定义res路径下的a.properties和b.xml文件 --><filelist dir="res" files="a.properties,b.xml"/>
</path>

Ant的任务

现在已经掌握了Ant生成文件的基本结构,以及<project…/>、<target…/>等元素的配置方式。而<target…/>元素的核心就是task(任务),即每个<target…/>由一个或多个task组成。
Ant提供了大量的核心task和可选task,除此之外,Ant还允许用户定义自己的task,这大大扩展了Ant的功能

  • javac:用于编译一个或多个Java源文件,通常需要srcdir和destdir两个属性,用于指定Java源文件的位置和编译后class文件保存的位置
  • java:用于允许某个Java类,通常需要classname属性,用于指定需要运行哪个类
  • jar:用于生成JAR包,通常需要指定destfile属性,用于指定所生成的JAR包的文件名,此外,通常还应指定一个文件集,表明需要将哪些文件打包到JAR包里
  • sql:用于执行一条或多条SQL语句,通常需要driver、url、userid和password等属性,用于指定连接数据库的驱动类、数据库URL、用户名和密码等,还可以通过src来指定所需要的SQL脚本文件,或者直接使用文本内容的方式指定SQL脚本字符串
  • echo:输出某个字符串
  • exec:执行操作系统的特定命令,通常需要executable属性,用于指定项执行的命令
  • copy:用于赋值文件或路径
  • delete:用于删除文件或路径
  • mkdir:用于创建文件夹
  • move:用于移动文件或路径

在%ANT_HOME%\manual\Tasks路径下包含了Ant的所有的task介绍文档
下面定义了一份简单的生成文件,这份生成文件里包含了编译Java文件、运行Java程序、生成JAR包等常用的target,通过这份文件就可以非常方便的管理该项目

<? xml version="1.0" encoding="utf-8" ?>
<!-- 定义生成文件的project根元素,默认的target为空 -->
<project name="antQs" basedir="." default=""><!-- 定义三个简单属性 --><property name="src" value="src"/><property name="classes" value="classes" /><property name="dest" value="desc" /><!-- 定义一组文件和路径集 --><path id="classpath"><pathelement path="${classes}"/></path><!-- 定义help target,用于输出该生成文件的帮助信息 --><target name="help" description="打印帮助信息"><echo>help - 打印帮助信息</echo><echo>compile - 编译Java源文件</echo><echo>run - 运行程序</echo><echo>build - 打包JAR包</echo><echo>clean - 清除所有编译生成的文件</echo></target><!-- 定义compile target,用于编译Java源文件 --><target name="compile" description="编译Java源文件"><!-- 先删除classes属性所代表的文件夹 --><delete dir="${classes}"/><!-- 创建classes属性所代表的文件夹 --><mkdir dir="${classes}"/><!-- 编译Java文件,将编译后的class文件放到classes属性所代表的文件夹内 --><javac destdir="${classes}" debug="true" includeantruntime="yes"deprecation="false" optimize="false" failonerror="true" encoding="utf-8"><!-- 指定需要编译的Java文件所在的位置 --><src path="${src}"/><!-- 指定编译Java文件所需要的第三方类库所在的位置 --><classpath refid="classpath"/></javac>   </target><!-- 在定义run target,用于运行Java源文件,在运行该target之前会先运行compile target--><target name="run" description="运行程序" depends="compile"><!-- 运行lee.HelloTest类,其中fork指定启动弄另一个JVM来执行java命令 --><java classname="lee.HelloTest" fork="yes" failonerror="true"><classpath refid="classpath"/><!-- 在运行Java程序时传入两个参数 --><arg line="测试参数1 测试参数2"/></java></target><!-- 定义build target,用于打包JAR文件,在运行该target之前会先运行compile target --><target name="build" description="打包JAR文件" depends="compile"><!-- 删除dest属性所代表的文件夹 --><delete dir="${dest}"/><!-- 创建dest属性所代表的文件夹 --><mkdir dir="${dest}"/><!-- 指定将classes属性所代表的文件夹下所有*.classes文件都打包到app.jar文件中 --><jar destfile="${dest}/app.jar" basedir="${classes}"includes="**/*.class"><!-- 为JAR的清单文件添加属性 --><manifest><attribute name="Main-Class" value="lee.HelloTest"/></manifest></jar></target><!-- 定义clean target,用于删除所有编译生成的文件 --><target name="clean" description="清除所有编译生成的文件"><!-- 删除两个目录,目录下的文件也一并删除 --><delete dir="${classes}"/><delete dir="${dest}"/></target>
</project>

在上面的生成文件中,在定义java task时代码指定了fork=“yes”(或fork=“true”,效果一样),这表明启动另一个JVM进行来运行lee.HelloTest类,这个属性通常是一个陷阱!如果不指定该属性,该属性默认是false,这表明使用允许Ant的同一个JVM来运行Java程序,这将导致随着Ant工具执行完成,被执行的Java程序也不得不退出——这当然不是开发者希望看到的。
上面配置定义生成的文件里包含了5个target,这些target分别完成打印帮助信息、编译Java、运行Java程序、打包JAR包和清除编译生成的文件。执行这些target可食用如下命令

  • ant help:输出该生成文件的帮助信息
  • ant compile:编译Java文件
  • ant run:运行lee.HelloTest类
  • ant build:将classes路径下的所有class文件打包成app.jar,并放在dest目录下
  • ant clean:删除classes和dest两个目录

Maven的安装和使用

Maven是一个比Ant更先进的项目管理工具,它采用一种“约定由于配置(Coc)”的策略来管理项目。使用Maven不仅可以把源代码构建成可发布的项目(包括编译、打包、测试和分发),还可以生成报告、生成Web站点等。在某些方面,Manven比Ant更加优秀,因此不少企业已经开始使用Maven

下载和安装Maven

将Maven解压目录更名为Maven362

目录解析:

  • bin:保存Maven的可执行命令。其中mvn和mvn.bat就是执行Maven工具的命令
  • boot:该目录只包含一个plexus-classworlds-2.6.0.jar。plexus-classworlds是一个类加载器框架,与默认的Java类加载器相比,它提供了更丰富的语法以及方便配置,Maven使用该框架加载自己的类库。通常无须理会该文件
  • conf:保存Maven配置文件的目录,该目录包含settings.xml文件,该文件用于设置Maven的全局行动。通常建议将该文件复制到~/.m2/目录下(表示用户名录)这样可以只设置当前用户的Maven行为
  • lib:该目录包含所有Maven运行时需要的类库,Maven本身是分模块开发的,因此用户能看到诸如maven-core-3.6.2、maven-repository-metadata-3.6.2.jar等文件。此外,还包含Maven所依赖的第三方类库
  • LICENSE、README.txt等说明性文档

重名Maven文件夹仅仅是为了方便、简介,并不是必须的

运行Maven需要如下两个环境变量

  • JAVA_HOME:该环境变量应指向JDK安装
  • M2_HOME:该环境变量指向Maven安装路径。
    M2_HOME的值应该为D:\Maven362

Maven安装路径就是前面释放Maven压缩文件的路径。在Maven安装路径下应该包含bin、boot、conf和lib这四个文件夹

Maven工具的关键命令就是%M2_HOME%\bin路径下的命令,建议将%M2_HOME%\bin添加到系统PATH环境变量中
经过上面步骤后,打开命令行界面输入

mvn help:system


Maven的运行概念是Maven主概念去调用各个插件,所以不管每次哪个操作第一次都需要去网上下载很多东西

设置Maven

设置Maven行为有两种方式

  • 全局方式:通过Maven安装目录下的conf\settings.xml文件进行设置
  • 当前用户方式:通过用户Home目录(以Windows7为例,用户Home目录为C:Users\用户名\)的.m2\目录下的settings.xml文件进行设置

上面两种方式只是起作用的范围不同,它们都使用settings.xml作为配置文件,而且这两种方式中settings.xml文件允许定义的元素也是相同的
通常来说,Maven允许设置如下参数

  • localRepository:该参数通过 <localRepository…/>元素设置,该元素的内容是一个路径字符串,该路径用于设置Maven的本地资源库路径。如果用户不设置该参数,Maven本地资源默认保存在用户Home目录的.m2/repository路径下。考虑到Windows经常需要重装、回复系统,因此建议将该Maven本地资源库设置到其他路径下。例如,此处将该属性设置为D:\maven_repo,这意味着Maven将会把所有插件都下载到D:\maven_repo目录下

资源库是Maven的一个重要概念,Maven构建项目所使用的插件、第三方依赖库都被集中放在本地资源库中

  • interactiveMode:该参数通过<interactiveMode…/>元素设置。该参数设置Maven是否处于交互模式——如果将Maven设置为交互模式,每当Maven需要用户输入时,Maven都会提示用户输入。但如果将该参数设置为false,那么Maven将不会提示用户输入,而是“智能”地使用默认值
  • offline:该参数设置Maven是否处于离线状态。如果将该参数设置为false,每当Maven找不到插件、依赖库时,Maven总会尝试从网络上下载
  • proxies:该参数用于为Maven设置代理服务器。该参数可包含多个<proxy…/>,每个<proxy…/>设置一个代理服务器,包括代理服务器的ID、协议、代理服务器地址、代理服务器端口、用户名、密码等信息,Maven可通过代理服务器访问网络
  • mirrors:该参数用于设置一系列Maven远程资源库的镜像。有时候连接不上Maven的国外资源库时,可连接国内镜像

如果网络通畅,通常只需要通过localRepository设置Maven的本地资源库路径,接下来既可正常使用Maven工具了。
前面已经提到,Maven工具的命令主要就是mvn,该命令的基本格式如下:

mvn <plugin-prefix>:<goal> -D<属性名>=<属性值> ...

以上命令中,plugin-prefix是一个有效的插件前缀,goal是该插件所包含的指定目标,-D用于为该目标指定属性,每次运行mvn命令都可通过多个-D选项来指定属性名、属性值。

除使用plugin-prefix的形式来代表指定插件之件,还可使用如下命令来运行指定插件

mvn <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>

其中,plugin-group-id、plugin-artifact-id、plugin-version被称为Maven坐标,可用于唯一表示某个项目
对于前面验证Maven是否安装成功所用的命令:mvn help:system,其中的help就是一个典型的Maven插件,system就是help插件中的goal。
Maven插件是一个非常重要的概念,从某种程序来看,Maven核心是一个空的“容器”,Maven核心其实并不做什么实际的事情,它只是解析了一些XML文档,管理声明周期和插件,除此之外,Maven什么也不懂。Maven的强大来自它的插件,这些插件可以编译源代码、打包二进制代码、发布站点等。换句话说,Maven的“空”才是它的强大支处,因为Maven是“空”的,它可以装各种插件,因此它的功能可以无限扩展。直接从Apache下载的Maven不知道如何编译Java代码,不知道如何打包WAR文件,也不知道如何运行单元测试…它什么都不懂。当开发者第一次使用全新的Maven运行诸如mvn install命令时,Maven会自动从远程资源库下载大部分核心Maven插件

创建简单的项目

创建项目使用Maven的archetype插件,关于Maven插件的功能和用法可登入Maven官网上Maven Plugins中查看

  • archetype:generate:使用指定原型创建一个Maven项目
  • archetype:create-from-project:使用已有的项目创建Maven项目
  • archetype:crawl:从仓库中搜索原型

上面项目会生成一个mavenQs文件夹
pom文件如下

pom.xml文件被称为项目对象模型(Project Object Model,POM)描述文件,Maven使用项目对象模型的方式来管理项目。POM用于描述该项目是什么类型的、该项目的名称是什么、该项目的构建是否自定义,Maven使用pom.xml文件来描述项目对象模型。因此,pom.xml并不是简单的生成文件,而是项目对象模型描述文件
由于本书使用Java11作为默认的编译、运行环境,Java11不再支持编译Java5的源代码,而Maven默认使用Java5的编译级别,因此需要通过属性告诉compiler插件使用更高级的编译级别。可以在上面pom.xml文件的<project…/>根元素中增加如下配置:

<properties><maven.compiler.source>1.6</maven.compiler.source><maven.compiler.target>1.6</maven.compiler.target></properties>

在pom.xml文件所在的路径中输入如下命令

mvn compile


使用Maven的exec插件来执行Java类。使用Maven执行Java程序的命令

mvn exec:java -Dexec.mainClass="org.fkjava.mavenqs.App"

Maven运行时,pom.xml是根据设置组合起来运行的,每个Maven项目的pom.xml都有一个上级pom.xml,当前项目的pom.xml的设置信息会被合并到上级pom.xml中。上级pom.xml(相当于Maven默认的pom.xml)定义了大量的默认设置。如果用户希望看到Maven项目实际起作用的pom.xml(也就是上级pom.xml与当前pom.xml合并后的结果),可以运行如下命令

mvn help:effective-pom

第一次运行该命令时,Maven也会不断从网络上下载一些文件,然后就会看到一个庞大的完整的pom.xml中定义对应的元素来覆盖上级pom.xml中的默认设置

在这个庞大的、完整的pom.xml文件中可以看到如下片段

以上片段指定了编译该项目所使用的compiler插件,该插件默认执行compile目标

Maven的核心概念

从前面介绍的过程来看,只要将项目的源文件按照Maven要求的规范组织,并提供pom.xml文件,即pom.xml文件中只包含极少的信息,开发者也依然可以使用Maven来编译项目、运行程序,甚至可以测试用例、打包项目,这是因为Maven采用了“约定优化配置(Convention over Configuration,CoC)”的原则、根据此原则,Maven的主要约定有如下几条

  • 源代码应该位于${basedir}/src/main/java
  • 资源文件应该位于${basedir}/src/main/resources
  • 测试代码应该位于${basedir}/src/test
  • 编程生成的class文件应该位于${basedir}/target/classes
  • 项目应该会产生一个JAR文件,并将生成的JAR包放在${basedir}/target路径下

通过这种约定,就可以避免像Ant那样必须为每个子项目定义这些目录。此外,Maven对核心插件也使用了一组通用的约定,用来编译源代码、打包可分发的JAR、生成Web站点,以及许多其他过程
Maven的强大很大程度来自它的“约定”,Maven预定义了一个固定的生命周期,以及一组用于构建和装配软件的通用插件。如果开发者完全遵循这些约定,只需要将源代码放到正确的目录下,Maven即可处理剩下的事情
使用CoC的一个副作用是,用户可能会觉得它们被迫使用一种固定的流程和方法,甚至对某些约定感到反感。不过这一点无须担心,所有遵循CoC原则的技术通常都会提供一种机制允许用户进行配置。以Maven为例,项目源代码的位置可以被自定义,JAR文件的名字可以被自定义。。。换句话说,如果开发者不想遵循约定,Maven也会允许自定义默认值来改变约定,
下面简单介绍Maven的一些核心概念

一、Maven的生命周期(lifecycle)
依然使用前面介绍的mavenQs项目,进入pom.xml文件所在的路径下,然后运行如下命令

mvn install

以上命令只是告诉Maven运行install,但从实际的运行结果来看,Maven不仅运行了install,还在运行该插件之前运行了大量的插件。这就是Maven声明周期所导致的结果
生命周期是只Maven构建项目包含多个有序的阶段(phase),Maven可以支持许多不同的生命周期,最常用的生命周期是Maven默认的生命周期
Maven生命周期中的元素被称为phase(阶段),每个生命周期由多个阶段组成,各阶段总是按顺序依次执行,Maven默认的声明周期的开始阶段是验证项目的基本完整性,结束阶段是将该项目发布至远程仓库

实际上,mvn命令除了可以使用<plugin-prefix.>:<goal.>运行指定插件的目标,还可以使用如下命令格式

mvn <phase1> <phase2>...

以上命令告诉Maven执行Maven生命周期中的一个或多个阶段。当使用mvn命令告诉Maven执行生命周期的某个阶段时,Maven会自动从声明周期的第一个阶段开始执行,直至mvn命令指定的阶段

Maven包含三个基本的生命周期

  • clean 生命周期
  • default 生命周期
  • site 生命周期

clean生命周期用于在构建项目之前进行一些清理工作,该生命周期包含如下三个核心阶段

  • pre-clean:在构建之前与预清理
  • clean:执行清理
  • post-clean:最后清理

进入mavenQs项目中pom.xml所在的路径下,执行如下命令:

mvn post-clean

执行上面命令将会清理项目编译过程中生成的文件。执行该命令后,将可以看到mavenQs目录下只剩下src目录和pom.xml文件
默认的生命周期则包含了项目构建的核心部分。默认的生命周期包含如下核心阶段

  • compile:编译项目
  • test:单元测试
  • package:项目打包
  • install:安装到本地仓库
  • deploy:部署到远程仓库

mvn compile、mvn install命令所执行的都是上面列出的阶段。当使用Maven执行mvn install时,实际上将会先执行install阶段之前的阶段。下图显示了Maven默认的生命周期所包含的核心阶段的执行过程

上面列出的只是Maven默认的生命周期的核心阶段。实际上,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:复制测试的资源文件至测试目标目录

site 生命周期用于生成项目报告站点、发布站点。该声明周期包含如下核心阶段

  • pre-site:生成站点之前做验证
  • site:生成站点
  • post-site:生成站点之后做验证
  • site-deploy:发布站点到远程服务器

在pom.xml添加如下代码

<plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-site-plugin</artifactId><version>3.9.0</version></plugin></plugins></build>

进入mavenQs项目中pom.xml所在的路径下,执行如下命令:

mvn post-site

二、插件和目标(plugins and goal)
前面已经提到,Maven的强大来自它的插件,Maven的所有功能几乎都是由插件完成的,Maven插件甚至可以把Ant整合起来,使用Maven来运行Ant生成的文件
Maven提供了ant插件为Maven项目生成Ant生成文件,还提供了antrun插件来运行Ant生成文件

除了可以使用Maven官方、第三方提供的各种插件,开发者还可以开发自定义插件,通过自定义插件来完成任意。
每个插件又可以包含多个可执行的目标(goal),前面已经介绍过,使用mvn命令执行指定目标的格式如下

mvn <plugin-prefix>:<goal> -D<属性名>=<属性值>...

当使用mvn允许Maven生命周期的指定阶段是,各阶段所完成的工作其实也是由插件实现的,插件目标可以被绑定到生命周期的各阶段,每个阶段可能绑定了零个或者多个目标。随着Maven沿着生命周期的阶段移动,它会自动执行绑定在各特定阶段上的所有目标

Maven生命周期的各阶段也是一个抽象的概念,对于软件构建过程来说,默认的声明周期被划分为compile、test、install、deploy5个阶段,但这5个额就但分别运行什么插件、目标,其实是抽象的——这些阶段对于不同项目来说意味着不同的事情。例如,在某些项目中,package阶段对应于生成一个JAR包,这意味着“将一个项目打包成一个JAR包”;而在另一些项目中,package阶段可能对应于生成一个WAR包
下图示范了mavenQs项目的默认生命周期的各阶段,以及mavenQs项目绑定到各阶段上的插件和目标


开发者完全可以将任意插件绑定到指定的生命周期,例如,将上面的mavenQs赋值一份,并在其pom.xml文件的<project…/>根元素中增加如下元素

<build><plugins><plugin><!-- 下面三个元素也定义了exec插件的坐标 --><groupId>org.codehaus.mojo</groupId><artifactId>exec-maven-plugin</artifactId><version>1.3.1</version><executions><execution><!-- 指定绑定到compile阶段 --><phase>compile</phase><!-- ① --><!-- 指定运行exec插件的java目标 --><goals><goal><goal>java</goal><!-- ② --></goal></goals><!-- configuration元素用于为插件的目标配置参数 --><configuration><!-- 下面的元素配置mainClass参数的值为org.fkjava.mavenqs.App --><mainClass>org.fkjava.mavenqs.App</mainClass></configuration></execution></executions></plugin></plugins>
</build>

上面配置文件中的代码可以唯一标识某个插件(被称为坐标)。①号配置代码指定将该插件、目标绑定到compile阶段;②号配置代码指定运行exec插件的java目标,通过上面这段配置,即可exec插件的Java目标绑定到compile阶段。
进入该项目中pom.xml所在的路径下,然后执行如下命令

mvn compile

执行这条命令,不仅可以看到Maven执行compile插件的compile目标来编译项目,还可以看到Maven执行exec插件的java目标来运行项目的org.fkjava.mavenqs.App类

三、Maven坐标(coordinate)
POM需要为项目提供一个唯一标识,这个标识就被称为Maven坐标,Maven坐标由如下4个元素组成

  • groupId:该项目的开发者的标识名(通常使用域名)
  • artifactId:指定项目名
  • packaging:指定项目打包的类型
  • version:指定项目的版本

例如,mavenQs项目的pom.xml文件中的如下配置定义了该项目的Maven坐标

<groupId>org.fkjava</groupId>
<artifactId>mavenQs</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>

Maven坐标可用于精准定位一个项目。例如,mavenQs项目中还有如下配置片段

<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope>
</dependency>

以上配置片段定义了一个依赖关系,这段配置表明该项目依赖junit3.8.1,groupId+artifactId+version就是junit项目的坐标
Maven坐标通常用英文冒号作为分隔符来书写,即以 groupId:artifaactId:packaging:version 格式书写。例如,mavenQs项目的坐标可以书写成 org:fkjava:mavenQs:jar:1.0-SNAPSHOT,而mavenQs项目所依赖的项目的坐标则可写成junit:junit:jar:3.8.1

四、Maven资源库(repository)
第一次运行Maven时,Maven会自动从远程资源库下载许多命令,包括各种Maven插件,以及项目依赖的库,实际上,初始的Maven工具非常小,这是因为Maven工具本身的功能非常有限,几乎所有的功能都是由Maven插件完成的
Maven资源库用于保存Maven插件,以及各种第三方框架。简单来说,Maven用到的插件、项目所依赖的JAR包,都会保存在资源中
Maven资源库可分为如下三种

  • 本地资源库:Maven用到的所有插件、第三方框架都会被下载到本地资源库中。只有当在本地资源库中找不到时才采取从远程下载。开发者可以通过Maven安装目录下的conf\settings.xml文件,或者用户Home目录下的.m2\settings.xml文件中的<localRepository…/>元素进行设置
  • 远程资源库:远程资源库通常由Maven官方维护,中央资源库包含了各种公开的Maven插件、第三方项目。几乎所有的开源项目都会选择中央资源库发布框架。中央资源库的地址为:链接1

当Maven需要使用某个插件或JAR包时,Maven的搜索顺序为:本地资源库——>远程资源库->中央资源库。当Maven从中央资源库下载了某个插件或JAR包时,Maven都会自动在本地资源库中保存它们,只有当Maven第一次使用某个插件或JAR包时,才需要通过网络下载

依赖管理

下面使用Maven开发一个简单的SpringMVC项目,本章主要介绍如何使用Maven构建Web项目,并为Web项目添加第三方框架
首先使用如下命令创建一个Web项目:

mvn archetype:generate -DgroupId=org.crazyit -DartifactId=smqs -Dpackage=org.crazyit.smqs -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false

项目结构

smqssrcmainresourceswebappWEB-INFweb.xml

其中,WEB-INF路径和web.xml文件就是Web应用必须的文件夹和配置文件
接下来打开smqs目录下的pom.xml文件,在该文件的<project…/>根元素内、坐标信息之后(<version…/>元素的后面)添加如下配置内容(删除原来的<name…/>和<url…/>元素)

<version>3.8.1</version><name>smqs</name><url>http://www.crazyit.org</url><!-- 定义该项目所使用的License --><licenses><license><name>Apache 2</name><url>http://www.apache.org/licenses/LICENSE-2.0.txt</url><distribution>repo</distribution><comments>A business-friendly OSS license</comments></license></licenses><!-- 声明该项目所属的组织 --><organization><name>CrazyIt</name><url>http://www.crazyit.org</url></organization><!-- 声明项目开发者 --><developers><developer><id>kongyeeku</id><name>kongyeeku</name><email>kongyeeku@gmai.com</email><url>http://www.crazyit.org</url><organization>CrazyIt</organization><!-- 声明开发者的角色 --><roles><role>developer</role></roles><timezone>+8</timezone></developer></developers><!-- 声明对项目有贡献的人 --><contributors><contributor><name>fkjava</name><email>fkjava@hotmail.com</email><url>http://www.fkjava.org</url><organization>疯狂软件教育中心</organization><roles><role>developer</role></roles></contributor></contributors>

上面的配置内容用于定制该项目的配置信息,这段配置信息指定了该项目遵循的License,并指定了该项目所属的组织、项目的开发者,以及对项目有贡献的人。这些信息都用于定制该Maven项目,这些信息主要起描述的作用
为该项目添加Spring MVC的支持,可以在pom.xml中的<dependencies…/>元素内增加<dependency…/>元素——每一个<dependency…/>元素定义一个依赖框架或依赖类库

<dependency…/>可接受如下子元素

  • <groupId…/>:指定依赖框架或依赖类库所属的组织ID
  • <artifactId…/>:指定依赖库UAN国家或依赖类库的项目名
  • <version…/>:指定依赖框架或依赖类库的版本号
  • <scope…/>:指定依赖库起作用的范围。该子元素可接收compile、provided、test、system、runtime、import等值
  • <type…/>:指定依赖框架或依赖类库的类型,该元素的默认值是jar。另外,还可以指定war、ejb-client、test-jar等值
  • <optional…/>:指定JDK版本号,如jdk14或jdk15等,指定被依赖的JAR包是在JDK哪个版本下编译的
  • <exclusions…/>:用于排除依赖
    <scope…/>元素用于指定依赖库起作用的范围。该元素可指定如下值
  • compile:默认的范围,编译、测试、打包时需要
  • provided:表示容器会在运行时提供
  • runtime:表示编译时不需要,但测试和运行时需要,最终打包时包含进来
  • test:只用于测试阶段
  • system:与provided类似,但要求该JAR是系统自带的
  • import:继承父POM文件中用dependencyManagement配置的依赖,import范围只能在dependencyManagement元素中使用(为了解决多继承)

关于Maven的依赖配置,需要说明的是,Maven依赖管理具有传递性,比如配置文件设置了项目依赖a.jar,而a.jar又依赖b.jar,那么该项目无须显式声明依赖b.jar,Maven会自动管理这种依赖的传递
由于Maven的依赖管理具有传递性,因此有时需要用<exclusions…/>子元素排除指定的依赖。例如以下配置

 <dependency><groupId>javax.activation</groupId><artifactId>mail</artifactId><type>jar</type><exclusions><exclusion><artifactId>activation</artifactId><groupId>javax.activation</groupId></exclusion></exclusions></dependency>

上面配置指定该项目依赖mail.jar。由于Maven的依赖具有传递性,因此Maven会自动将mail.jar依赖的activation.jar也包含进来。为了将activation.jar排除出去,即可进行如上配置文件中所示

<!-- 配置该项目依赖SpringMVC --><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><!-- 此处指定依赖的Spring MVC版本 --><version>5.2.0.RELEASE</version></dependency>

进入smqs项目的pom.xml文件所在的路径下,执行如下命令

mvn package

由于此时Maven项目中的文件组织形式符合Web应用的格式,而且pom.xml文件中<packaging…/>元素的值为war,因此执行上面的命令将会把该项目打包成WAR包。
执行上面的命令,同样也会从网络上下载插件和文件
执行结束后可以看到一个smqs.war
可以看出,使用Maven之后,开发者只需要在pom.xml文件中配置该项目依赖SpringMVC,剩下的事情就交给Maven搞定,开发者无须关心Spring MVC的官网,无须关心从哪里下载Spring MVC的JAR包,无须关心Spring MVC框架哪些第三方JAR包,所有依赖关系都交给Maven处理即可。依赖管理,可以说是Maven最大的魅力之一

POM文件的元素

Maven使用pom.xml文件来描述项目对象模型,因此pom.xml文件可以包含大量元素用于描述该项目。前面已经通过示例介绍了pom.xml文件中大量常用的元素。实际上,pom.xml文件还可包含如下元素

  • <properties…/>:该元素用于定义全局属性
  • <dependencies…/>:该元素用于定义依赖关系。该元素可以包含0~N个<dependency…/>子元素,每个<dependency…/>子元素定义一个依赖关系
  • <dependencyManagement…/>:该元素用于定义依赖管理
  • <build…/>:该元素用于定义构建信息
  • <reporting…/>:该元素用于定义站点报告的相关信息
  • <licenses…/>:该元素用于定义该项目的License信息
  • <organization…/>:该元素指定该项目所属的组织信息
  • <developers…/>:该元素用于配置该项目的开发者信息
  • <contributors…/>:该元素用于配置该项目的贡献者信息
  • <issueManagement…/>:该元素用于定义该项目的bug跟踪系统
  • <mailingLists…/>:该元素用于定义该项目的邮件列表
  • <scm…/>:该元素指定该项目源代码管理工具,如CVS、SVN等
  • <repositories…/>:该元素用于定义远程资源库的位置
  • <pluginRepositorie…/>:该元素用于定义插件资源库的位置
  • <distributionManagement…/>:该元素用于部署管理
  • <profiles…/>:该元素指定根据环境变量调整构建配置

关于pom.xml文件的详细语句约束可参考 http://maven.apache.org.maven-v4_0_0.xsd文件

使用Git进行软件配置管理(SCM)

SVN是一个广泛使用的版本控制系统,但SVN的主要弱点在于:它必须时刻连接着服务器,一旦断开网络,SVN就无法正常工作
由于Linus(Linux系统的创始人)对SVN非常“不感冒”(因为SVN必须联网才能使用),因此Linus在2005年着手开发了一个新的分布式版本控制系统:Git。不就,很多人就感受到了Git的魅力,纷纷转投Git门下
2008年,GitHub网站上线了,它为开源项目免费提供Git存储,无数开源项目开始迁移至GitHub,包括jQuery和MyBatis等
SVN与Git相比,二者的本质区别在于:SVN是集中式的版本控制系统,而Git是分布式的版本控制系统。
先简单回顾集中式版本控制系统(以SVN为例),SVN的版本库是集中存放在中央服务器上的,每个开发者工作时,都必须先从中央服务器同步最新的代码(下载最新的版本),然后开始修改,修改完了再提交给服务器
下面介绍分布式(以Git为例)。对于Git而言,每个开发者的本地磁盘上都存放着一份完整的版本库,因此开发者工作时无须互联网,直接使用本地版本库即可。只有需要多人相互协作时,才通过“中央服务器”进行管理

简单来说,与SVN相比,Git的改变相当于让每个开发者都在本地“缓存”了一份完整的资源库,因此开发者对自己开发的项目文件执行添加、删除、返回之前版本时不需要通过服务器来完成

下载和安装Git、TortoiseGit

Git是Linus开发的,因此起初Git自然是运行在Linux平台上的。后来Git也为Windows、Mac OS X等平台提供了响应的版本。本书以Windows7为例来介绍Git的安装和使用
快速下载链接

64-bit Git for Windows Setup : https://npm.taobao.org/mirrors/git-for-windows/v2.26.2.windows.1/Git-2.26.2-64-bit.exe


上面的提示信息表明Git安装成功
如果用户非常喜欢命令行工具,则可以直接在命令行窗口使用git命令来进行软件配置管理。但是,对于大部分读者而言,直接使用git命令会比较费劲,因此本书还会介绍一个非常好用的工具:TortoiseGit

https://download.tortoisegit.org/tgit/2.8.0.0/

在快捷菜单中集成的TortoiseGit工具菜单

TortoiseGit已经被整合到Windows资源管理器中,因此使用TortoiseGit非常简单(注意上面是没有勾选Git的自带GUI工具),在Windows资源管理器的任何文件、文件夹或者空白处单击鼠标右键,即可在弹出的快捷菜单中看到TortoiseGit对应的工具菜单
TortoiseGit还提供了一个语言包,可以将该软件汉化成简体中文界面,但考虑到软件开发者的工作环境(大部分人用英文,甚至于国外开发者协作开发),因此推荐保持英文界面

创建本地资源库

创建本地资源库非常简单:选择需要版本管理的工作目录,然后在该工作目录下创建资源库即可。具体操作按以下步骤执行即可。

一、选择需要版本管理的工作目录,比如此处打算对D:、gitJava目录进行版本管理。通过资源管理器进入该目录,在空白处右键空白,弹出下图的TortoiseGit工具菜单,单击“Git Create repository here…”菜单项

二、该对话框中有一个“Make it Bare” 复选框,如果勾选该复选框,则意味着将该目录初始化为“纯版本库”(开发者不能在该目录下干活),因此此处不要勾选该复选框。单击“OK”即可成功创建本地资源库
以上步骤相当于在D:\gitJava目录下执行git init命令,该命令同样用于在指定目录下创建本地资源库。执行git init --bare命令,则相当于勾选了“Make it Bare”复选框

创建完成后,Git将会在D:\gitJava目录下新建一个隐藏的.git文件夹,该文件夹就是Git的本地版本库,它负责管理D:\gitJava目录下的添加、删除、修改、分支等操作
创建本地资源库之后,接下来可对该资源库进行一些初步配置
在资源库目录(D:\gitJava)的空白处单击鼠标右键,系统弹出如下菜单,单击“TortoiseGit” -> “Settings”菜单项,系统弹出如下参数设置对话框

在上图所示的参数对话框中提供了常用的设置分类

  • General:该分类主要用于设置界面语言、字体、字体大小、字体颜色等通用信息
  • Git:该分类主要用于设置Git本身的相关信息
  • Diff Viewer:该分类用于设置Diff文件比较器的比较界面
  • TortoiseGitUDiff:该分类用于设置TortoiseGitUDiff文件比较器的比较界面
    此处主要介绍Git相关设置,因此单击上图所示的“Git”节点,并选中上方的“Global”单按钮,即可看到下面的对话框

    在上图所示对话框输入Name、E-mail、Signing key信息,这些信息将作为用户提供代码的标识(就是告诉Git谁在提供代码)。后面会看到,每次提交代码时,Git都会记录这些用户信息。
    通过上图所示对话框设置的是Git的全局信息,全局信息以明文保存在用户HOME目录(Windows的用户HOME目录为C:\Users<用户名>)下的.git-credentials文件中,开发者也通过上图所示对话框下方的“Edit global.gitconfig”按钮直接编辑git-credentials文件,这种方式更直接——但对于初级用户来说,容易产生错误

    选中对话框所示的“Local”单按钮,表明为当前项目设置自Git相关信息,此时可以重新设置Name、E-mail、Signing key等信息。局部信息以明文保存在.git目录下的config文件中,开发者也可以通过对话框下方的“Edit local.git/config”按钮直接编辑config文件,这种方式更直接——但对于初级用户来说,容易产生错误
    当局部变量的全局信息不一致时,局部信息取胜(就进原则)。如果“Global”选项和“Local”选项下输入的用户信息不一致,则选中“Effective”单选钮(该选项用于显示实际生效的用户信息),即可看到实际生效的是“Local”选项下输入的用户信息

添加文件和文件夹

Git添加文件和文件夹也很简单,先把文件和文件夹添加到Git系统管理之下,然后提交修改即可
例如,在D:\gitJava目录下添加一个a.jsp文件,该文件内容可以随便写,并在该目录下添加一个WEB-INF文件夹,在该文件夹下添加web.xml文件。接下来,打算将a.jsp文件和WEB-INF文件夹添加到Git管理之下,步骤如下

一、同时选中a.jsp文件和WEB-INF文件夹,单击鼠标右键,在弹出的快捷菜单中选择“TortoiseGit”->“Add”菜单项,系统弹出如下对话框

二、点击“OK”按钮,该文件和文件夹就被添加到Git管理之下了。添加完成后,TortoiseGit显示如下图

添加操作相当于之下git add命令,因此上面步骤相当于在D:\GitJava目录下执行git add a.jsp WEB-INF命令

提交修改

与SVN相似,添加文件和文件夹之后,还需要执行提交操作才能真正的将修改提交到版本库中。实际上,Git的操作总是按“操作->提交”模式执行的,此处的操作包括添加文件、修改、删除等。
创建本地资源库之后,Git在资源库下创建一个.git文件夹,该文件夹被称为Git版本库(用于记录各文件的修改历史)。Git版本中存了很多东西,其中包括名为stage(index)的暂存区
开发者对文件所做的各种操作(比如添加、删除、修改等),都只是保存在stage暂存区中,只有等到执行提交时才会将暂存区中的修改批量提交到指定分支。在创建Git本地资源库时,Git会自动创建唯一的master主分支

执行提交操作请按照如下步骤进行

一、在D:\gitJava目录的空白处单击鼠标右键,在弹出的快捷菜单中单击“Git Commit”->“master…”菜单项,系统显示如下所示的提交确定对话框


二、在上图所示的提交确定对话框中,可以为本次提交输入说明信息,也可以通过勾选“new branch”复选框提交给新的分支(默认提交给master主分支,这是Git默认创建的主分支),下面则列出了本次提交所产生的修改。按图所示方式输入说明信息后,单击“Commit”按钮即可开始提交,TortoiseGit显示下图提交进度对话框

当提交进度条完成时,表明Git提交完成,可单击“Close”按钮关闭该对话框
提交操作相当于执行git commit命令,因此上面步骤相当于在D:\gitJava目录下执行git commit命令

此外,开发者可以使用自己喜欢的工具(文本编辑器或IDE工具)对工作区的代码进行开发,Git会自动将这些修改放入stage暂存区中
当项目开发到某个步骤,需要将stage暂存区中的修改提交给指定分支时,提交修改操作也按刚刚介绍的步骤进行。
此处可以尝试对a.jsp进行一些修改,然后通过git commit命令或TortoiseGit菜单中的“Git Commit” -> “master…”菜单项目执行提交

查看文件或文件夹的版本变更

通过TortoiseGit也可查看文件或文件夹的版本变更历史,并比较任意两个版本之间的差异
查看文件或文件夹的版本变更历史非常简单,在D:\gitJava目录的空白处点击鼠标右键,在弹出的快捷菜单中点击“TortoiseGit” -> “Show log”菜单项,即可看到版本变化

从上图可以看出,Git会集中管理整个项目的版本变更。我们在窗口上选中某个提交信息,在窗口中间可以看到本次提交的唯一标识(以SHA-1名表示)和说明信息;在窗口下方可以看到本次提交涉及的文件。比如上图所示,选中了第一次提交的添加操作没在窗口中可以看到本次提交操作添加了WEB-INF/web.xml和a.jsp两个文件
查看版本变更历史也可以使用git log命令,该命令将以文字界面的方式显示资源库的版本变更历史,文件界面就不如图界面直观了

TortoiseGit的很多“撤回操作”都可通过上图所示的窗口来完成。比如在a.jsp文件上单击鼠标右键,即可弹出下图所示的菜单

其中前三个菜单项主要用于对比该版本的文件与其他版本(查看具体做过哪些修改,修改部分会以高亮显示);中间部分的菜单项主要用于对当前版本执行某种操作,比如推回该版本,可单击“Revert to this revision”菜单项;将版本文件另存,则可单击“Save revision to…”菜单项

删除文件或文件夹

删除文件或文件夹操作同样按“删除->提交”模式执行。通过TortoiseGit删除指定的文件或文件夹非常简单,按如下步骤操作即可

一、通过资源管理器删除指定文件或文件夹
也可以通过git rm<文件或文件夹>命令来删除文件或文件夹

二、在资源库的空白处单击鼠标右键,在弹出的快捷菜单中单击“TortoiseGit” -> “Commit”菜单项,提交修改即可
删除文件或文件夹之后,还必须执行提交操作;否则,在本地所做的删除操作不会提交到服务器。提交修改同样可使用git commit命令来完成

从以前版本重新开始

使用版本管理工具最大的好处在于:开发者可以随时返回以前的某个版本。如果在开发过程中吧某个文件改坏了,希望重新找回该文件以前的某个版本,或者向从前面的某个阶段重新开始,TortoiseGit都提供了方便的操作允许“重返”(重设,Reset操作)以前某个版本
如果要将整个资源库重返以前的版本,则按如下步骤进行

一、按前面介绍的方式查看版本库的历史变更
二、右键弹出菜单,点击:“Reset master to this”菜单项
三、该对话框设置重设的相关选项

  • Soft:软重设,只将指定分支重设到指定版本,不改变当前工作空间和stage暂存区
  • Mixed:混合,将指定分支重设到指定版本,将stage暂存区也重设到指定版本,但不改变工作空间
  • Hard:将指定分支、stage暂存区、工作空间全部重设到指定版本

由于前一步删除了WEB-INF文件夹和a.jsp文件,如果希望能将整个工作空间(就是D:\gitJava目录)都恢复到删除之前的状态,那么应该选中“Hard”重设类型

四、根据需要选择重设类型,然后单击“OK”按钮,整个项目即可恢复到指定版本。此时将会看到工作空间下的WEB-INF文件夹爱和a.jsp文件又回来了。

重设指定版本也可使用git reset<版本标识>命令来完成,其中“版本标识”就是前面所看到的每次提交的SHA-1名

如果只想将单个文件恢复到指定版本,则按如下步骤进行

一、按前面介绍的方式查看版本库的变更历史
二、鼠标右键,选择“Revert to this revision”菜单项,该文件就会恢复到指定版本的状态
三、恢复单个文件后,实际上相当于对文件进行了修改,如果希望将这种修改保存到版本库中,则同样需要执行提交操作

克隆项目

克隆(Clone)项目就是将所选资源库当前分支的所有内容复制到新的工作空间下。如果当前分支不是master主分支,而是其他分支,那么克隆操作自然就是复制其他分支的内容
克隆项目按如下步骤进行即可

一、进入打算克隆的项目的文件夹爱,在该文件夹空白处右键,在弹出的快捷菜单中点击“Git Clone…”菜单项

二、在上图所示对话框的URL中填写克隆项目的URL,如果是本地项目,则直接填写该项目所在的路径;如果是远程项目,则填写远程项目的URL。“DIRECTORY”则用于指定将项目克隆到本地的哪个目录下。如果项目中可能包含有大文件,则勾选“LFS”复选框。设置完成后点击“OK”按钮
TortoiseGit将会显示克隆过程的进度,克隆完成后,在D:\newGit\目录下将会多个一个文件夹,这就是刚刚克隆出的项目
克隆项目可通过git.exe被克隆项目的URL,本地存储路径命令来完成。克隆本地项目与克隆远程项目其实差不多,只是填写被克隆项目的URL有所不同而已

创建分支

有些时候不想继续沿着开发主线开发,而是希望试探性地添加一些新功能,这时候就需要在原来的开发主线上创建一个分支(Branch),进而在分支上进行开发,避免损坏原有的稳定版本。
创建分支请按如下步骤进行

一、在项目所在工作空间的空白处单击鼠标右键,在弹出的快捷菜单单击“TortoiseGit”->“Create Branch…”菜单项,系统弹出如下所示对话框


二、在图所示对话框中输入新分支的名字,并指定该分支基于哪个版本来创建,然后单击“OK”按钮,创建分支成功
创建分支之后,接下来就可以在新分支上进行开发了,从而避免损坏原有的文件版本

沿着分支开发

为了沿着分支开发,要求先切换到分支所在的版本(可通过勾选上图对话框中的“Switch to new branch”复选框,在创建分支时切换到指定分支)
为了切换到指定分支继续开发,可按如下步骤进行

一、在工作空间的空白处单击鼠标右键,在弹出的快捷菜单中单击“TortoiseGit”->“Switch/Checkout…”菜单项,系统弹出下图所示对话框


二、在上图所示对话框中选择要切换的分支,然后点击“OK”按钮,当前文件就会被切换到指定分支,接下来对该文件所做的修改都将沿着该分支进行,
切换到指定分支,也可以通过git.exe checkout<分支名>命令来完成

例如,切换到newBranch分支之后继续对a.jsp进行修改,修改完成后,将所做的修改提交到版本库,再次查看该项目的版本变更历史
可以看出此时所做的修改表示在master主分支上进行的,而是在newBranch分支上进行的
如果开发者沿着分着开发了一段时间之后,想继续维护master分支上的开发,则还可以切换回master主分支继续开发。从新分支切换回master主分支与切换到其他分支无任何区别,故此出不再赘述。

合并分支

当前项目沿着分支试探性开发新功能达到一定的稳定状态之后,还可以将开发分支和master主分支进行合并,从而将分支中的新功能添加到master主分支中
为了实现合并,可以按如下步骤进行

一、在工作空间的空白处点击鼠标右键,在弹出的快捷菜单中点击“TortoiseGit” -> “Merge…”菜单项,系统弹出如下对话框

二、在上图所示对话框的上方设置要合并的目标分支,在下方填写合并的说明信息,然后单击“OK”按钮,TortoiseGit开始执行合并
执行合并可通过git.exe merge -m合并信息,<分支名>命令来完成。在执行合并之前,可以先通过TortoiseGit提供的文件对比工具查看两个分支的文件之间存在的差异

使用Eclipse作为Git客户端

最新的Eclipse IDE for Java EE Develpopers(2019-9版)默认已经集成了Git客户端,因此可使用Eclipse作为Git客户端

如果想要使用Eclipse导入Git项目,则可通过如下步骤进行

一、单击Eclipse的“File”->“Import”菜单,打开Eclipse的Import对话框,如下图所示

二、选择“Git”->“File”->“Import”菜单,打开Eclipse的Import对话框,如下所示

三、在上图所示对话框中显示了“Existing local repository”和“Clone URI”两个节点,它们分别代表克隆本地资源库和克隆远程资源库。此次打算克隆前面的D:\gitJava资源库(本地资源库),因此选择第一个节点然后点击“Next”按钮

四、Eclipse显示选择Git资源库的对话框。在初始状态下,Eclipse不会显示任何Git资源库,这是因为还没有为Eclipse配置Git资源库。单击该对话框右边的“Add…”按钮,Eclipse显示如下的对话框

五、填写本地Git项目的路径后,单击“Finish”按钮,返回选择Git资源库的对话框,此时将看到Eclipse列出了刚刚添加的Git资源库。选择该Git库,然后单击“Next”按钮,Eclipse显示如下所示对话框

六、在上图所示的对话框中,第一个选项表示导入一个已有的Eclipse项目;第二个选项表示启用新项目向导来执行导入;第三个选项表示作为一个通用项目导入。此处选择第三个“Import as general project”,然后单击“Finish”按钮完成导入
在Eclipse中导入Git项目之后,在该项目上单击鼠标右键,在弹出的快捷菜单中选择:“Team”,即可看到如下所示的Git管理的菜单项

从上图可以看出,Git最常用的添加(Add)、提交(Commit)、重返以前版本(Reset)等都非常直观,此处不再赘述
此外,对于一个已有的Eclipse项目(非Git项目),也可在该项目上单击鼠标右键,在弹出的快捷菜单中单击“Team”->“Sharee Project”菜单项,选择通过Git将该项目放入Git资源库中。

配置远程中央资源库

前面介绍的Git操作都是直接通过本地资源库进行的(无须连接远程资源库),这就是Git分布式的典型特点。但是当多个开发者需要对项目进行协作开发时,最后还是需要连接远程中央资源库的,所有开发者都需要通过远程中央资源库进行项目交换
GitHub就是免费的远程中央服务器,如果是个人、小团队的开源项目,则可以直接使用GitHub作为中央服务器进行托管。但如果是公司开发的项目,则通常不会选择GitHub作为中央服务器,往往会在企业内部搭建自己的中央服务器
本节将会介绍使用GitStack来配置远程中央资源库,GitStack是Windows平台上的远程中央资源库,具有简单、易用的特征

在企业实际开发中大多会采用Linux平台来配置Git中央资源库,在Linux上配置中央资源库其实更方便。在Windows平台上配置Git中央服务器,除使用GitStack之外,也可使用Gitblit GO

下载和安装GitStack

安装注意:

  • 不要将GitStack安装在带空格的路径
  • 即使机器上一级安装了Git,GitStack也依然要使用它自带的Git,因此推荐安装GitStack时一并安装Git

GitStack安装完成后,启动浏览器,在地址栏输入

http://localhost/gitstack/

如果访问远程主机,则将localhost换成主机IP地址,即可看到GitStack的登入界面,GitStack默认内置了一个admin账户,密码也是admin

输入账号和密码 admin即可登入GitStack管理界面

上图可以看出,GitStack的关联主要分为三类

  • Repositoies:用于管理Git资源库,包括创建资源库、删除资源库、管理资源库权限等

  • Users&Groups:主要用于管理用户和组,包括添加、删除和组,以及管理用户和组的权限

  • Settings:主要是GitStack的一些通常设置。可通过Settings下的Genernal设置来修改admin账户的密码、修改服务器端口、修改GitStack管理的资源库的存储路径。通常,只需要修改admin账户的密码即可,其他设置暂时无须改变


    上图界面中列出了刚刚创建的firstDemo.git资源库,还提供了克隆该资源库的命令:git clone http://localhost/firstDemo.git 在该资源库条目的右边支持三个操作

  • 查看(放大镜图标):通过浏览器查看资源库的内容

  • 管理用户权限(人像图标):为该资源库管理用户以及对应的权限

  • 删除(删除图标):删除该资源库

资源库创建完成后,可以在C:\GitStack\repositories目录下(假设GitStack安装在C盘根目录下)看到多了一个firstDemo.git文件夹,该文件夹就是改革创建的纯资源库

接下来,我们为GitStack新增一个用户,单击GitStack管理界面左边的“Users&Groups”类下的Users标签,系统显示如下所示的用户管理界面


在Username和Password框中分别输入用户名、密码后,单击“Greate”按钮,即可创建一个新用户
创建完用户之后,返回首页管理界面,单击资源库右边的管理用户权限图表


从上图可以看出,此时该资源库下没有任何用户,也没有任何用户组。单击该管理界面上的“Add user”按钮,即可为该资源库添加用户(此处添加的用户需要先通过“Users&Groups”分类下的Users标签进行配置)。用户添加完成后,可以看到下图的界面

上图中可以看出,fkjava用户对该资源库具有Read、Write权限(勾选代表有权限)这意味着fkjava可以读取资源库,也可以向资源库中提交代码。everyone(任何人)用户则只有Read权限,因此其只能读取资源库

推送项目

推送(Push)项目指的是将本地资源库的更新推送给中央资源库。

在默认情况下,获取项目将取回所有分支的更新。如果想取回中央资源库的所有分支,则执行如下格式的命令

git fetch <远程主机URL>

如果指向取回特定分支的更新,则可以指定分支名,执行如下格式的命令

git fetch <远程主机URL><分支名>

拉去项目用于返回远程中央资源库的某个分支的更新,然后与本地的指定分支合并。该命令的完整格式如下:

git pull <远程主机URL><远程分支名>:<本地分支名>

如果希望将远程中央资源库的某个分支合并到本地资源库的当前分支上,则可省略本地分支名,即执行如下格式的命令即可

git pull <远程主机URL> <远程分支名>

轻量级JavaWeb开发环境部署相关推荐

  1. JavaWeb开发环境配置

    JavaWeb开发环境配置(win7_64bit) 目录 1.概述 2.JavaWeb学习路线 3.JavaWeb常用开发环境搭建 4.注意事项 >>看不清的图片可在新标签打开查看大图 1 ...

  2. 阿里云javaweb开发环境搭建(一)(jdk+Tomcat)

    因项目需要,新买了阿里云,准备把之前开发的项目打包部署在阿里云上. 我的阿里云镜像用的是Centos7,先是要搭建javaweb开发环境,这里把踩过的坑写一下,直接上干货: 一.使用工具 Xshell ...

  3. JavaWeb开发环境搭建

                                         JavaWeb开发环境搭建 我们都知道,学习java首先要进行java运行环境的搭建,也就是JDK的安装,许多有着java学习 ...

  4. 好文分享:Javaweb开发环境搭建常用工具类型

    随着互联网的不断发展,无论是前端开发还是后端开发都越发垂直细分化,而今天我们就通过案例分析来了解一下,Javaweb开发环境搭建常用工具类型. 一:Web相关概念 Web程序也就是一般所说的网站,由服 ...

  5. vscode 配置javaweb开发环境,超级简单,纯新手带图,学会后真香.宇宙无敌第一编辑器vscode

    vscode配置javaweb开发环境 1.vscode配置java环境 2.下载tomcat 在官网中下载https://tomcat.apache.org/download-10.cgi 3.下载 ...

  6. 【Smobiler企业APP开发之一】开发环境部署

    最近研究了下Smobiler-.net移动开发,对于做企业APP开发Smobiler还是够用的,况且是完全使用C#进行编程,对于使用C#进行程序设计的程序员来说还是很容易上手的. 本章节主要介绍Smo ...

  7. java alsa 编程_搭建JavaWeb开发环境

    更好的阅读体验欢迎访问博客搭建JavaWeb开发环境 前言 在服务器上搭建javaweb开发环境,特此记录 一.安装JDK 查看默认JDK java -version rpm -qa|grep jav ...

  8. 基于IDEA的JavaWeb开发环境搭建

    基于IDEA的JavaWeb开发环境搭建 基于IDEA的JavaWeb开发环境搭建 jdk下载安装配置环境变量 下载 安装 配置环境变量 下载安装激活使用IntelliJ IDEA 下载 安装 激活 ...

  9. Linux——Django 开发环境部署(二)python版本控制器pyenv

    python版本控制器pyenv 之前的 那篇是说明了django环境的site package完全独立出来了,但是使用的python解释器还是系统的,为了继续独立出来,甚至是达到ruby的rvm的自 ...

最新文章

  1. python中Scipy模块求取积分
  2. linux的简单面试题,收集的一些简单的UNIX/Linux面试题
  3. python3 time模块与datetime模块
  4. acl审计软件_什么是IT审计员?风险评估的重要角色
  5. c++11特性move和forward区别
  6. maven离线安装jar包
  7. 亚马逊出的平板电脑_亚马逊发布Fire HD 8新系列平板电脑,90美元起
  8. cad直线和圆弧倒角不相切_建议收藏:史上最全CAD快捷键大全
  9. python离线安装whl文件.
  10. python3 调用http接口例子
  11. Bootstrap学习笔记02
  12. 浅谈智能搜索和对话式OS
  13. 南阳oj STL分类练习
  14. 【T+】根据畅捷通T+的账套备份文件判断软件版本以及数据库
  15. 极路由 刷linux,极路由极壹HC6361刷OpenWrt固件教程
  16. source 命令解释
  17. 通俗易懂:非线性与线性的区别是什么?
  18. 百度智能云开物凭什么在“双跨”新增名单中排名榜首?
  19. 通过docker搭建企业内部文档共享平台-MM-WiKi
  20. 更改bootstrap工具提示-tooltip

热门文章

  1. 阿里面试回来,想和Java程序员谈一谈
  2. 中安威士数据库审计之绑定变量审计
  3. 工控软件及计算机监控系统设计
  4. mysql workbench 特性_MySQL Workbench的使用方法(图文)
  5. 三步搞定专利-专利写作技巧以及流程
  6. PMP入门知识你知道吗?
  7. 深入浅出C语言——C语言简介
  8. SA装系统之U盘量产winpe来维护windows系统。
  9. 数字服务器及tms系统,TMS影院管理系统坐阵影院市场
  10. 微信小程序返回上个页面并携带参数