技术经理给我安排了一个上古时期的Tomcat项目,Tomcat中的bat批处理脚本源码分析,还好我是练过的,基础的底层知识掌握得妥妥滴

简介: 技术经理给我安排了一个上古时期的Tomcat项目,Tomcat中的bat批处理脚本源码分析,还好我是练过的,基础的底层知识掌握得妥妥滴
✨我是喜欢分享知识、喜欢写博客的YuShiwen,与大家一起学习,共同成长!
📢闻到有先后,学到了就是自己的,大家加油!

前言:

前几天部门的技术经理给我分配了一个任务,叫我一个人去维护之前上古时期的Java Wbe项目,这个项目其实是一个前置机程序,负责消息的加解密、加签验签和消息的转发;这个程序部署于Servlet容器中,用的是Tomcat服务,并且这个Tomcat服务我们公司的运维人员不知道怎么操作,说配置的步骤太多了,之前有一个人配置成功了,但是离职了,写的文档也模糊不清,现在他们都不知道咋配置,1000-9999人的公司,这个运维人员不大行,算了不吐槽了(⊙﹏⊙)!
运维人员和笔者说,这个前置机程序是运行在客户那边的,最好是不需配置环境变量等其他操作,做到一键点击即可启动Tomcat服务。这样古老项目的维护难度又提高了亿丢丢。
笔者解压缩了之前项目的压缩包后,看了一下,发现启动的步骤是用的Tomcat的startup.bat批处理文件(Windows系统)进行启动的,下面会详细讲。
好了,下面进入正文:

1.idea自动反编译class文件,在idea中我们也可以查看字节码的源代码

首先之前开发的源码已经丢失了,只有编译后的class文件;
当我拿到程序编译后的class文件后,用idea打开,idea自带反编译功能,如下是小demo(公司的代码不能向外界提供,所以这里提供了一个小demo):
比如我打开JDK中的Integer类,上面说到过用idea打开是自动进行了反编译的结果,如下:
在这里插入图片描述
那么如何查看反编译前的字节码文件呢,我们在idea中也可以查看,如下操作:(点击View–>Show Bytecode)
在这里插入图片描述
字节码文件的内容如下:
在这里插入图片描述
好说到这里,咋们就打住,关于如何查看字节码的内容,这个咋们之后再聊(会写一篇关于这个的博文)。
回到主题,刚开始说了,idea自动进行的反编译,还好之前的项目写的代码不多,看了半天代码后,理清思路,然后又花费一天时间,写代码,自测,修改,又自测,终于写好了,自测通过;接下来的任务就是之前运维提到的,去掉项目启动前环境变量配置的过程,优化一系列的操作,做到点击startup.bat批处理文件即可一键启动Tomcat服务。

2.如何做到一键点击startup.bat批处理文件启动Tomcat服务

在这里插入图片描述

2.1startup.bat批处理文件

如下是Tomcat的文件目录,关于Tomcat目录的讲解,可以参考笔者之前的博文:https://blog.csdn.net/MrYushiwen/article/details/113383917
在这里插入图片描述

因为是点击startup.bat批处理文件进行启动的,我第一反应就是用文本编辑器打开startup.bat文件,点击进入bin目录下,bin目录如下,等会讲解红色框中的三个批处理文件:
在这里插入图片描述

找到startup.bat批处理文件,用文本编辑器打开,具体内容如下(嘿嘿,之前有写过批处理脚本的我还是看得懂的哈,看不懂的小伙伴可以参看下面的章节三,关于批处理文件的讲解零基础快速入门):
在这里插入图片描述

第一个红色框这条语句是检测CATALINE_HOME的值,如果不为空,就跳转到gotHome标记出执行。可以看到在这个批处理文件中,多次用到了CATALINA_HOME变量,这个变量我们可以在环境变量中进行配置,关于环境变量深入的理解,可以参考笔者这篇博文:https://blog.csdn.net/MrYushiwen/article/details/120509711,因为在批处理文件中用到了这个CATALINE_HOME变量,它可以取自环境变量,也可以用set命令给CATALINE_HOME变量赋值;所以之前我们需要设置如下环境变量才可以运行:
在这里插入图片描述

第二个红框设置变量EXECUTABLE的值为CATALINE_HOME变量下的bin包下的catalina.bat批处理文件,这个EXECUTABLE在第三步中会用到。

第三个红框用call命令进行调用,启动EXECUTABLE环境变量所指向的程序,即catalina.bat。

