美文网首页
Tomcat学习笔记之启动分析(Server)(四)

Tomcat学习笔记之启动分析(Server)(四)

作者: 夏目手札 | 来源:发表于2019-05-07 21:49 被阅读0次

前言

通过上面一篇关于生命周期的介绍,我们知道子类只要实现#initInternal()和#startInternal()方法即可。

initInternal()方法

protected void initInternal() throws LifecycleException {
        super.initInternal();
        //1. 初始化实用程序执行程序
        reconfigureUtilityExecutor(getUtilityThreadsInternal(utilityThreads));
        //2. jmx相关
        register(utilityExecutor, "type=UtilityExecutor");

        // 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
        if (getCatalina() != null) {
            ClassLoader cl = getCatalina().getParentClassLoader();
            // Walk the class loader hierarchy. Stop at the system class loader.
            // This will add the shared (if present) and common class loaders
            while (cl != null && cl != ClassLoader.getSystemClassLoader()) {
                if (cl instanceof URLClassLoader) {
                    URL[] urls = ((URLClassLoader) cl).getURLs();
                    for (URL url : urls) {
                        if (url.getProtocol().equals("file")) {
                            try {
                                File f = new File (url.toURI());
                                if (f.isFile() &&
                                        f.getName().endsWith(".jar")) {
                                    ExtensionValidator.addSystemResource(f);
                                }
                            } catch (URISyntaxException e) {
                                // Ignore
                            } catch (IOException e) {
                                // Ignore
                            }
                        }
                    }
                }
                cl = cl.getParent();
            }
        }
        //3. 初始化所有的service
        for (int i = 0; i < services.length; i++) {
            services[i].init();
        }
    }

从上面可以看出#Server.init()方法主要初始化了所有的service,这里的services是在解析service.xml是设置进去的。

digester.addObjectCreate("Server/Service",
                                 "org.apache.catalina.core.StandardService",
                                 "className");
        digester.addSetProperties("Server/Service");
        digester.addSetNext("Server/Service",
                            "addService",
                            "org.apache.catalina.Service");

createStartDigester()方法中可以看出,通过调用#Server.addService()方法设置了services:

public void addService(Service service) {
      //1. 设置service的Server
      service.setServer(this);
        synchronized (servicesLock) {
            Service results[] = new Service[services.length + 1];
            System.arraycopy(services, 0, results, 0, services.length);
            results[services.length] = service;
            services = results;
            //2. 如果状态是start、before_start、after_start则直接启动service
            if (getState().isAvailable()) {
                try {
                    service.start();
                } catch (LifecycleException e) {
                    // Ignore
                }
            }
            //3. 将此属性更改报告给感兴趣的监听器
            support.firePropertyChange("service", null, service);
        }
    }

这里一般执行到第二步状态是NEW,所以不回去启动service。

startInternal()方法

protected void startInternal() throws LifecycleException {
        //1. 通知所有的监听器CONFIGURE_START_EVENT状态事件,通常发生在BEFORE_START_EVENT之后和START_EVENT之前
        fireLifecycleEvent(CONFIGURE_START_EVENT, null);
        //2. 设置容器状态为STARTING
        setState(LifecycleState.STARTING);

        globalNamingResources.start();

        //3. 启动services
        synchronized (servicesLock) {
            for (int i = 0; i < services.length; i++) {
                services[i].start();
            }
        }

        if (periodicEventDelay > 0) {
            monitorFuture = getUtilityExecutor().scheduleWithFixedDelay(
                    new Runnable() {
                        @Override
                        public void run() {
                            startPeriodicLifecycleEvent();
                        }
                    }, 0, 60, TimeUnit.SECONDS);
        }
    }

流程比较简单,就不做介绍了。

总结

到这,Server也启动完成了,下面进入Service的启动。

相关文章

网友评论

      本文标题:Tomcat学习笔记之启动分析(Server)(四)

      本文链接:https://www.haomeiwen.com/subject/yauogqtx.html