Tomcat學(xué)習(xí)筆記之啟動分析(Server)(四)

前言

通過上面一篇關(guān)于生命周期的介紹,我們知道子類只要實(shí)現(xiàn)#initInternal()和#startInternal()方法即可。

initInternal()方法

protected void initInternal() throws LifecycleException {
        super.initInternal();
        //1. 初始化實(shí)用程序執(zhí)行程序
        reconfigureUtilityExecutor(getUtilityThreadsInternal(utilityThreads));
        //2. jmx相關(guān)
        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是設(shè)置進(jìn)去的。

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

createStartDigester()方法中可以看出,通過調(diào)用#Server.addService()方法設(shè)置了services:

public void addService(Service service) {
      //1. 設(shè)置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. 如果狀態(tài)是start、before_start、after_start則直接啟動service
            if (getState().isAvailable()) {
                try {
                    service.start();
                } catch (LifecycleException e) {
                    // Ignore
                }
            }
            //3. 將此屬性更改報(bào)告給感興趣的監(jiān)聽器
            support.firePropertyChange("service", null, service);
        }
    }

這里一般執(zhí)行到第二步狀態(tài)是NEW,所以不回去啟動service。

startInternal()方法

protected void startInternal() throws LifecycleException {
        //1. 通知所有的監(jiān)聽器CONFIGURE_START_EVENT狀態(tài)事件,通常發(fā)生在BEFORE_START_EVENT之后和START_EVENT之前
        fireLifecycleEvent(CONFIGURE_START_EVENT, null);
        //2. 設(shè)置容器狀態(tài)為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);
        }
    }

流程比較簡單,就不做介紹了。

總結(jié)

到這,Server也啟動完成了,下面進(jìn)入Service的啟動。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容