好了,startup.bat批处理文件讲解完了,如果我们不想配置环境变量CATALINE_HOME的值,根据上面提到的我们只需要在startup.bat批处理文件头部加上set CATALINE_HOME=xxx(注意等号后面不允许有空格,本人踩过坑)即可,这样就不会从环境变量值获取该值了,直接在批处理文件中就有定义,如下(笔者的路径就是本项目的Tomcat,即就是解压缩之后的文件所在的路径):
在这里插入图片描述

2.2catalina.bat批处理文件

上面提到过startup.bat批处理文件会用call命令调用catalina.bat批处理文件,我们用文本编辑器打开catalina.bat批处理文件,如下:
在这里插入图片描述

第一个红色框,可以看到在catalina.bat批处理文件中也同样用到了CATALINE_HOME这个变量,如果我们不想配置环境变量,同样也可以在文件的开始处加上set CATALINE_HOME=xxx即可。

第二个红色框,用call命令调用了setclasspath.bat批处理文件

同样我们不想配置环境变量,在文件的开始处加上set CATALINE_HOME=xxx即可,如下:
在这里插入图片描述

2.3setclasspath.bat批处理文件

接下来我们点进setclasspath.bat批处理文件中查看,如下:
在这里插入图片描述
第一个红框中可以看到setclasspath.bat批处理文件用到了JAVA_HOME和JRE_HOME这两个变量,如果们配置了环境变量,可以从环境变量中取,我们也可以用set命令在文件头部指定(如下图一),我们指定了就不需要配置Java的环境变量了,当然JDK需要放到Tomcat的目录中去(如下图二),虽然文件大了点,但是方便了用户。这样就做到了不需要配置环境变量,通过startup.bat批处理文件一键启动Tomcat服务。

ffc9fc72cbbf43d88184f302119217a4.png
图一
224af50a00b14161ae3f0ebc85a17aad.png
图二

2.4复盘

根据上面的2.1 、2.2、2.3的分析,我们现在总结一下:
bin目录下的startup.bat—调用—>catalina.bat—调用—>setclasspath.bat
说明:

tomcat的startup.bat脚本主要用来判断环境,找到catalina.bat脚本源路径,将启动命令参数传递给catalina.bat执行;setclasspath.bat检查各种变量是否赋值,验证tomcat启动停止需要涉及到的文件,保障tomcat顺利启动停止;catalina.bat脚本使用了大量的判断,使用if作为参数的输入判断,核心的启动命令其实就是java命令。

我们在startup.bat、catalina.bat和setclasspath.bat这三个批处理文件中用set操作对需要用到的变量进行赋值,这样就不需要再去配置环境变量了。

3.bat批处理文件零基础快速入门

我们以Tomcat中的startup.bat为例进行讲解:(其中rem为注释,大部分rem已被笔者删掉),文件内容如下:
在这里插入图片描述

对上述的脚本一行行的分析(大家耐心看完,绝对会有很大的收获,如果对命令不是很了解的话,可以看下该篇文章进行学习:批处理命令教程;然后在过来看笔者这里写的,妥妥地保姆级别分析源码):

