`

从源码学spring一启动

阅读更多
       Jetty在启动时,先启动Server,调用jettyserver的父类 HandlerWrapper的dostart方法,启动handler,handler是一个HandlerWrapper,总共包含8个Handler,循环调用Handler的start方法,启动各个Handler。
        其中XX,负责解析webapp的基本信息,解析web.xml,并将信息保存到实体中。然后调用WebAppContext doStart 启动,  记载和调用在web.xml中解析并已经加载的所有Listener的contextInitialized 方法,启动listener。 
       本文分析的主要包括:webapp的解析和启动、请求的处理、权限的管理、jsp的解析。
(一)webapp的解析和启动包括:
  1.     webapp的解析和启动
  2.     Spring的启动和Bean的加载等
(二)请求的处理包括:
  1.     jetty如何处理请求,并转发到spring 
  2.     spring如何处理请求
(三)权限的管理包括:
  1.    jetty如何管理cookies和session
  2.    spring security如何管理权限
(四)jsp的解析
  1.    jsp如何转化为servlet
  2.    各个模板引擎是如何工作的
 

一、webapp的解析和启动

 
 服务启动时调用server的dostart方法,dostart方法调用父类HandlerWrapper的dostart方法,dostart方法启动Handler的,这个Handler是一个HandlerCollection,包含三个元素,循环启动三个Handler。
  1.  0 = {ContextHandlerCollection@3593} 
  2.  1 = {DefaultHandler@3633} 
  3.  2 = {RequestLogHandler@3634} 
        其中ContextHandlerCollection是部署的app,webapp目录下面有多少个war,就有多少个JettyWebAppContext元素,循环调用JettyWebAppContext的start方法启动app的部署和解析。

1、web.xml的解析    

     JettyWebAppContext 的类层次结构如下:
    JettyWebAppContext > WebAppContext > ServletContextHandler > ContextHandler > ScopeHandler > HandlerWrapper > AbstractHandlerContainer > AbstractHandler > AggregateLifeCycle >  AbstractLifeCycle 
 
protected void doStart() throws Exception {
        try {
            this._metadata.setAllowDuplicateFragmentNames(this.isAllowDuplicateFragmentNames());
            this.preConfigure();
            super.doStart();
            this.postConfigure();
            if(this.isLogUrlOnStart()) {
                this.dumpUrl();
            }
        } catch (Exception var2) {
            LOG.warn("Failed startup of context " + this, var2);
            this._unavailableException = var2;
            this.setAvailable(false);
            if(this.isThrowUnavailableOnStartupException()) {
                throw var2;
            }
        }
    }
 
dostart方法的调用堆栈如下:
at org.eclipse.jetty.webapp.StandardDescriptorProcessor.visitSessionConfig(StandardDescriptorProcessor.java:667)
at sun.reflect.NativeMethodAccessorImpl.invoke0(NativeMethodAccessorImpl.java:-1)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.eclipse.jetty.webapp.IterativeDescriptorProcessor.visit(IterativeDescriptorProcessor.java:85)
at org.eclipse.jetty.webapp.IterativeDescriptorProcessor.process(IterativeDescriptorProcessor.java:72)
at org.eclipse.jetty.webapp.MetaData.resolve(MetaData.java:366)
at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1240) ContextHandler的startContext方法
at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:717)
at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:494)
at org.mortbay.jetty.plugin.JettyWebAppContext.doStart(JettyWebAppContext.java:298) 
 
其中_configurations 包含如下:
0 = {MavenWebInfConfiguration@3811}
1 = {WebXmlConfiguration@3812}
2 = {MetaInfConfiguration@3813}
3 = {FragmentConfiguration@3814}
4 = {EnvConfiguration@3675}
5 = {PlusConfiguration@3815}
6 = {MavenAnnotationConfiguration@3816}
7 = {JettyWebXmlConfiguration@3817}
 
MavenWebInfConfiguration主要处理webinf目录和一些临时目录等相关的配置。
WebXmlConfiguration负责定位和解析web.xml配置文件。
MetaInfConfiguration负责解析jar包。
 
org.eclipse.jetty.webapp.WebAppContext.startContext最后负责启动所有的Listener,如果使用了Spring框架,此时会启动Spring的ContextLoaderListener。
0 = {ELContextCleaner@5759}
1 = {IntrospectorCleaner@5760}
2 = {LogbackConfigListener@5761}
3 = {SystemLoaderListener@5762}
4 = {OnlineInfoListener@5763}
 
在WebAppContext的启动过程中启动了SessionHandler。
at org.eclipse.jetty.server.session.HashSessionManager.doStart(HashSessionManager.java:92)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:64)
- locked <0x12c1> (a java.lang.Object)
at org.eclipse.jetty.server.session.SessionHandler.doStart(SessionHandler.java:123)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:64)
- locked <0x1287> (a java.lang.Object)
at org.eclipse.jetty.server.handler.HandlerWrapper.doStart(HandlerWrapper.java:95)
at org.eclipse.jetty.server.handler.ScopedHandler.doStart(ScopedHandler.java:115)
at org.eclipse.jetty.server.handler.ContextHandler.startContext(ContextHandler.java:763)
at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:249)
at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1242)
at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:717)
at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:494)
 
 

2、Spring的启动

 
第一步解析并把bean的定义加载到集合中,此时不会初始化bean,因为bean可能存在以来关系。
第二步分析bean的依赖关系.
第三步创建并加载bean
bean的解析和加载是一个递归的过程。
 
如果是XML的context配置,通过web.xml配置文件找到Spring的初始配置文件,并解析。包括外部文件、component-scan、bean的创建、资源的映射等的处理。
其中parseDefaultElement方法根据不同的类型进行不同的处理。

 

 
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics