JSP 容器可插拔性
ServletContainerInitializer 和编程式注册特性可以在 Servlet 和JSP 容器之间提供一个清晰的职责分离,通过由 Servlet 容器只负责解析 web.xml 和 web-fragment.xml 资源,而解析标签库描述符(TLD)资源委托给 JSP 容器。
在此之前,web 容器必须扫描 TLD 资源寻找任何 Listener 声明。使用Servlet 3.0 和后续版本后,该职责可以委托给 JSP 容器。JSP 容器是内嵌到一个 Servlet3.0 兼容的 Servlet 容器中,可以提供它自己的ServletContainerInitializer 实现,搜索传递到它的 onStartup 方法的 ServletContext 参数寻找任何 TLD 资源,扫描这些资源寻找Listener 声明,并向 ServletContext 注册相关的 Listener。
另外,Servlet3.0 之前,JSP 容器用于必须扫描应用的部署描述符寻找jsp-config 相关的配置。使用 Servlet3.0 和后续版本后,Servlet 容器必须提供通过 ServletContext.getJspConfigDescriptor 方法得到应用的 web.xml 和 web-fragment.xml 部署描述符中的任何 jsp-config 相关的配置。
在 TLD 中发现的和编程注册的任何 ServletContextListener 在它们提供的功能上是有限的。任何试图调用一个在 Servlet3.0 中加入的ServletContext API 方法将导致一个UnsupportedOperationException。
另外,Servlet 3.0 和后续版本兼容的 Servlet 容器必须提供一个名字为javax.servlet.context.orderedLibs 的 ServletContext 属性,它的值(java.util.List