tomcat源码解读之初始化过程

之前我拜读了《How Tomcat Works》这本书,对tomcat的架构与里面的实现有了一定的了解,现在借着tomcat的源码来深入了解这个精巧的艺术品。
首先从初始化开始,

 getServer().init();

前面类加载的过程与digester读取xml文件的过程我先跳过,直接来看tomcat是怎么初始化的。

  1. 在Catalina的load函数中,调用了上述的语句,获取server并调用init()方法。
    图1:standardServer继承关系图
    2.由上图的继承关系可以看出来,调用init()方法就会调用其祖先LifecycleBase的init()方法:
public final synchronized void init() throws LifecycleException {
        // 1
        if (!state.equals(LifecycleState.NEW)) {
            invalidTransition(Lifecycle.BEFORE_INIT_EVENT);
        }
        // 2
        setStateInternal(LifecycleState.INITIALIZING, null, false);

        try {
            // 模板方法
            /**
             * 采用模板方法模式来对所有支持生命周期管理的组件的生命周期各个阶段进行了总体管理,
             * 每个需要生命周期管理的组件只需要继承这个基类,
             * 然后覆盖对应的钩子方法即可完成相应的声明周期阶段的管理工作
             */
            initInternal();
        } catch (Throwable t) {
        ...
        }

        // 3
        setStateInternal(LifecycleState.INITIALIZED, null, false);
    }

3.这个init()方法,先将状态设置为正在初始化,然后调用initInternal()方法,这个方法很有意思,这是个抽象方法,然后因为standardServer这个子类实现了这个方法,并且之前是getServer.init(),根据java多态的原则,就会调用standardServer的initInternal()方法

protected void initInternal() throws LifecycleException {
        
        super.initInternal();

        // Register global String cache
        // Note although the cache is global, if there are multiple Servers
        // present in the JVM (may happen when embedding) then the same cache
        // will be registered under multiple names
        onameStringCache = register(new StringCache(), "type=StringCache");

        // Register the MBeanFactory
        MBeanFactory factory = new MBeanFactory();
        factory.setContainer(this);
        onameMBeanFactory = register(factory, "type=MBeanFactory");
        
        // Register the naming resources
        globalNamingResources.init();
        
        // Populate the extension validator with JARs from common and shared
        // class loaders
    ...
   
        // Initialize our defined Services
        for (int i = 0; i < services.length; i++) {
            services[i].init();
        }
    }

4.这个方法的第一行 super.initInternal();调用了其父类的initInternal()方法,根据上面的继承关系图可以看出,这调用的是LifecycleMBeanBase的initInternal()方法

 protected void initInternal() throws LifecycleException {
        
        // If oname is not null then registration has already happened via
        // preRegister().
        if (oname == null) {
            mserver = Registry.getRegistry(null, null).getMBeanServer();
            
            oname = register(this, getObjectNameKeyProperties());
        }
    }

5.这个方法很简洁,作用就是将容器注册到MBeanServer里面,便于管理
6.然后回到standardServer的initInternal方法,接下来就是注册MBeanFactory,初始化NamingResources这一系列的动作
7.然后standardServer就会去初始化底下的service

for (int i = 0; i < services.length; i++) {
            services[i].init();
        }

8.然后又回到我们熟悉的节奏了,调用services的init()方法,这里自然地调到LifecycleBase的init()方法
9.LifecycleBase方法中的模板方法随后就调了standardService中的initInternal()方法:

 protected void initInternal() throws LifecycleException {

        super.initInternal();
        
        if (container != null) {
            container.init();
        }

        // Initialize any Executors
        for (Executor executor : findExecutors()) {
            if (executor instanceof LifecycleMBeanBase) {
                ((LifecycleMBeanBase) executor).setDomain(getDomain());
            }
            executor.init();
        }

        // Initialize our defined Connectors
        synchronized (connectors) {
            for (Connector connector : connectors) {
                try {
                    connector.init();
                } catch (Exception e) {
                    String message = sm.getString(
                            "standardService.connector.initFailed", connector);
                    log.error(message, e);

                    if (Boolean.getBoolean("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE"))
                        throw new LifecycleException(message);
                }
            }
        }
    }

10.这里与standardServer很像,第一步都钓了父类也就是LifecycleMBeanBase的initInternal方法,将standardService注册到了MBeanServer中,接着,调用了container.init()
11.从继承关系图中可以看到containerBase是standardEngine、standardContext、standardHost、standardWrapper的父类是LifecycleMBeanBase的子类,这也就意味着,会先调用LifecycleBase的init()方法,然后就先后调用containerBase与standardEngine的initInternal方法,并且在途中都会将自己注册到MBeanServer中
12.初始化完容器,接下来初始化connector,在初始化connector途中会对mapperListener进行初始化

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值