本文章是结合轻量级JavaWeb企业级应用实战所写的学习总结记录文章,开发环境部署文章仍然使用的是我的旧文章习惯,在下一章我会使用新的文章书写习惯来更清晰和简便的记录
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目录解析
注意:此处JAVA_HOME环境变量应该指向JDK的安装路径,不是JRE安装路径。在JDK安装路径下应该包含bin目录,在该目录下应该有javac.exe、javadoc.exe等程序
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>listingsparam-name>
<param-value>trueparam-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>
<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-guirole-name>
auth-constraint>
security-constraint>
<security-constraint>
<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-scriptrole-name>
auth-constraint>
security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>JMX Proxy interfaceweb-resource-name>
<url-pattern>/jmxproxy/*url-pattern>
web-resource-collection>
<auth-constraint>
<role-name>manager-jmxrole-name>
auth-constraint>
security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>Status interfaceweb-resource-name>
<url-pattern>/status/*url-pattern>
web-resource-collection>
<auth-constraint>
<role-name>manager-guirole-name>
<role-name>manager-scriptrole-name>
<role-name>manager-jmxrole-name>
<role-name>manager-statusrole-name>
auth-constraint>
security-constraint>
<login-config>
<auth-method>BASICauth-method>
<realm-name>Tomcat Manager Applicationrealm-name>
login-config>
通过上面的配置文件可以知道,登录Manager App控制台可能需要不同的manager角色。对于普通开发者来说,通常需要访问匹配/html/*、/status/*的资源,因此为该用户分配一个manager-gui角色即可
Tomcai默认采用文件安全域,急用文件存放用户名和密码,Tomcat的用户由conf路径下的tomcat-users.xml文件控制。打开该文件,发现有如下内容:
<tomcat-users>
tomcat-users>
将其内容修改如下:
<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文件)
在Tomcat中部署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的系统文件,因此不建议采用
从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">
<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初始化Context
Context 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();
//获取Statement
Statment stmt = conn.createStatement();
//执行查询,返回ResultSet对象
ResultSet rs = stmt.executeQuery("select*from news_inf");
while(rs.next()){
out.println(rs.getString(1)
+"\t"+rs.getString(2)+"
");
}
上面的DataSource代码实现了JNDI查找数据源对象,一旦获取了查找数据源对象一大,一旦获取了该数据源对象,程序就可以通过该数据源取得数据库连接,从而访问数据库
上面的方式是配置局部数据源,如果需要配置全局数据源,则应该通过的修改server,xml文件来实现,全局数据源的配置与局部数据源的配置基本类似,只是修改的文件不同。局部数据源只需要修改Web应用的配置文件,而全局数据源需要修改Tomcat的server.xml文件
使用全局数据源需要修改Tomcat原有的server.xml文件所以可能导致破坏Tomcat系统,因而尽量避免使用全局数据源
Eclipse平台是IBM向开源社区捐赠的开发框架,IBM官宣为开发Eclipse投入了4千万美元,这种巨大投入开发出了一个成熟的、精心设计的、可扩展的开发工具。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版本的兼容性
手动安装也分两种安装方式
直接安装
将插件中包含的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文件删除即可
为了开发Web应用,必须现在Eclipse中配置Web服务器,这里以Tomcat位例来介绍如何在Eclipse中配置Web服务器。在Eclipse中配置Tomcat按如下步骤进行
一、单击Eclipse主界面下方的“Servers”面板,在该面板的空白处单击鼠标右键,在弹出的快捷菜单中选择“New”->“Server”菜单项
添加Servlet9并且遵循Servlet4.0的开发规范,指定Tomcat路径后,在WebContext中新建一个JSP文件
将需要部署的项目移动到右边列表框内
很多时候,可能需要向Eclipse中导入其他项目。比如实际开发中可能需要导入其他开发者提供的Eclipse项目,在学习过程中可能需要导入网络、书籍中提供的示例项目。
向Eclipse中导入一个Eclipse项目比较简单
一、单击“File”->“Import…”菜单项
二、选择“General”->“Existing Projects into Workspace”节点,单击“Next”按钮,系统将弹出下图
三、输入项目保存位置,也可以通过Browse按钮来选择项目保存的位置,输入完成后,将看到“Projects”文本域内列出了所有可导入的项目,勾选需要导入的项目后,单击“Finish”按钮即可
有些时候,也可能需要导入非Eclipse项目到Eclipse中、一、新建一个普通的Eclipse项目
二、单击“File”->“Import…”菜单项
三、选择“General”->“File System”节点,单击“Next”按钮
此对话框的左边有三个按钮,它们的作用分别是
四、输入需要导入文件的路径
不要指望将一个非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是一种基于Java的生成工具。从作用上看,它有些类似于C编程(UNIX平台上使用较多)中的Make工具,C/C++项目经常使用Make工具来管理整个项目的编译、生成
Make使用Shell命令来定义生成任务,并定义任务之间的依赖关系,以便它们总是以必需的顺序来执行
Make工具主要有如下两个缺陷
Ant是基于Java语言的生成工具,所以具有跨平台的能力;而且Ant工具使用XML来编写生成文件,因而具有更好的适应性
由此可见,Ant是Java世界的Make工具,而且这个工具是跨平台的,并且具有简单、易用的特性
由于Ant具有跨平台性,所以编写Ant生成文件时可能会失去一些灵活性。为了弥补这个不足,Ant提供了一个“exec”核心任务,这个任务允许执行特定操作系统上的命令
https://archive.apache.org/dist/ant/source/
先找到官网然后进行搜索
下载后解压到一个位置
为环境变量中添加以下配置
JAVA_HOME -> JDKPath
ANT_HOME -> ANTPath
Path add -> %ANT_HOME%\bin
配置完毕后在命令行输入命令ant.bat
出现以下信息则表示安装成功
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生成文件的根元素是
例如,如下代码片段
每个生成目标对应一个
例如,如下配置片段
<target name="run" depends="compile"/>
<target name="exA" if="prop1"/>
<target name="exB" unless="prop2"/>
每个生成目标又可能由一个或多个任务序列组成,当执行某个生成目标时,实际上就是依次完成该目标所包含的全部任务。每个任务由一段可执行的代码组成
定义任务的代码格式如下
<name attribute1="value1" attribute2="value2" .../>
上面代码中name是任务的名称,attributeN和valueN用于指定执行该任务所需的属性名和属性值
简而言之,Ant生成文件的基本结构是 project/> 元素里包含多个 target/>元素,而每个 target/>元素里包含多个任务,看下图结构示意
Ant的任务可以分为如下三类
核心任务:Ant自带的任务
可选任务:来自第三方的任务,因此需要一个附加的JAR文件
用户自定义的任务:用户自己开发的任务
此外,
一、property元素
定义一个属性的最简单形式如下:
<project name="builddir" value="dd"/>
如果需要获取属性值,则使用${propName}的形式。例如,如下代码即可获取builddir属性值
${builddir}
由此可见,"$"符号在Ant沙僧陈文件中具有特殊的意义,如果希望Ant将生成文件中的美元符号当成普通字符,可以使用“两个美元符号”。例如,如下配置片段
<echo>$${builddir}=${builddir}echo>
上面代码中的$${builddir}不会获取builddir属性值,而美元符号{builddir}才会获取builddir属性值,执行上面任务,将会输出
[echo] ${builddir}=dd
echo是Ant的核心任务之一,该任务直接输出某个字符串,通常用于输出某些提示信息
实际上,
关于文件集合和路径集以及文件集合路径集引用的知识,请参考
下面给出几个使用
<property file="foo.properties"/>
从网络中读取属性名和属性值
<!-- 指定从指定URL处读取属性名和属性值 -->
<property url="http://www.crazyit.org/props/foo.properties" />
通过
author=Yeeku.H.Lee
book=Light Weight Java EE
price=128
此外,通过
<property environment="env" />
定义了上面的
<echo>${env.JAVA_HOME}echo>
在我们的机器上运行上面的任务,即可看到输出:[echo]D:\Java\jdk-11.0.1,这就是该机器上JAVA_home环境变量的值
二、path元素和classpath元素
使用Ant编译、运行Java文件时常常需要引入第三方JAR包,这就是需要使用
因为
location:指定一个目录和JAR文件
因为JAR文件还可以包含更多层次的文件结构,所以可以将JAR文件看成一个文件路径
例如下面配置片段
<pathelement path="/path/to/file2.jar:/path/to/class2;/path/to/class3"/>
<pathelement location="lib/helper.jar"/>
如果需要指定路径集,则应该使用
<!-- 指定该路径集的根路径是build目录 -->
<dirset dir="build">
<!-- 指定包含apps目录下的所有classes目录 -->
<include name="apps/**/classes" />
<!-- 指定排除目录名中有Test子串的目录 -->
<exclude name="apps/**/*Test*"/>
</dirset>
上面的配置文件代表build/apps目录下所有名为classes且文件名中不包含Test子串的目录
如果希望配置多个文件,则可用
例如下面的配置片段
<!-- 配置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 id="docfiles" dir="${doc.src}">
<!-- 通过两个file子元素指定的文件列表和通过files属性指定的文件列表完全一样 -->
<file name="foo.xml"/>
<file name="bar.xml"/>
</filelist>
此外,
<fileset dir="src" casesensitive="yes">
<include name="**/*.java"/>
<exclude name="**/*Test*"/>
掌握了
<path id="classpath">
<pathelement path="${classpath}"/>
<fileset dir="lib">
<include name="**/*.jar"/>
fileset>
<pathelement location="classes"/>
<dirset dir="build">
<include name="apps/**/classes"/>
<exclude name="apps/**/*Test*"/>
dirset>
<filelist dir="res" files="a.properties,b.xml"/>
path>
现在已经掌握了Ant生成文件的基本结构,以及
Ant提供了大量的核心task和可选task,除此之外,Ant还允许用户定义自己的task,这大大扩展了Ant的功能
在%ANT_HOME%\manual\Tasks路径下包含了Ant的所有的task介绍文档
下面定义了一份简单的生成文件,这份生成文件里包含了编译Java文件、运行Java程序、生成JAR包等常用的target,通过这份文件就可以非常方便的管理该项目
xml version="1.0" encoding="utf-8" ?>
<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>
<target name="help" description="打印帮助信息">
<echo>help - 打印帮助信息echo>
<echo>compile - 编译Java源文件echo>
<echo>run - 运行程序echo>
<echo>build - 打包JAR包echo>
<echo>clean - 清除所有编译生成的文件echo>
target>
<target name="compile" description="编译Java源文件">
<delete dir="${classes}"/>
<mkdir dir="${classes}"/>
<javac destdir="${classes}" debug="true" includeantruntime="yes"
deprecation="false" optimize="false" failonerror="true" encoding="utf-8">
<src path="${src}"/>
<classpath refid="classpath"/>
javac>
target>
<target name="run" description="运行程序" depends="compile">
<java classname="lee.HelloTest" fork="yes" failonerror="true">
<classpath refid="classpath"/>
<arg line="测试参数1 测试参数2"/>
java>
target>
<target name="build" description="打包JAR文件" depends="compile">
<delete dir="${dest}"/>
<mkdir dir="${dest}"/>
<jar destfile="${dest}/app.jar" basedir="${classes}"
includes="**/*.class">
<manifest>
<attribute name="Main-Class" value="lee.HelloTest"/>
manifest>
jar>
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可食用如下命令
Maven是一个比Ant更先进的项目管理工具,它采用一种“约定由于配置(Coc)”的策略来管理项目。使用Maven不仅可以把源代码构建成可发布的项目(包括编译、打包、测试和分发),还可以生成报告、生成Web站点等。在某些方面,Manven比Ant更加优秀,因此不少企业已经开始使用Maven
重名Maven文件夹仅仅是为了方便、简介,并不是必须的
运行Maven需要如下两个环境变量
Maven安装路径就是前面释放Maven压缩文件的路径。在Maven安装路径下应该包含bin、boot、conf和lib这四个文件夹
Maven工具的关键命令就是%M2_HOME%\bin路径下的命令,建议将%M2_HOME%\bin添加到系统PATH环境变量中
经过上面步骤后,打开命令行界面输入
mvn help:system
Maven的运行概念是Maven主概念去调用各个插件,所以不管每次哪个操作第一次都需要去网上下载很多东西
设置Maven行为有两种方式
上面两种方式只是起作用的范围不同,它们都使用settings.xml作为配置文件,而且这两种方式中settings.xml文件允许定义的元素也是相同的
通常来说,Maven允许设置如下参数
资源库是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中查看
上面项目会生成一个mavenQs文件夹
pom文件如下
pom.xml文件被称为项目对象模型(Project Object Model,POM)描述文件,Maven使用项目对象模型的方式来管理项目。POM用于描述该项目是什么类型的、该项目的名称是什么、该项目的构建是否自定义,Maven使用pom.xml文件来描述项目对象模型。因此,pom.xml并不是简单的生成文件,而是项目对象模型描述文件
由于本书使用Java11作为默认的编译、运行环境,Java11不再支持编译Java5的源代码,而Maven默认使用Java5的编译级别,因此需要通过属性告诉compiler插件使用更高级的编译级别。可以在上面pom.xml文件的
<properties>
<maven.compiler.source>1.6maven.compiler.source>
<maven.compiler.target>1.6maven.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中的默认设置
以上片段指定了编译该项目所使用的compiler插件,该插件默认执行compile目标
从前面介绍的过程来看,只要将项目的源文件按照Maven要求的规范组织,并提供pom.xml文件,即pom.xml文件中只包含极少的信息,开发者也依然可以使用Maven来编译项目、运行程序,甚至可以测试用例、打包项目,这是因为Maven采用了“约定优化配置(Convention over Configuration,CoC)”的原则、根据此原则,Maven的主要约定有如下几条
通过这种约定,就可以避免像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命令除了可以使用
mvn <phase1> <phase2>...
以上命令告诉Maven执行Maven生命周期中的一个或多个阶段。当使用mvn命令告诉Maven执行生命周期的某个阶段时,Maven会自动从声明周期的第一个阶段开始执行,直至mvn命令指定的阶段
Maven包含三个基本的生命周期
clean生命周期用于在构建项目之前进行一些清理工作,该生命周期包含如下三个核心阶段
进入mavenQs项目中pom.xml所在的路径下,执行如下命令:
mvn post-clean
执行上面命令将会清理项目编译过程中生成的文件。执行该命令后,将可以看到mavenQs目录下只剩下src目录和pom.xml文件
默认的生命周期则包含了项目构建的核心部分。默认的生命周期包含如下核心阶段
mvn compile、mvn install命令所执行的都是上面列出的阶段。当使用Maven执行mvn install时,实际上将会先执行install阶段之前的阶段。下图显示了Maven默认的生命周期所包含的核心阶段的执行过程
上面列出的只是Maven默认的生命周期的核心阶段。实际上,Maven默认的生命周期包含如下阶段
site 生命周期用于生成项目报告站点、发布站点。该声明周期包含如下核心阶段
在pom.xml添加如下代码
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-site-pluginartifactId>
<version>3.9.0version>
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文件的
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojogroupId>
<artifactId>exec-maven-pluginartifactId>
<version>1.3.1version>
<executions>
<execution>
<phase>compilephase>
<goals>
<goal>
<goal>javagoal>
goal>
goals>
<configuration>
<mainClass>org.fkjava.mavenqs.AppmainClass>
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个元素组成
例如,mavenQs项目的pom.xml文件中的如下配置定义了该项目的Maven坐标
<groupId>org.fkjavagroupId>
<artifactId>mavenQsartifactId>
<packaging>jarpackaging>
<version>1.0-SNAPSHOTversion>
Maven坐标可用于精准定位一个项目。例如,mavenQs项目中还有如下配置片段
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>3.8.1version>
<scope>testscope>
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需要使用某个插件或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
项目结构
smqs
src
main
resources
webapp
WEB-INF
web.xml
其中,WEB-INF路径和web.xml文件就是Web应用必须的文件夹和配置文件
接下来打开smqs目录下的pom.xml文件,在该文件的
<version>3.8.1version>
<name>smqsname>
<url>http://www.crazyit.orgurl>
<licenses>
<license>
<name>Apache 2name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txturl>
<distribution>repodistribution>
<comments>A business-friendly OSS licensecomments>
license>
licenses>
<organization>
<name>CrazyItname>
<url>http://www.crazyit.orgurl>
organization>
<developers>
<developer>
<id>kongyeekuid>
<name>kongyeekuname>
<email>[email protected]email>
<url>http://www.crazyit.orgurl>
<organization>CrazyItorganization>
<roles>
<role>developerrole>
roles>
<timezone>+8timezone>
developer>
developers>
<contributors>
<contributor>
<name>fkjavaname>
<email>[email protected]email>
<url>http://www.fkjava.orgurl>
<organization>疯狂软件教育中心organization>
<roles>
<role>developerrole>
roles>
contributor>
contributors>
上面的配置内容用于定制该项目的配置信息,这段配置信息指定了该项目遵循的License,并指定了该项目所属的组织、项目的开发者,以及对项目有贡献的人。这些信息都用于定制该Maven项目,这些信息主要起描述的作用
为该项目添加Spring MVC的支持,可以在pom.xml中的
关于Maven的依赖配置,需要说明的是,Maven依赖管理具有传递性,比如配置文件设置了项目依赖a.jar,而a.jar又依赖b.jar,那么该项目无须显式声明依赖b.jar,Maven会自动管理这种依赖的传递
由于Maven的依赖管理具有传递性,因此有时需要用
<dependency>
<groupId>javax.activationgroupId>
<artifactId>mailartifactId>
<type>jartype>
<exclusions>
<exclusion>
<artifactId>activationartifactId>
<groupId>javax.activationgroupId>
exclusion>
exclusions>
dependency>
上面配置指定该项目依赖mail.jar。由于Maven的依赖具有传递性,因此Maven会自动将mail.jar依赖的activation.jar也包含进来。为了将activation.jar排除出去,即可进行如上配置文件中所示
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.2.0.RELEASEversion>
dependency>
进入smqs项目的pom.xml文件所在的路径下,执行如下命令
mvn package
由于此时Maven项目中的文件组织形式符合Web应用的格式,而且pom.xml文件中
执行上面的命令,同样也会从网络上下载插件和文件
执行结束后可以看到一个smqs.war
可以看出,使用Maven之后,开发者只需要在pom.xml文件中配置该项目依赖SpringMVC,剩下的事情就交给Maven搞定,开发者无须关心Spring MVC的官网,无须关心从哪里下载Spring MVC的JAR包,无须关心Spring MVC框架哪些第三方JAR包,所有依赖关系都交给Maven处理即可。依赖管理,可以说是Maven最大的魅力之一
Maven使用pom.xml文件来描述项目对象模型,因此pom.xml文件可以包含大量元素用于描述该项目。前面已经通过示例介绍了pom.xml文件中大量常用的元素。实际上,pom.xml文件还可包含如下元素
关于pom.xml文件的详细语句约束可参考 http://maven.apache.org.maven-v4_0_0.xsd文件
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是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”菜单项,系统弹出如下参数设置对话框
在上图所示的参数对话框中提供了常用的设置分类
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”菜单项
三、该对话框设置重设的相关选项
由于前一步删除了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 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安装完成后,启动浏览器,在地址栏输入
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> <远程分支名>