前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >tomcat启动分析(2)Bootstrap

tomcat启动分析(2)Bootstrap

作者头像
平凡的学生族
发布2019-05-25 09:24:54
5660
发布2019-05-25 09:24:54
举报
文章被收录于专栏:后端技术后端技术

startup.bat会最终运行Bootstrapmain方法,而main会先调用init方法。

1.init

1.1 setCatalinaHome();、setCatalinaBase();

代码语言:javascript
复制
setCatalinaHome();
setCatalinaBase();

点进它们的实现,发现这两个方法都调用到System.getProperty(Globals.CATALINA_HOME_PROP),其中Globals.CATALINA_HOME_PROP"catalina.home"。这个调用的返回值不会是空,因为在之前的idea启动设置中:

catalina.home环境变量设置为了tomcat的home目录。 这两个函数会设置Globals.CATALINA_BASE_PROPGlobals.CATALINA_HOME_PROP的系统变量。

1.2 initClassLoaders

创建commonLoadercatalinaLoadersharedLoader类加载器(默认情况下这三个类加载器指向同一个对象。它们都调用了createClassLoader

1.2.1 createClassLoader

装载 catalina.properties 里配置的目录下的文件和jar包,后两个加载器的父加载器都是第一个,最后注册了 MBean,可以用于 JVM 监控该对象)。

代码语言:javascript
复制
String value = CatalinaProperties.getProperty(name + ".loader");

CatalinaProperties在static代码块内会读取{home}/conf/catalina.properties,加载到properties变量。之后便可调用getProperty获取其中的属性。 换句话说,CatalinaProperties的属性都可在文件catalina.properties找到。

代码语言:javascript
复制
value = replace(value);

value中的${catalina.base}${catalina.home}替换为实际的字符串。

中间的一段代码是根据value分割的每个路径各自生成一个Repository,添加到repositories里。

最后调用

代码语言:javascript
复制
return ClassLoaderFactory.createClassLoader(repositories, parent);

其中getCanonicalPath可查阅file的getPath getAbsolutePath和getCanonicalPath的不同。 该函数会先解析repositories,把路径和需要添加的jar包的URL都保存到set中。 最后调用

代码语言:javascript
复制
return AccessController.doPrivileged(
    new PrivilegedAction<URLClassLoader>() {
        @Override
        public URLClassLoader run() {
            if (parent == null)
                return new URLClassLoader(array);
            else
                return new URLClassLoader(array, parent);
        }
    });

其中AccessController.doPrivilegedURLClassLoader可看教程(这两个知识点分别能占据不少学习时间)。

总之,createClassLoader会根据repositories找到路径和路径下的jar包,将它们合起来,创建一个基于这些URL的URLClassLoader。

1.2.2 回到initClassLoaders

commonLoader = createClassLoader("common", null);会将commonLoader绑定一个URLClassLoader,而

代码语言:javascript
复制
catalinaLoader = createClassLoader("server", commonLoader);
sharedLoader = createClassLoader("shared", commonLoader);

其实都是第一个commonLoader,因为createClassLoader内有:

代码语言:javascript
复制
if ((value == null) || (value.equals("")))
  return parent;

1.3中间步骤

代码语言:javascript
复制
Thread.currentThread().setContextClassLoader(catalinaLoader);
SecurityClassLoad.securityClassLoad(catalinaLoader);
  1. Thread.currentThread().setContextClassLoader(catalinaLoader);是为了设置该线程的上下文ClassLoader,以便以后调用Class.forName(string name)加载时,用给好的catalinaLoader
  2. SecurityClassLoad.securityClassLoad(catalinaLoader);是会加载各种需要用到的类,以防以后被安全检查阻止。

1.4 调用Catalina的setParentClassLoader

后面的这些代码就是用反射机制完成以下事情:

  1. 加载一个org.apache.catalina.startup.Catalina对象
  2. 调用其public void setParentClassLoader(ClassLoader parentClassLoader)方法,且参数传入为sharedLoader

2. 获取参数

然后执行以下代码,获取最后一个参数。

代码语言:javascript
复制
String command = "start";
  if (args.length > 0) {
    command = args[args.length - 1];
  }

由于传来的最后一个参数是start(startup.bat中传入的),故会执行以下代码,也就是loadstart

代码语言:javascript
复制
 else if (command.equals("start")) {
  daemon.setAwait(true);
  daemon.load(args);
  daemon.start();
}

3. load

就是通过反射调用 catalinaDaemon 对象的 load 方法,catalinaDaemon 对象在上面的 init 方法中已经实例化过了。

4. start

start 方法与 load 方法相似,也是通过反射调用 catalinaDaemon 对象上的 start 方法

总结

1.就是设置"catalina.home"和"catalina.base"环境变量

  1. 创建URLClassLoader用于加载lib下的jar包(源码中lib是空的,正式软件中lib有很多需要的jar包)、预加载各种类。
  2. 设置那个URLClassLoader为各种loader以及线程的ClassLoader
  3. 创建了一个Catalina服务器实例,并调用其loadstart方法。

下面一篇文章将分析 catalinaDaemon 对象中的 load、start 两个方法,里面会涉及一个有趣的话题 —— Digester 的使用。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.04.10 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.init
    • 1.1 setCatalinaHome();、setCatalinaBase();
      • 1.2 initClassLoaders
        • 1.2.1 createClassLoader
        • 1.2.2 回到initClassLoaders
      • 1.3中间步骤
        • 1.4 调用Catalina的setParentClassLoader
        • 2. 获取参数
        • 3. load
        • 4. start
        • 总结
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档