上善若水
          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來表達,而對這些Descriptor的處理使用DescriptorProcessor來實現。


          Descriptor和DescriptorProcessor類圖



          Descriptor實現

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

           

          每個Descriptor使用一個xml的Resource實例作為構造函數構建,并使用XmlParser將其解析成類DOM樹,保存樹的root節點引用。

           

          除了TldDescriptor在TagLibConfiguration中已經處理完成,其他的Descriptor使用StandardDescriptorProcessor以及PlusDescriptorProcessor來處理,其中StandardDescriptorProcessor在WebXmlConfiguration的configure方法中注冊到MetaData的descriptorProcessors集合中,而PlusDescriptorProcessor在PlusConfiguration的configure方法中注冊到MetaData中。并在MataData的resolve方法中使用注冊的DescriptorProcessor依次解析webDefaultsRoot、webXmlRoot、webOverrideRoots以及webFragmentRoots對應的Descriptor實例。

          DescriptorProcessor實現

          DescriptorProcessor只有一個process方法,他遍歷傳入的Descriptor的所有Node,并對不同Node做相應的處理。在IterativeDescriptorProcessor的采用了非常巧妙的實現方法,即使用一個visitors的Map,包含節點的tag到相應處理方法的映射,因而在IterativeDescriptorProcessor的實現中,它遍歷Descriptor的節點樹,對每個節點查找對應的處理方法,并調用查找到的方法,其子類的實現只需要注冊這個visitors的Map,然后實現注冊的方法即可;為了增加可擴展性,在解析前和解析后分別添加了start、end的插入點。

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

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

          servlet-mapping=> visitServletMapping 配置ServletHandler中servlet-name對應的ServletMapping信息。

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

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

          welcome-file-list => visitWelcomeFileList 設置WebAppContext中的welcomeFiles。

          locale-encoding-mapping-list => visitLocaleEncodingList 設置WebAppContext中locale到encoding的映射關系。

          error-page => visitErrorPage 設置ErrorPageErrorHandler中errorCode或exceptionType到location的映射關系。

          taglib => visitTagLib 設置taglib-uri到taglib-location的映射關系,即WebAppContext中taglib-uri是taglib-location的alias。

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

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

          login-config => visitLoginConfig 向SecurityHandler中設置AuthMethod、RealmName屬性,以及對FORM方法的驗證,設置login、error頁面的InitParam。

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

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

          filter-mapping => visitFilterMapping 向ServletHandler注冊FilterMapping信息。

          listenr => visitListener 向WebAppContext注冊EventListener。

          distributable => visitDestributable 設置WebDescriptor的distributable屬性為true。

           

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

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

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

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

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

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

           

          所有以上注冊的RunAsCollection、InjectionCollection、LifeCycleCallbackCollection都在PlusDecorator中使用,PlusDecorator類實現Decorator方法,在所有的decorate實現方法中,使用RunAsCollection向ServletHolder中注冊配置的roleName(感覺這里有bug,應該是decorate一個Servlet而不是ServletHolder);使用InjectionCollection向Servlet、Filter、EventListener注入JNDI對應的值;使用LifeCycleCallbackCollection調用所有注冊的PostConstruct方法。而在destroyServlet、Filter實例時,使用LifeCycleCallbackCollection調用素有注冊的PreDestroy方法。

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

          FeedBack:
          # re: 深入Jetty源碼之DescriptorProcessor實現
          2014-05-26 11:51 | 手機賺錢網-手機賺錢軟件排行,手機賺錢平臺http://www.9izhuanqian.com
          手機賺錢網- 手機賺錢軟件排行,手機賺錢平臺http://www.9izhuanqian.com  回復  更多評論
            
          主站蜘蛛池模板: 翁源县| 长海县| 离岛区| 霞浦县| 济源市| 彩票| 台北市| 金乡县| 如东县| 武强县| 固安县| 武乡县| 长海县| 南皮县| 云霄县| 调兵山市| 临武县| 德州市| 乡宁县| 西安市| 临高县| 东兰县| 黄山市| 青河县| 奉节县| 临颍县| 武清区| 灵川县| 商河县| 洪洞县| 县级市| 夏邑县| 乌恰县| 阜南县| 潮州市| 屏山县| 昌宁县| 花莲县| 共和县| 伊通| 永靖县|