在设置metadata-complete="true"后(解决了Tomcat 7启动缓慢的问题),如何处理注释?

43

看起来Tomcat 7启动缓慢问题可以通过在web.xml中设置"metadata-complete"为"true"来解决,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<web-app metadata-complete="true" id="WebApp_ID" version="3.0"...

问题在于Tomcat在启动时会扫描注解,这会显著减慢启动速度。我的时间从25秒缩短到了5秒。(更多信息请参见:Tomcat and Servlet 3.0 Web Configuration

然而,我的代码中有一些注解,例如:

@ManagedBean
@RequestScoped
@Override
...

我很困惑 - 在设置了metadata-complete ="true"之后,我的代码还能正常工作吗?我必须删除注释并将所有内容移动到web.xml中吗?

2个回答

74

缓慢的启动是因为在/WEB-INF/lib中的每个JAR文件中的每个类文件也会被扫描以查找Servlet 3.0特定的注释。您显然有许多(大型)JAR文件在/WEB-INF/lib中。

metadata-complete="true"表示不需要扫描/WEB-INF/lib中的JAR文件以查找Servlet 3.0特定的注释,但仍将扫描Web应用程序自己的类。

请注意,您列出了两个JSF注释和一个Java SE注释,但没有任何Servlet 3.0注释。Servlet 3.0注释在javax.servlet.annotation包中列出。只有当JAR文件包含JSF 2.0兼容的/META-INF/faces-config.xml文件时,JSF才会扫描注释。它不会立即扫描每个JAR文件中的每个类。Java SE的@Override注释不是运行时注释,而只是编译时的辅助功能。

另请参阅:


2
非常感谢 - 我错过了只有JAR文件不会被扫描注释的部分(直到现在我认为metadata-complete="true"也会影响Web应用程序的类)。 - NSPKUWCExi2pr8wVoGNk
@mattblang:自定义标签/组件库中的JSF工件将不再自动注册。在适用的情况下,您需要显式地注册它们。 - BalusC
@BalusC 再次感谢您分享您的知识。 - Edward J Beckett
@BalusC - Servlet容器通过扫描jar文件中的注释和web-fragment.xml来做什么?如果在添加metadata-complete=true后应用程序仍然可以正常工作,这是否意味着该标记只会导致类的懒加载和初始化? - Andy Dufresne
在我的情况下(我使用的是Tomcat 7),metadata-complete="true" 关闭了 /WEB-INF/lib/WEB-INF/classes 中的注解扫描。特别是它关闭了已注册的监听器、过滤器和servlet上的 @Resource 注解扫描。 - Pavel S.
显示剩余6条评论

15

以下是Java Servlet 3.0 / 3.1规范的相关内容:

Web应用程序部署描述符包含web-app元素上的metadata-complete属性。metadata-complete属性定义了web.xml描述符是否完整,或者是否应考虑部署过程中使用的其他元数据来源。元数据可以来自web.xml文件、web-fragment.xml文件、WEB-INF/classes中类文件的注释以及WEB-INF/lib目录中jar文件中的类的注释。如果metadata-complete设置为"true",则部署工具仅检查web.xml文件,并且必须忽略应用程序类文件中存在的注释,例如@WebServlet、@WebFilter和@WebListener,还必须忽略任何打包在WEB-INF/lib中的jar文件中的web-fragment.xml描述符。如果未指定metadata-complete属性或将其设置为"false",则部署工具必须根据先前指定的方式检查类文件和web-fragment.xml文件中的元数据。
为了优化Tomcat的启动时间,需要使用metadata-complete="true",并将每个Servlet或Filter或Listener放入部署描述符中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接