Jetty的启动过程

      Jetty 是一个轻量级的、开源的servlet容器,可以非常容易的嵌入到应用程序当中作为嵌入式服务器使用,下面我们从代码层面来看看它是如何启动的

     Jetty的启动从Server类的start()方法开始的,Server类继承了AbstractLifeCycle类,会首先执行AbstractLifeCycle的start()方法.方法如下:

     

    public final void start() throws Exception
    {
        synchronized (_lock)
        {
            try
            {
                if (_state == STARTED || _state == STARTING)
                    return;
                setStarting();//启动之前调用监听器
                doStart();//启动jetty
                Log.debug("started {}",this);
                setStarted();//启动之后调用监听器
            }
            catch (Exception e)
            {
                setFailed(e);
                throw e;
            }
            catch (Error e)
            {
                setFailed(e);
                 throw e;
            }
        }
    }

     doStart()方法在Server类中.如下:

       

      

    /* ------------------------------------------------------------ */
    protected void doStart() throws Exception
    {
        Log.info("jetty-"+_version);
        HttpGenerator.setServerVersion(_version);
        MultiException mex=new MultiException();
      
        for (int i=0;_realms !=null && i<_realms.length; i++)
        {
            if (_realms[i] instanceof LifeCycle)
                ((LifeCycle)_realms[i]).start();
        }

        Iterator itor = _dependentLifeCycles.iterator();
        while (itor.hasNext())
        {   
            try
            {
                ((LifeCycle)itor.next()).start(); 
            }
            catch (Throwable e) {mex.add(e);}
        }
        
        if (_threadPool==null)
        {
            QueuedThreadPool tp=new QueuedThreadPool();
            setThreadPool(tp);
        }
        
        if (_sessionIdManager!=null)
            _sessionIdManager.start();
        
        try
        {
            if (_threadPool instanceof LifeCycle)
                ((LifeCycle)_threadPool).start();
        } 
        catch(Throwable e) { mex.add(e);}
        
        try 
        { 
            super.doStart(); 
        } 
        catch(Throwable e) 
        { 
            Log.warn("Error starting handlers",e);
        }
        
        if (_connectors!=null)
        {
            for (int i=0;i<_connectors.length;i++)
            {
                try{_connectors[i].start();}
                catch(Throwable e)
                {
                    mex.add(e);
                }
            }
        }
        mex.ifExceptionThrow();
    }

      这里面启动了处理请求的线程和Session管理器,还有连接器,super.doStart()调用了HandlerWrapper类的doStart()方法,如下:

      

  protected void doStart() throws Exception
    {
        if (_handler!=null)
            _handler.start();
        super.doStart();
    }

  

      _handler.start()调用了AbstractLifeCycle的start()方法,同上面,AbstractLifeCycle里面的start()方法会调用

