如何禁用Servlet 3.0扫描和自动加载组件

我们有一个应用程序,它继续从我们的第三方库中加载ServletContainerInitializer的实例。

一个实例是JerseyServletContainerInitializer,另一个是SpringServletContainerInitializer。 来自Jersey和Spring的这些类似乎“接管”了我们的servlet上下文,弄乱了我们的映射和filter等等。

我们确实需要显式配置我们的servlet容器的web.xml,这种自动扫描让我们疯狂。 通过简单地在pom.xml中引入依赖项,我们的运行时ServletContext配置(如Servlets / Filters / ContextListeners)会发生变异,因为servlet容器会在类路径中找到这些库。

有没有办法使用Servlet 3但禁用其恼人的自动类路径扫描“function”?

来自https://wiki.apache.org/tomcat/HowTo/FasterStartUp

可以在WEB-INF / web.xml文件中指定两个选项:

  • 元素上设置metadata-complete =“true”属性。
  • 添加一个空的元素。

设置metadata-complete =“true”将禁止扫描Web应用程序及其库,以查找使用注释定义Web应用程序组件(Servlet等)的类。 元数据完成选项不足以禁用所有注释扫描。 如果存在带有@HandlesTypes注释的SCI,则Tomcat必须扫描应用程序以查找使用该注释中指定的注释或接口的类。

元素指定必须扫描哪些Web片段JAR(根据其WEB-INF / web-fragment.xml文件中的名称)的SCI,片段和注释。 空元素配置不扫描任何元素。

在Tomcat 7中,绝对排序选项会影响Web应用程序提供的SCI和容器提供的SCI(即$ CATALINA_HOME / lib中的库)的发现。 在Tomcat 8中,该选项仅影响Web应用程序,而无论绝对排序如何,始终会发现容器提供的SCI。 在这种情况下,单独的绝对排序选项不会阻止扫描注释,但是要扫描的JAR列表将为空,因此扫描将很快完成。 无论绝对排序如何,始终扫描WEB-INF / classes中的类。

扫描Web应用程序资源和TLD扫描不受这些选项的影响。

有关Servlet 3.1规范的绝对排序的规范声明,请参见第8.2.2节“web.xml和web-fragment.xml的排序”,第1.d部分:

元素可以包含零个或一个元素。 此元素所需的操作如下所述。 如果元素不包含元素,则必须忽略元素中未特别提及的任何Web片段。 不会对已注释的servlet,filter或侦听器扫描排除的jar。 但是,如果web.xml中列出了来自排除jar的servlet,filter或侦听器或非排除的web-fragment.xml,则除非被me​​tadata-complete排除,否则将应用注释。

关键的一点是,使用空的绝对排序元素不仅会关闭servlet-container初始值设定项的扫描。 扫描所有定义注释的组件(例如@WebServlet)将被关闭。 如果您确实要关闭Web应用程序中JAR文件的所有注释处理,则建议使用空的绝对排序元素。

可以更精细地调整扫描:使用绝对排序元素,并包括要使用名称元素扫描的JAR的名称,并省略您希望跳过的JAR。 不要使用其他元素,因为这将返回到未明确列出的所有JAR的排序,并将为这些JAR重新开启扫描。

作为一般惯例,我们发现关闭所有注释处理是危险的,因为启用注释扫描的Web应用程序具有必须扫描的一些类,这意味着完全关闭扫描会破坏Web应用程序。

我发现这两个答案都没有奏效。

从类路径中实际过滤掉第三方SCI的唯一方法是Context容器的containerSciFilter属性(在context.xml ),定义为

指定哪个容器提供的SCI应该被过滤掉而不用于此上下文的正则表达式。 匹配使用java.util.regex.Matcher.find(),因此正则表达式只需要匹配提供SCI的容器的完全限定类名的子字符串,以便将其过滤掉。 如果未指定,则不应用过滤。

在我的情况下,我想过滤掉像org.eclipse.jetty.apache.jsp.JettyJasperInitializer这样的东西,所以我用