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

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

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

准备工作

  • 开发工具: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的执行步骤:
  1. 对当前的操作系统进行检测,检测完毕后验证连接是否可用。
  2. 定义变量:PRGDIR存储当前系统目录,EXECUTABLE存储文件名称
  3. 调用另外一个可执行文件(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
  1. 观察代码5-1~5-4我们可以看出来catalina.sh文件的执行步骤如下
  2. 系统参数验证,就是大家常用的环境变量(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源代码了。

你可能感兴趣的:(Java,tomcat,代码分析)