资讯专栏INFORMATION COLUMN

TOMCAT-02-tomcat 启动流程01

KavenFan / 3072人阅读

摘要:反射创建对象,并设置设置对象为的成员变量是对象,该对象的属性是也就是我们可以看到,其中的的声明是类型的,降低了和的耦合,而且编译时不用提供的依赖。

tomcat 启动流程01

通过debug 分析tomcat启动流程

1.tomcat启动入口

2、初始化Catalina对象

1. 初始化内容:反射实例话Catalina并添加ClassLoader

初始化入口

 public static void main(String args[]) {//args 参数是start, stop 等等

        if (daemon == null) {
            // Don"t set daemon until init() has completed
            Bootstrap bootstrap = new Bootstrap();
            try {
                bootstrap.init();//初始化Catalina对象,参考catalinaDaemon

bootstrap.init会初始化一个Catalina对象,并给其中的ClassLoader赋值

classLoader成员变量

    /**
     * The shared extensions class loader for this server.
     */
    protected ClassLoader parentClassLoader =Catalina.class.getClassLoader();

2、初始化Catalina的classloader

    //tomcat 的3个相关classloader
    ClassLoader commonLoader = null;
    ClassLoader catalinaLoader = null;
    ClassLoader sharedLoader = null;


    // -------------------------------------------------------- Private Methods
    private void initClassLoaders() {
        try {
            commonLoader = createClassLoader("common", null);
            if( commonLoader == null ) {
                // no config file, default to this loader - we might be in a "single" env.
                commonLoader=this.getClass().getClassLoader();
            }
            catalinaLoader = createClassLoader("server", commonLoader);
            sharedLoader = createClassLoader("shared", commonLoader);

上述initClassLoaders方法会读取${TOMCAT_HOME}/conf/catalina.properties文件,读取要loader的jar包配置

注意,tomcat在catalina.properties 配置文件中指定了:common.loader,catalina.loader,shared.loader但是后2者的配置都为空,网上说是shared.loader 是分享公共的,没有配置的意义。
从上述的initClassLoaders 可以看出使用creatteClassLoader("","") 创建后两者的loader时,都传入了commonLoader, 这样,配置为空,catalinaLoader 其实还是commonLoader.

备注:tomcat使用了org.apache.catalina.startup.CatalinaProperties封装tomcat/conf/catalina.properties文件,其读取配置文件的方式值得学习,代码如下:

    private static void loadProperties() {

        InputStream is = null;
        Throwable error = null;

        try {
            String configUrl = System.getProperty("catalina.config");
            if (configUrl != null) {
                is = (new URL(configUrl)).openStream();
            }
        } catch (Throwable t) {
            handleThrowable(t);
        }

        if (is == null) {
            try {
                File home = new File(Bootstrap.getCatalinaBase());
                File conf = new File(home, "conf");
                File propsFile = new File(conf, "catalina.properties");

学习之处:可以看到,第一步是判断有没有catalina.config 指定catalina.conf的配置路径,没有该-D参数才会使用tomcat/conf下的该配置。这个值得学习。

3、反射创建Catalina对象,并设置classLoader

 public void init() throws Exception {

        initClassLoaders();

        Thread.currentThread().setContextClassLoader(catalinaLoader);

        SecurityClassLoad.securityClassLoad(catalinaLoader);

        // Load our startup class and call its process() method
        if (log.isDebugEnabled())
            log.debug("Loading startup class");
        **Class startupClass = catalinaLoader.loadClass("org.apache.catalina.startup.Catalina");**
        Object startupInstance = startupClass.getConstructor().newInstance();

        // Set the shared extensions class loader
        if (log.isDebugEnabled())
            log.debug("Setting startup class properties");
        **String methodName = "setParentClassLoader";**
        Class paramTypes[] = new Class[1];
        paramTypes[0] = Class.forName("java.lang.ClassLoader");
        Object paramValues[] = new Object[1];
        paramValues[0] = sharedLoader;
        Method method =
            startupInstance.getClass().getMethod(methodName, paramTypes);
        method.invoke(startupInstance, paramValues);

        catalinaDaemon = startupInstance;

    }
3、设置Catalina对象为BootStrap的catalinaDaemon 成员变量
    private Object catalinaDaemon = null;  //catalinaDaemon 是Catalina对象,该对象的parentClassLoader 属性是sharedClassloader 也就是commonClassLoader

我们可以看到,其中的catalinaDaemon 的声明是Object类型的,降低了tomcat和Catalina的耦合,而且编译Bootstrap时不用提供Catalina的依赖。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/69683.html

相关文章

  • gulp——用自动化构建工具增强你的工作流程

    摘要:概念之前有写了,现在重新写感觉二者最终结果虽说相差无几,但是侧重点还是有所不同更偏向于工程化,侧重于项目的整个流程控制,你可以二者结合,也可以分开取舍都有利于前端项目的工程化构建安装全局安装作为项目的开发依赖安装在项目根目录下创建一 gulp概念 之前有写了webpack, 现在重新写gulp感觉二者最终结果虽说相差无几,但是侧重点还是有所不同 webpack更偏向于工程化,gulp侧...

    geekidentity 评论0 收藏0
  • swoft| 源码解读系列二: 启动阶段, swoft 都干了些啥?

    摘要:源码解读系列二启动阶段都干了些啥阅读框架源码了解启动阶段的那些事儿小伙伴刚接触的时候会感觉压力有点大更直观的说法是难开发组是不赞成难这个说法的的代码都是实现的而又是世界上最好的语言的代码阅读起来是很轻松的之后开发组会用系列源码解读文章深 date: 2018-8-01 14:22:17title: swoft| 源码解读系列二: 启动阶段, swoft 都干了些啥?descriptio...

    hqman 评论0 收藏0
  • swoft中Crontab定时器的坑

    摘要:我们项目使用的是框架,所以我就想到用框架的定时器。,以及的结构注在定时器这块使用到两个一个是用于存储任务的实例。 这两天老大给了个需求想把商城热点数据同步到redis缓存。我们项目使用的是swoft框架,所以我就想到用框架的Crontab定时器。但是在测试的时候发现把Table的size设置为1024时(实际上设置为任何大小都一样,贴上swoole的解释)发现内存溢出了 showImg...

    CarterLi 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<