@echo off
默认情况下,批处理文件将在运行时显示其命令。 这第一个命令的目的是关闭这个显示。 “echo off”命令会关闭整个脚本的显示,除了“echo off”命令本身之外。前面的“@”符号使命令也适用于自己。if "%OS%"=="Windows_NT" setlocal
这是个if语句。在命令行中执行help if就可以打印出if语句的使用帮助,大家可以多看下手册。
这里这条语句的作用是检查OS环境变量的值是否是Windows_NT,如果条件成立,则执行setlocal。setlocal这是开始批处理文件中环境改动的本地化操作。在执行SETLOCAL之后所做的环境改动只限于批处理文件。要还原原先的设置,必须执行ENDLOCAL。达到批处理文件结尾时,对于该批处理文件的每个尚未执行的SETLOCAL命令,都会有一个隐含的ENDLOCAL被执行。set CURRENT_DIR = %cd%
这条语句是设置变量CURRENT_DIR 的值为当前目录(两个百分号可以取变量的值),比如C:\Users\yushiwenif not "%CATALINE_HOME%"=="" goto gotHome
这条语句是检测CATALINE_HOME的值,如果不为空,就跳转到gotHome标记(标签)处执行。(用冒号+字符表示标记,比如第8条的 :gotHomeset CATALINA_HOME=%CURRENT_DIR%
把CATALINA_HOME的值设置为CURRENT_DIR变量的值,两个百分号可以取变量的值。if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHomecd ..set CATALINA_HOME=%cd%cd %CURRENT_DIR%
6、7、8、9一起讲:
如果catalina.bat是存在的,就跳转到okHome标记处开始往下继续执行,
如果catalina.bat不存在,先cd到当前目录的上级目录,然后设置CATALINA_HOME变量为cd变量所对应的值(注意上一步已经执行了cd …,返回了上级目录,此时的目录是之前目前的上级目录)。:gotHome
标记,goto命令用来跳转,上面的第4条语句用到了该标记。if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome
判断指定的文件是否存在,存在就跳转到okHomeecho The CATALINA_HOME environment variable is not defined correctly
echo命令用于在命令行中显示echo后面的字符内容echo This .....
echo命令用于在命令行中显示echo后面的字符内容goto end
和上面的11.if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome一起看,如果if条件不成立,就跳转到end标记处,继续往下执行,其实就是结束了此次批处理命令。:okHome
标记,goto命令用来跳转,上面的第11条语句用到了该标记。set EXECUTABLE=%CATALINA_HOME%\bin\catalina.bat
设置EXECUTABLE变量的值if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHomeecho Cannot find ......eco This file ......goto end:okExec
17、18、19、20、21一起看:
如果catalina.bat还是不存在的话,就在命令行窗口回显两句话,然后跳转到end标记处,继续往下执行,其实就是结束了此次批处理命令。
如果catalina.bat存在,就跳转到okExec标记(标签)处,继续往下执行。set CMD_LINE_ARGS=
清空CMD_LINE_ARGS变量的值:setArgs
标记,goto命令用来跳转,下面的第27条语句用到了该标记,起到了循环的作用。if ""%1""=="""" goto doneSetArgs
检查%1是否为空,如果为空就表示没有参数了,设置参数结束,跳转至doneSetArgs标记处;如果不为空就把%1指向的参数追加到CMD_LINE_ARGS这个环境变量中。
知识点:关于这里的%1 还有下面的第26条命令shift
比如有如下的文件:demo.bat
demo.bat文件的内容为:echo %0 %1 %2 %3 ,(如下图图A)
demo.bat这个批处理文件只有一条语句,在命令行中执行这条语句:demo.bat a b c d e
那么结果就会打印出如下内容:(如下图图B)
C:\Users\yclw060\Desktop>demo.bat a b c d e

C:\Users\yclw060\Desktop>echo demo.bat a b c
demo.bat a b c

说明:%0 %1 %2 %3都表示变量
%0表示这个批处理文件的文件名,%1表示传递给该批处理文件的第一个参数,%2表示传递给该批处理文件的第二个参数,%3表示传递给该批处理文件的第三个参数,一直可以用这个方法传递9个参数,即使用到%9,但是如果参数再多了,应该如何处理呢?
这时候shift命令就派上用场了
现在我们来更改demot.bat的内容,更改后的内容如下:(如下图图C)
shift
echo %0 %1 %2
做了这些更改之后,同样执行上面的命令:demo.bat a b c d e
shift这个命令的作用就是把传递的参数依次前移,这样%0就代表了a,%1代表b,%2代表c,%3代表d了。(如下图图D)
如果让e显示出来,就需要用两次shift,那么此时%0就代表了b,%1代表c,%2代表d,%3代表e。

在这里插入图片描述
图A
在这里插入图片描述
图B
在这里插入图片描述
图C
在这里插入图片描述

图D

set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1
把%1指向的参数追加到CMD_LINE_ARGS这个环境变量中shift
shift指令是移位参数,使%1指向了下个参数goto setArgs
跳转到setArgs,检查%1是否为空,如果不空,继续追加参数。:doneSetArgs
标记(标签),goto命令用来跳转,上面的第24条语句用到了该标记,起到了结束循环的作用。call "%EXECUTABLE%" start %CMD_LINE_ARGS%
调用EXECUTABLE环境变量所指向的程序,即catalina.bat,其后跟的第一个参数是start,表示启动Tomcat,如果是stop,则停掉Tomcat,第二个参数是把CMD_LINE_ARGS作为参数传递进去;:end
标记,可以用goto命令跳转到此处,直接结束此处批处理命令。

能坚持到这里,相信大家一定会有所收获,另外,如果觉得笔者写得还八错,期待后续的博文可以点波关注哈!

知我所能,我所能者,尽善尽美; 知我所不能,我所不能者,虚怀若谷!

我是喜欢分享知识、喜欢写博客的YuShiwen,与大家一起学习,共同成长!咋们下篇博文见。

已完结
于CSDN
2022.02.24
author:YuShiwen
目录
相关文章
|
3天前
|
监控 Java 应用服务中间件
Spring Boot整合Tomcat底层源码分析
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置和起步依赖等特性,大大简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是其与Tomcat的整合。
19 1
|
3月前
|
Java 应用服务中间件 Windows
【应用服务 App Service】App Service 中部署Java项目,查看Tomcat配置及上传自定义版本
【应用服务 App Service】App Service 中部署Java项目,查看Tomcat配置及上传自定义版本
|
2月前
|
监控 网络协议 应用服务中间件
【Tomcat源码分析】从零开始理解 HTTP 请求处理 (第一篇)
本文详细解析了Tomcat架构中复杂的`Connector`组件。作为客户端与服务器间沟通的桥梁,`Connector`负责接收请求、封装为`Request`和`Response`对象,并传递给`Container`处理。文章通过四个关键问题逐步剖析了`Connector`的工作原理,并深入探讨了其构造方法、`init()`与`start()`方法。通过分析`ProtocolHandler`、`Endpoint`等核心组件,揭示了`Connector`初始化及启动的全过程。本文适合希望深入了解Tomcat内部机制的读者。欢迎关注并点赞,持续更新中。如有问题,可搜索【码上遇见你】交流。
【Tomcat源码分析】从零开始理解 HTTP 请求处理 (第一篇)
|
2月前
|
人工智能 前端开发 Java
【Tomcat源码分析】启动过程深度解析 (二)
本文深入探讨了Tomcat启动Web应用的过程,重点解析了其加载ServletContextListener及Servlet的机制。文章从Bootstrap反射调用Catalina的start方法开始,逐步介绍了StandardServer、StandardService、StandardEngine、StandardHost、StandardContext和StandardWrapper的启动流程。每个组件通过Lifecycle接口协调启动,子容器逐层启动,直至整个服务器完全启动。此外,还详细分析了Pipeline及其Valve组件的作用,展示了Tomcat内部组件间的协作机制。
【Tomcat源码分析】启动过程深度解析 (二)
|
1月前
|
Java 应用服务中间件 Maven
idea+maven+tomcat+spring 创建一个jsp项目
这篇文章介绍了如何在IntelliJ IDEA中使用Maven和Tomcat创建一个JSP项目,包括配置Maven依赖、设置Tomcat服务器、编写JSP页面、创建控制器和配置文件,以及项目的运行结果。
160 0
idea+maven+tomcat+spring 创建一个jsp项目
|
2月前
|
前端开发 Java 应用服务中间件
【Tomcat源码分析 】"深入探索:Tomcat 类加载机制揭秘"
本文详细介绍了Java类加载机制及其在Tomcat中的应用。首先回顾了Java默认的类加载器,包括启动类加载器、扩展类加载器和应用程序类加载器,并解释了双亲委派模型的工作原理及其重要性。接着,文章分析了Tomcat为何不能使用默认类加载机制,因为它需要解决多个应用程序共存时的类库版本冲突、资源共享、类库隔离及JSP文件热更新等问题。最后,详细展示了Tomcat独特的类加载器设计,包括Common、Catalina、Shared、WebApp和Jsp类加载器,确保了系统的稳定性和安全性。通过这种设计,Tomcat实现了不同应用程序间的类库隔离与共享,同时支持JSP文件的热插拔。
【Tomcat源码分析 】"深入探索:Tomcat 类加载机制揭秘"
|
2月前
|
设计模式 应用服务中间件 容器
【Tomcat源码分析】Pipeline 与 Valve 的秘密花园
本文深入剖析了Tomcat中的Pipeline和Valve组件。Valve作为请求处理链中的核心组件,通过接口定义了关键方法;ValveBase为其基类,提供了通用实现。Pipeline则作为Valve容器,通过首尾相连的Valve链完成业务处理。StandardPipeline实现了Pipeline接口,提供了详细的Valve管理逻辑。通过对代码的详细分析,揭示了模板方法模式和责任链模式的应用,展示了系统的扩展性和模块化设计。
【Tomcat源码分析】Pipeline 与 Valve 的秘密花园
|
1月前
|
Java 应用服务中间件 Linux
tomcat学习二:tomcat部署多个项目:不修改端口和修改端口 两种方式详解
这篇文章详细介绍了在Tomcat服务器上部署多个项目的方法,包括不修改端口和修改端口两种方式。
98 0
|
2月前
|
设计模式 人工智能 安全
【Tomcat源码分析】生命周期机制 Lifecycle
Tomcat内部通过各种组件协同工作,构建了一个复杂的Web服务器架构。其中,`Lifecycle`机制作为核心,管理组件从创建到销毁的整个生命周期。本文详细解析了Lifecycle的工作原理及其方法,如初始化、启动、停止和销毁等关键步骤,并展示了LifecycleBase类如何通过状态机和模板模式实现这一过程。通过深入理解Lifecycle,我们可以更好地掌握组件生命周期管理,提升系统设计能力。欢迎关注【码上遇见你】获取更多信息,或搜索【AI贝塔】体验免费的Chat GPT。希望本章内容对你有所帮助。