上善若水
          In general the OO style is to use a lot of little objects with a lot of little methods that give us a lot of plug points for overriding and variation. To do is to be -Nietzsche, To bei is to do -Kant, Do be do be do -Sinatra
          posts - 146,comments - 147,trackbacks - 0

          概述

          在Jetty中,所有XML文件的配置使用Descriptor來(lái)表達(dá),而對(duì)這些Descriptor的處理使用DescriptorProcessor來(lái)實(shí)現(xiàn)。


          Descriptor和DescriptorProcessor類圖



          Descriptor實(shí)現(xiàn)

          Descriptor可以表達(dá)一個(gè)*.tld文件(TldDescriptor)、一個(gè)/META-INF/web.xml文件(WebDescriptor),一個(gè)/org/eclipse/jetty/webapp/webdefault.xml(DefaultsDescriptor),一個(gè)/META-INF/web-fragment.xml文件(FragmentDescriptor),一個(gè)override-web.xml文件(OverrideDescriptor)。其中TldDescriptor在TagLibConfiguration的TagListener中查找并使用TldProcessor解析;WebDescriptor在WebXmlConfiguration的preConfigure中查找,并設(shè)置到MetaData的webXmlRoot字段中,并更新MetaData的ordering字段,其資源文件可以手動(dòng)設(shè)置WebAppContext的descriptor字段,或者未設(shè)置而使用META-INF/web.xml文件;DefaultsDescriptor也在WebXmlConfiguration的preConfigure中查找,并設(shè)置到MetaData的webDefaultsRoot字段中,并更新MetaData的ordering字段,其資源文件可以手動(dòng)設(shè)置WebAppContext中的defaultsDescriptor字段,或未設(shè)置而默認(rèn)使用/org/eclipse/jetty/webapp/webdefault.xml文件;OverrideDescriptor也在WebXmlConfiguration的preConfigure中查找,并設(shè)置到MetaData的webOverrideRoots集合中,并更新MetaData中的ordering字段,其資源文件可以手動(dòng)設(shè)置,如果未設(shè)置,則忽略;而FragmentDescriptor則是在FragmentConfiguration中的preConfigure中添加到MetaData的webFragmentResourceMap、webFragmentNameMap以及webFragmentRoots中,如果MetaData的ordering為null,且不為absolute,則更新ordering字段。

           

          每個(gè)Descriptor使用一個(gè)xml的Resource實(shí)例作為構(gòu)造函數(shù)構(gòu)建,并使用XmlParser將其解析成類DOM樹(shù),保存樹(shù)的root節(jié)點(diǎn)引用。

           

          除了TldDescriptor在TagLibConfiguration中已經(jīng)處理完成,其他的Descriptor使用StandardDescriptorProcessor以及PlusDescriptorProcessor來(lái)處理,其中StandardDescriptorProcessor在WebXmlConfiguration的configure方法中注冊(cè)到MetaData的descriptorProcessors集合中,而PlusDescriptorProcessor在PlusConfiguration的configure方法中注冊(cè)到MetaData中。并在MataData的resolve方法中使用注冊(cè)的DescriptorProcessor依次解析webDefaultsRoot、webXmlRoot、webOverrideRoots以及webFragmentRoots對(duì)應(yīng)的Descriptor實(shí)例。

          DescriptorProcessor實(shí)現(xiàn)

          DescriptorProcessor只有一個(gè)process方法,他遍歷傳入的Descriptor的所有Node,并對(duì)不同Node做相應(yīng)的處理。在IterativeDescriptorProcessor的采用了非常巧妙的實(shí)現(xiàn)方法,即使用一個(gè)visitors的Map,包含節(jié)點(diǎn)的tag到相應(yīng)處理方法的映射,因而在IterativeDescriptorProcessor的實(shí)現(xiàn)中,它遍歷Descriptor的節(jié)點(diǎn)樹(shù),對(duì)每個(gè)節(jié)點(diǎn)查找對(duì)應(yīng)的處理方法,并調(diào)用查找到的方法,其子類的實(shí)現(xiàn)只需要注冊(cè)這個(gè)visitors的Map,然后實(shí)現(xiàn)注冊(cè)的方法即可;為了增加可擴(kuò)展性,在解析前和解析后分別添加了start、end的插入點(diǎn)。

          如在StandardDescriptorProcessor中,注冊(cè)了如下幾個(gè)visitor方法:
          context-param => visitContextParam 向WebAppContext添加InitParam信息。

          display-name => visitDisplayName 向WebAppContext設(shè)置displayName屬性。
          servlet => visitServlet 向ServletHandler中添加一個(gè)新的ServletHolder,并配置其servlet-name、init-param、servlet-class、jsp-file、load-on-startup、security-role-ref、run-as、async-supported、enabled、multipart-config等信息;如果id設(shè)置為jsp,則會(huì)在InitParam中配置scratchdir、classpath參數(shù),以及為Jasper配置com.sun.appserv.jsp.classpath參數(shù),而在WebAppContext中為Jasper配置org.apache.catalina.jsp_classpath屬性;用于注冊(cè)org.apache.jasper.servlet.JspServlet;對(duì)jsp-file,設(shè)置其forcePath為該值。

          servlet-mapping=> visitServletMapping 配置ServletHandler中servlet-name對(duì)應(yīng)的ServletMapping信息。

          session-config => visitSessionConfig 設(shè)置SessionHandler中SessionManager的一些配置信息。

          mime-mapping => visitMimeMapping 設(shè)置WebAppContext中extension到mimeType的映射。

          welcome-file-list => visitWelcomeFileList 設(shè)置WebAppContext中的welcomeFiles。

          locale-encoding-mapping-list => visitLocaleEncodingList 設(shè)置WebAppContext中l(wèi)ocale到encoding的映射關(guān)系。

          error-page => visitErrorPage 設(shè)置ErrorPageErrorHandler中errorCode或exceptionType到location的映射關(guān)系。

          taglib => visitTagLib 設(shè)置taglib-uri到taglib-location的映射關(guān)系,即WebAppContext中taglib-uri是taglib-location的alias。

          jsp-config => visitJspConfig 將jsp-property-group下url-pattern映射到JspServlet中。

          security-constraint => visitSecurityConstraint 向SecurityHandler中添加ConstraintMapping。

          login-config => visitLoginConfig 向SecurityHandler中設(shè)置AuthMethod、RealmName屬性,以及對(duì)FORM方法的驗(yàn)證,設(shè)置login、error頁(yè)面的InitParam。

          security-role => visitSecurityRole 向SecurityHandler中注冊(cè)定義的role集合。

          filter => visitFilter 向ServletHandler注冊(cè)FilterHolder,并配置filter-name、filter-class、init-param、async-supported等信息。

          filter-mapping => visitFilterMapping 向ServletHandler注冊(cè)FilterMapping信息。

          listenr => visitListener 向WebAppContext注冊(cè)EventListener。

          distributable => visitDestributable 設(shè)置WebDescriptor的distributable屬性為true。

           

          在PlusDescriptorProcessor中,首先在其start方法中會(huì)向WebAppContext注冊(cè)InjectionCollection、LifeCycleCallbackCollection、RunAsCollection(該屬性在RunAsAnnotationHandler中使用)屬性,并且注冊(cè)了以下幾個(gè)visitor方法:
          env-entry => visitEnvEntry 向InjectionCollection添加Injection實(shí)例,其中jndiName為env-entry-name定義的值,valueClass為env-entry-type定義的類型,而targetClass、targetName為injection-target下的injection-target-class、injection-target-name中定義的值,每個(gè)injection-target生成一個(gè)Injection實(shí)例。同時(shí)將env-entry-value中定義的值綁定到j(luò)ava:com/env/<name>對(duì)應(yīng)的資源中。(Injection實(shí)例也可以使用@Resource注解注冊(cè),并在ResourceAnnotationHandler中解析)

          resource-ref => visitResourceRef 向InjectionCollection添加Injection實(shí)例,其中jndiName為res-ref-name,typeClass為res-type,并綁定該引用資源。

          resource-env-ref => visitResourceEnvRef 向InjectionCollection添加Injection實(shí)例,其中jndiName為resource-env-ref-name,typeClass為resource-env-ref-type,并綁定該env引用資源。

          message-destination-ref => visitMessageDestinationRef 向InjectionCollection添加Injection實(shí)例,其中jndiName為message-destination-ref-name,typeClass為message-destination-type,并綁定該message-destination引用資源。

          post-construct => visitPostConstruct 向LifeCycleCallbackCollection注冊(cè)一個(gè)PostConstructCallback,其targetClass由lifecycle-callback-class定義,而method由lifecycle-callback-method定義(該P(yáng)ostConstructCallback也可以使用@PostConstruct的Annotation方式注冊(cè),并在PostConstructAnnotationHandler中解析)。

          pre-destroy => visitPreDestroy 向LifeCycleCallbackCollection注冊(cè)PreDestroyCallback,其targetClass由lifecycle-callback-class定義,methodName由lifecycle-callback-method定義(該P(yáng)reDestroyCallback也可以使用@PreDestroy注解注冊(cè),并在PreDestroyAnnotationHandler中解析)。

           

          所有以上注冊(cè)的RunAsCollection、InjectionCollection、LifeCycleCallbackCollection都在PlusDecorator中使用,PlusDecorator類實(shí)現(xiàn)Decorator方法,在所有的decorate實(shí)現(xiàn)方法中,使用RunAsCollection向ServletHolder中注冊(cè)配置的roleName(感覺(jué)這里有bug,應(yīng)該是decorate一個(gè)Servlet而不是ServletHolder);使用InjectionCollection向Servlet、Filter、EventListener注入JNDI對(duì)應(yīng)的值;使用LifeCycleCallbackCollection調(diào)用所有注冊(cè)的PostConstruct方法。而在destroyServlet、Filter實(shí)例時(shí),使用LifeCycleCallbackCollection調(diào)用素有注冊(cè)的PreDestroy方法。

          posted on 2014-05-24 22:06 DLevin 閱讀(791) 評(píng)論(1)  編輯  收藏 所屬分類: Jetty

          FeedBack:
          # re: 深入Jetty源碼之DescriptorProcessor實(shí)現(xiàn)
          2014-05-26 11:51 | 手機(jī)賺錢網(wǎng)-手機(jī)賺錢軟件排行,手機(jī)賺錢平臺(tái)http://www.9izhuanqian.com
          手機(jī)賺錢網(wǎng)- 手機(jī)賺錢軟件排行,手機(jī)賺錢平臺(tái)http://www.9izhuanqian.com  回復(fù)  更多評(píng)論
            
          主站蜘蛛池模板: 商丘市| 普陀区| 洛阳市| 同江市| 紫阳县| 二连浩特市| 云浮市| 南郑县| 锦州市| 云霄县| 调兵山市| 临朐县| 江永县| 舞阳县| 寿光市| 金寨县| 闽清县| 石景山区| 皋兰县| 开江县| 宜春市| 宁蒗| 北流市| 四川省| 清丰县| 开原市| 台东市| 河南省| 舒城县| 平江县| 台南县| 武川县| 保山市| 图片| 太和县| 大新县| 吴忠市| 化隆| 红桥区| 容城县| 玛多县|