您的位置:首页 > 运维架构 > Tomcat

Tomcat9源代码分析(一)-源码切入点

2017-12-08 11:14 387 查看
        转JAVA开发(之前做.NET(C#))到现在已经一年多一点了。掌握了基本JAVA开发技能,但对于JAVA更深层次的基数一直无暇探究。今天开始就来着手从Tomcat9源代码开始研究JAVA的世界。

        本系列文章是本人针对Tomcat9的部分源代码个人理解的一个归纳,如有不正确的地方请及时纠正。本人邮箱:249466389@qq.com欢迎大家一起研究讨论。

准备工作

开发工具:IDEA
Tomcat源代码版本:apache-tomcat-9.0.2-src
下载地址:https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-9/v9.0.2/src/apache-tomcat-9.0.2-src.zip
SSH工具:Bitvise SSH Client
        Tomcat安装方法此处不再赘述,不会的同学可以找度娘。

正文

        当我们一套系统开发完毕,将打好*.war包丢到/Tomcat/webapp/目录下,调用/Tomcat/bin/startup.sh启动系统。此时Tomcat服务开始启动。本系列文章就从此处作为入口结合Tomcat源代码一起进入Tomcat的世界,看看她是如何实现,如何工作。

        既然从startup.sh开始,我们就首先来看看startup.sh做了些什么

[root@localhost ~]# cd /home/tomcat/bin/
[root@localhost bin]# vi startup.sh

代码1

        通过上面命令我们可以得到看到如下内容
-----上面内容自动忽略-----
//注册该文件为一个可执行文件(脚本)
os400=false
case "`uname`" in
OS400*) os400=true;;
esac

//解析连接地址是否软连接
PRG="$0"

while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`/"$link"
fi
done
//当前路径
PRGDIR=`dirname "$PRG"`
//文件名称
EXECUTABLE=catalina.sh

//检查目标可执行文件是否存在
if $os400; then
# -x will Only work on the os400 if the files are:
# 1. owned by the user
# 2. owned by the PRIMARY group of the user
# this will not work if the user belongs in secondary groups
eval
else
if [ ! -x "$PRGDIR"/"$EXECUTABLE" ]; then
echo "Cannot find $PRGDIR/$EXECUTABLE"
echo "The file is absent or does not have execute permission"
echo "This file is needed to run this program"
exit 1
fi
fi
//执行文件
exec "$PRGDIR"/"$EXECUTABLE" start "$@"

代码2
        通过代码2中的内容我们可以看出,startup.sh的执行步骤:
对当前的操作系统进行检测,检测完毕后验证连接是否可用。
定义变量:PRGDIR存储当前系统目录,EXECUTABLE存储文件名称
调用另外一个可执行文件(shell脚本)`catalina.sh`。并传递参数`start`

根据这个线索我们继续往下看

[root@localhost bin]# ls
[root@localhost bin]# vi catalina.sh

代码4

        执行上面的命令后,我们可以看到`catalina.sh`内容。
if [ "$1" = "debug" ] ; then
-------忽略部分-----------
exec "$_RUNJDB" "$LOGGING_CONFIG" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \
-Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath "$CLASSPATH" \
-sourcepath "$CATALINA_HOME"/../../java \
-Djava.security.manager \
-Djava.security.policy=="$CATALINA_BASE"/conf/catalina.policy \
-Dcatalina.base="$CATALINA_BASE" \
-Dcatalina.home="$CATALINA_HOME" \
-Djava.io.tmpdir="$CATALINA_TMPDIR" \
org.apache.catalina.startup.Bootstrap "$@" start
else
exec "$_RUNJDB" "$LOGGING_CONFIG" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \
-Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath "$CLASSPATH" \
-sourcepath "$CATALINA_HOME"/../../java \
-Dcatalina.base="$CATALINA_BASE" \
-Dcatalina.home="$CATALINA_HOME" \
-Djava.io.tmpdir="$CATALINA_TMPDIR" \
org.apache.catalina.startup.Bootstrap "$@" start
fi
fi
elif [ "$1" = "run" ]; then
-------忽略部分-----------
eval exec "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \
-Djava.endorsed.dirs="\"$JAVA_ENDORSED_DIRS\"" -classpath "\"$CLASSPATH\"" \
-Djava.security.manager \
-Djava.security.policy=="\"$CATALINA_BASE/conf/catalina.policy\"" \
-Dcatalina.base="\"$CATALINA_BASE\"" \
-Dcatalina.home="\"$CATALINA_HOME\"" \
-Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \
org.apache.catalina.startup.Bootstrap "$@" start
else
eval exec "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \
-Djava.endorsed.dirs="\"$JAVA_ENDORSED_DIRS\"" -classpath "\"$CLASSPATH\"" \
-Dcatalina.base="\"$CATALINA_BASE\"" \
-Dcatalina.home="\"$CATALINA_HOME\"" \
-Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \
org.apache.catalina.startup.Bootstrap "$@" start
fi

elif [ "$1" = "start" ] ; then
-------忽略部分-----------
eval $_NOHUP "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \
-Djava.endorsed.dirs="\"$JAVA_ENDORSED_DIRS\"" -classpath "\"$CLASSPATH\"" \
-Djava.security.manager \
-Djava.security.policy=="\"$CATALINA_BASE/conf/catalina.policy\"" \
-Dcatalina.base="\"$CATALINA_BASE\"" \
-Dcatalina.home="\"$CATALINA_HOME\"" \
-Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \
org.apache.catalina.startup.Bootstrap "$@" start \
>> "$CATALINA_OUT" 2>&1 "&"

else
eval $_NOHUP "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \
-Djava.endorsed.dirs="\"$JAVA_ENDORSED_DIRS\"" -classpath "\"$CLASSPATH\"" \
-Dcatalina.base="\"$CATALINA_BASE\"" \
-Dcatalina.home="\"$CATALINA_HOME\"" \
-Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \
org.apache.catalina.startup.Bootstrap "$@" start \
>> "$CATALINA_OUT" 2>&1 "&"

fi
-------忽略部分-----------

代码5-1

elif [ "$1" = "stop" ] ; then
-------忽略部分-----------
eval "\"$_RUNJAVA\"" $LOGGING_MANAGER $JAVA_OPTS \
-Djava.endorsed.dirs="\"$JAVA_ENDORSED_DIRS\"" -classpath "\"$CLASSPATH\"" \
-Dcatalina.base="\"$CATALINA_BASE\"" \
-Dcatalina.home="\"$CATALINA_HOME\"" \
-Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \
org.apache.catalina.startup.Bootstrap "$@" stop

代码5-2
elif [ "$1" = "configtest" ] ; then
-------忽略部分-----------
 eval "\"$_RUNJAVA\"" $LOGGING_MANAGER $JAVA_OPTS \
      -Djava.endorsed.dirs="\"$JAVA_ENDORSED_DIRS\"" -classpath "\"$CLASSPATH\"" \
      -Dcatalina.base="\"$CATALINA_BASE\"" \
      -Dcatalina.home="\"$CATALINA_HOME\"" \
      -Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \
      org.apache.catalina.startup.Bootstrap configtest

代码5-3
elif [ "$1" = "version" ] ; then
-------忽略部分-----------
-classpath "$CATALINA_HOME/lib/catalina.jar" \
org.apache.catalina.util.ServerInfo

代码5-4

观察代码5-1~5-4我们可以看出来catalina.sh文件的执行步骤如下
系统参数验证,就是大家常用的环境变量(JAVA_HOME,,JAR_HOME,CLASSPATH等)的获取。及其他系统变量的获取及验证。根据传递过来的参数(“$1”)调用JAVA文件及方法:
        debug,run,start:调用org.apache.catalina.startup.Bootstrap 传递参数“start”
        stop:调用org.apache.catalina.startup.Bootstrap 传递参数“stop”
        configtest:调用org.apache.catalina.startup.Bootstrap 传递参数“configtest”
        version:调用org.apache.catalina.util.ServerInfo

        看到此处我们发现熟悉的东西:org.apache.catalina.startup.Bootstrap,org.apache.catalina.util.ServerInfo。这不就是我们常用的类文件引用路径吗?类入口`public static void main(String args[])`我们只要找到对应类中的main方法,就算正式切入Tomcat9源代码了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: