the Servlet Specification 之 annotations 和 pluggability

                                              annotations 和 pluggability



8.2    Pluggability(可插拔性)

8.2.1   Modularity of  web.xml(web.xml文件的模块)

             使用上述定义的注解充分使用了web.xml的选择性。然而不管是重写默认值或者通过注解设置值,要使用部署描述符。像之前,如果metadata-complete元素在web.xml描述符中设置为true,类文件的注解和jars包中的web片段将不会执行。其适用于这个应用程序的所有元数据通过web.xml描述符指定。

           

            为了更好地可插拔性和更少的配置,在Servlet 3.0规范中我们设计了web模块部署描述符片段。一个web片段是web.xml的部分或者全部,能够指定和包含一个库或者框架jar包的META-INF目录。WEB-INF/lib目录下,没有web-fragment.xml文件的jar包也被认为是一个分片。一些其中指定的注解将通过规则处理。容器将获取并使用这些配置作为下面定义的规则。


            一个web片段是web应用程序的逻辑分区,以这种方式web应用程序中使用的框架能够定义所有的工件而不需要开发者在这个web.xml文件中编辑或增加信息。它能包含web.xml描述符使用的所有元素。然而描述符的最高级别元素是web-fragment并且相对应的描述符文件必须称为web-fragment.xml文件。web.xml和web-fragment.xml文件中相关元素的排序也是不同的。

 

           如果一个框架打包成jar文件并且在部署描述符中有元数据信息,那么web-fragment.xml必须在jar文件的META-INF目录下。

 

           如果一个框架想其META-INF/web-fragment.xml以这种方式执行,那么将扩充web应用程序的web.xml。框架必须捆绑在web应用程序的WEB-INF/lib目录下。为了使框架中其他类型的资源文件能够被web应用程序访问,使框架在web应用程序的类加载器委托链中随时随地可用是很重要的。换句话说,只有绑定在web应用程序WEB-INF/lib目录下的JAR文件,而不是在类加载器委托链中的那些,需要扫描web-fragment.xml。


           在部署期间,容器负责扫描本地和发现web-fragment.xml并处理它们。对于一个单一web.xml,当前存在的命名唯一性的要求也适用于一个web.xml的联合和所有适用的web-fragement.xml文件。


          下面是包含了一个库或者框架的例子:

          

<web-fragment>
     <servlet>
         <servlet-name>welcome</servlet-name>
         <servlet-class>
             WelcomeServlet
         </servlet-class>
      </servlet>
      <listener>
         <listener-class>
            RequestListener
         </listener-class>
      </listener>
</web-fragment>



         上述的web-fragment.xml文件将会位于框架jar文件的META-INF/目录下。在web-fragment.xml和注解中的配置顺序是没有定义的。如果顺序很重要,则请看下面的如何获取期望顺序的定义规则。

        

8.2.2   Ordering of web.xml and web-fragment.xml(web.xml和web-fragment.xml的排序)

                由于规范允许应用程序配置资源可以由多个配置文件组成(web.xml和web-fragment.xml文件),从一个应用程序不同的部分发现和加载的排序问题就出来了。这部分指定了配置资源如何申明这些文件的顺序需求。

              

                一个web-fragment.xml文件可能有一个javaee:java-identifierType类型的顶级<name>元素,也可以仅有一个。如果存在一个<name>元素,必须考虑各个组件的排序(除非多命名异常适用,如下所述)


             必须考虑两种情况,允许应用程序配置资源设置排序优先权。

             

             1  绝对排序:web.xml中的<absolute-ordering>元素。只能有一个<absolute-ordering>元素

                 a.   在这种情况下,排序优先由下面情况处理的必须忽略

                 b.   在absolute-ordering元素中列出的web-fragments处理前,必须先处理web.xml

                 c.   <absolute-ordering>的任何<name>元素的直接子元素必须解释成来指定命名web片段的绝对排序,可能有或者没有,必须被处理。

                 d.   <absolute-ordering>元素可能包含0个或者1个<others />元素。这个元素的请求操作如下描述。如果这个<absolute-ordering>元素不包含一个<others/>元素,任何没有在<name/>元素中特别指定的web-fragment必须被忽略。     对于添加了注解的servlets,过滤器或者监听器不扫描已排除jar。然而,如果来自已排除jar中的servlets,过滤器或者监听器存在于web.xml或者在一个非已排除的web-fragment.xml中,稍后将使用注解除非从metadata-complete中移除。在已移除jar的TLD文件中发现的ServletContextListeners不能使用程序化APIs配置过滤器和servlets。任何尝试这样做的将引发一个IllegalStateException异常。如果从一个已经移除的jar中加载ServletContainerInitializer,将被忽略。由ServletContainerInitializer处理的类不扫描已排除jars。

                e.   重复命名异常:当遍历<absolute-ordering>的子元素时,遇到有相同<name>元素的多个子元素时,只考虑第一个元素。

2 相对排序:由web-fragment.xml中的<ordering>元素指定。有且仅有一个<ordering>元素。

                a.  web-fragment.xml可能仅有一个<ordering>元素。如果这样,这个元素必须包含零个或一个<before>元素和零个或一个<after>元素。这些元素代表的意思在下面解释。

                b. 重复命名异常:如果,当遍历web-fragments时,遇到有相同<name>元素的多个成员时,应用程序必须记录一个信息错误消息,其包括了帮助修复问题的信息,并且部署失败。例如,修复这个问题的一种方式是使用绝对排序,在这种情况下忽略相对路径。

                c. 考虑下面的例子,有三个web-fragments -MyFragment1, MyFragment2 和 MyFragment3,这三个也是web.xml的一部分。

web-fragment.xml
<web-fragment>
<name>MyFragment1</name>
<ordering><after><name>MyFragment2</name></after></ordering>
...
</web-fragment>
web-fragment.xml
<web-fragment>
<name>MyFragment2</name>
..
</web-fragment>
web-fragment.xml
<web-fragment>
<name>MyFragment3</name>
<ordering><before><others/></before></ordering>
..
</web-fragment>
web.xml
<web-app>
...
</web-app>

在这个例子中,处理顺序如下:

web.xml
MyFragment3

MyFragment2
MyFragment1


处理顺序一般遵循以下原则:

<before>表示这个文档必须排序在这个文档中匹配<name>元素名字的文档的前面

<after>   表示这个文档必须排在这个文档中匹配<name>元素名字的文档的后面

有一个特殊元素<others/>,在<before>和<after>中可能包含零个或者一个,或者在<absolute-ordering>元素内有零个或一个。<others/>元素必须处理如下:


  •  如果<before>元素包含一个内嵌的<others/>,这个文档将被移到排序文档列表的前端。如果有重复的<before><others/>这样标签的文档,它们将全部在排序文档的前端,但是文档内部的排序是未指定的
  • 如果<after>元素包含了一个内嵌的<others/>,文档将被移到排序文档列表的末端。如果有多个文档需要<after><others/>,它们就都将在排序文档的末端,但是文档内部组不指定排列顺序。
  • 在一个<before/>或者<after/>元素内部,如果有一个<other>元素,但是了<others/>不是其父元素中唯一的<name>元素,父元素的其他元素必须考虑排序处理。
  • 如果如果<others/>元素出现在<absolute-ordering>元素内部,运行期必须确保不在<absolute-ordering>区域内显示命名的web-fragments包含了处理顺序的那个点上。
  • 如果web-fragment.xml文件没有<ordering>或者web.xml没有一个<absolute-ordering>元素,artifacts假定没有任何排序依赖。
  • 如果运行期发现了循环依赖,一定要记录提示消息,应用程序必将部署失败。使用者可能采取的措施是在web.xml中使用绝对路径
  • 前面的例子可以扩展为说明web.xml中有排序的情况。

web.xml
<web-app>
<absolute-ordering>
<name>MyFragment3</name>
<name>MyFragment2</name>
70 Java Servlet Specification • November 2009
</absolute-ordering>
...
</web-app>



  在这个例子中,对于不同的元素,顺序是:

web.xml
MyFragment3
MyFragment2

下面还有其他的例子。所有的这些全是相对排序而不是绝对排序。

Document A:
<after>
<others/>
<name>
C
</name>
</after>
Document B
<before>
<others/>
</before>
Document C:
<after>
<others/>
</after>

Document D: no ordering
Document E: no ordering
Document F:
<before>
<others/>
<name>
B
</name>
</before>


解析顺序:

web.xml, F, B, D, E, C, A.





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值