tomcat分析之server

本文详细解析了Tomcat Server的分析步骤,从Server接口的init()方法到其实现类StandardServer的initInternal()和startInternal()。重点讨论了initInternal中的组件初始化,如全局字符串缓存、MBeanFactory、Service的初始化等。startInternal()则涵盖了状态变更、全局命名资源启动和服务启动等关键操作。通过对这些步骤的深入理解,揭示了Tomcat Server启动的核心逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

分析Server的步骤

关于分析Server自然不能是全文把每一个函数都看一遍,具体的分析思路是根据执行步骤去按照逻辑的顺序来一点一点分析。所以其实分析Server应该从之前讲的catlina的执行流程中开始分析。
在讲解catlina的时候其中说过Server.init()。但是在Server接口中其实是没有定义init(),这个方法其实是在它的父类接口中定义的。而init()的实际操作其实是在他的实现类中StandardServer.initInternal(),至于为什么是initInternal而不是init(),这是相关的代码
LifecycleBase.init()

    @Override
    public final synchronized void init() throws LifecycleException {
        if (!state.equals(LifecycleState.NEW)) {
            invalidTransition(Lifecycle.BEFORE_INIT_EVENT);
        }

        try {
            setStateInternal(LifecycleState.INITIALIZING, null, false);
            initInternal();
            setStateInternal(LifecycleState.INITIALIZED, null, false);
        } catch (Throwable t) {
            handleSubClassException(t, "lifecycleBase.initFail", toString());
        }
    }

也就是说调用init(),实质上是在调用initInternal,至于为啥是在LifecycleBase中定义,是由于LifecycleBase是Lifecycle的默认实现类,而Lifecycle其实是tomcat中来定义生命周期的一个接口。(Lifecycle相关的知识会专门写一个博客的)
而关于start方法其实也是一样的,相关的操作也是在StandardServer.startInternal中。
所以就开始分析StandardServer这个类吧。

StandServer.initInternal

@Override
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
    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 | IOException e) {
                            // Ignore
                        }
                    }
                }
            }
            cl = cl.getParent();
        }
    }
    // Initialize our defined Services
    for (Service service : services) {
        service.init();
    }
}

1,对父类的初始化

@Override
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());
    }
}

代码相对简单,其实就是对ManabedBean的进行一次注册。
2,注册全局的字符串缓存
3,注册MBeanFactory
4,globalNamingResources.init()
(用于注册资源的命名)
5,利用来自common和shared的类加载器的jars进行扩展校验
6,初始化service
(这才是重点,一个server可以初始化多个service,这部分也会单独拿出来分析)

注: Service:Service是包含Connector和Container的集合,Service用适当的Connector接收用户的请求,再发给相应的Container来处理。
关于Service,Connector和Container的相关知识后面都会有所介绍。

StandServer.startInternal()

    @Override
    protected void startInternal() throws LifecycleException {

        fireLifecycleEvent(CONFIGURE_START_EVENT, null);
        setState(LifecycleState.STARTING);

        globalNamingResources.start();

        // Start our defined Services
        synchronized (servicesLock) {
            for (Service service : services) {
                service.start();
            }
        }
    }

1,执行 fireLifecycleEvent函数
(这是一个处理lifecycleEvent时间的方法,在LifecycleBase中定义)
2,将状态设置为STARTING
3,globalNamingResources.start()
4,开始执行service
(也是server,start()的核心步骤)

由此对于 server的分析也就告一段落

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值