WebAppContext的doStart()方法,如下:

       

    protected void doStart() throws Exception
    {
        try
        {
            // 初始化四个类WebInfConfiguration,WebXmlConfiguration, JettyWebXmlConfiguration,TagLibConfiguration            
             loadConfigurations();

            for (int i=0;i<_configurations.length;i++)
                _configurations[i].setWebAppContext(this);

            // Configure classloader
            _ownClassLoader=false;
            if (getClassLoader()==null)
            {
                WebAppClassLoader classLoader = new WebAppClassLoader(this);
                setClassLoader(classLoader);//生成classloader加载应用的war
                _ownClassLoader=true;
            }

            if (Log.isDebugEnabled())//打印日志 
            {
                ClassLoader loader = getClassLoader();
                Log.debug("Thread Context class loader is: " + loader);
                loader=loader.getParent();
                while(loader!=null)
                {
                    Log.debug("Parent class loader is: " + loader); 
                    loader=loader.getParent();
                }
            }

            for (int i=0;i<_configurations.length;i++)
                _configurations[i].configureClassLoader();//WebInfConfiguration类加载war包的lib,classes目录
            getTempDirectory();
            if (_tmpDir!=null && !_isExistingTmpDir && !isTempWorkDirectory())
            {
                File sentinel = new File(_tmpDir, ".active");
                if(!sentinel.exists())
                    sentinel.mkdir();
            }

            super.doStart();

            if (isLogUrlOnStart()) 
                dumpUrl();
        }
        catch (Exception e)
        {
            //start up of the webapp context failed, make sure it is not started
            Log.warn("Failed startup of context "+this, e);
            _unavailableException=e;
            _unavailable = true;
        }
    }

    

    WebInfConfiguration类的configureClassLoader()方法如下:

    

    public  void configureClassLoader()
    throws Exception
    {
        //cannot configure if the context is already started
        if (_context.isStarted())
        {
            if (Log.isDebugEnabled()){Log.debug("Cannot configure webapp after it is started");}
            return;
        }

        Resource web_inf=_context.getWebInf();//生成临时目录将war拷过来

        // Add WEB-INF classes and lib classpaths
        if (web_inf != null && web_inf.isDirectory() && _context.getClassLoader() instanceof WebAppClassLoader)
        {
            // Look for classes directory
            Resource classes= web_inf.addPath("classes/");
            if (classes.exists())
                ((WebAppClassLoader)_context.getClassLoader()).addClassPath(classes.toString());

            // Look for jars
            Resource lib= web_inf.addPath("lib/");
            if (lib.exists() || lib.isDirectory())
                ((WebAppClassLoader)_context.getClassLoader()).addJars(lib);
        }
        
     }

    WebAppContext的start()方法里的 super.doStart()会调用ContextHandler的doStart()方法,方法如下:

  protected void doStart() throws Exception
    {
        if (_contextPath==null)
            throw new IllegalStateException("Null contextPath");
        
        _logger=Log.getLogger(getDisplayName()==null?getContextPath():getDisplayName());
        ClassLoader old_classloader=null;
        Thread current_thread=null;
        SContext old_context=null;

        _contextAttributes=new AttributesMap();
        try
        {
            
            // Set the classloader
            if (_classLoader!=null)
            {
                current_thread=Thread.currentThread();
                old_classloader=current_thread.getContextClassLoader();
                current_thread.setContextClassLoader(_classLoader);
            }
            

            if (_mimeTypes==null)
                _mimeTypes=new MimeTypes();
            
            old_context=(SContext)__context.get();
            __context.set(_scontext);
            
            if (_errorHandler==null)
                setErrorHandler(new ErrorHandler());
            
            startContext();
            
           
        }
        finally
        {
            __context.set(old_context);
            
            // reset the classloader
            if (_classLoader!=null)
            {
                current_thread.setContextClassLoader(old_classloader);
            }
        }
    }

    startContext()方法会调用WebAppContext类的startContext()方法,如下:

  

    protected void startContext()
        throws Exception
    {
        // Configure defaults
        for (int i=0;i<_configurations.length;i++)
            _configurations[i].configureDefaults();//调用WebXmlConfiguration类解析xml文件
        
        // Is there a WEB-INF work directory
        Resource web_inf=getWebInf();
        if (web_inf!=null)
        {
            Resource work= web_inf.addPath("work");
            if (work.exists()
                            && work.isDirectory()
                            && work.getFile() != null
                            && work.getFile().canWrite()
                            && getAttribute(ServletHandler.__J_S_CONTEXT_TEMPDIR) == null)
                setAttribute(ServletHandler.__J_S_CONTEXT_TEMPDIR, work.getFile());
        }
        
        // Configure webapp
        for (int i=0;i<_configurations.length;i++)
            _configurations[i].configureWebApp();

        
        super.startContext();
    }

 
super.startContext()调用父类Context的startContext()方法,如下:

    

    protected void startContext() throws Exception
    {
        super.startContext();//初始化xml里配置的listener
        
        // OK to Initialize servlet handler now
        if (_servletHandler != null && _servletHandler.isStarted())
            _servletHandler.initialize();//初始化xml里面配置的servlet
    }

      

猜你喜欢

转载自liudeh-009.iteye.com/blog/1663224