【问题标题】:how tomcat identifies servlet specified with the annotations?tomcat如何识别用注释指定的servlet?
【发布时间】:2014-07-09 17:01:32
【问题描述】:

在servlet 3.0 之前,需要在web.xml 中通过提供url 模式和servlet 类来配置servlet。每当发送对 servlet 的请求时,tomcat 都会在 web.xml 中搜索 servlet 类,并根据请求的类型调用 doget 或 dopost。 在 servlet 3.0 中,我们可以使用 @WebServlet 之类的注解在 servlet 类本身中配置 servlet。 我的问题是在这种情况下,tomcat 如何识别 servlet 类,因为在 web.xml 中没有为 servlet 指定映射。

提前致谢。

【问题讨论】:

  • 尝试谷歌搜索“注释扫描”
  • 通过实现Processor接口。
  • @LuiggiMendoza 是在运行时调用的吗?我知道这是一个只编译的工具。
  • @chrylis 注释可以在编译时(检查 Lombok 项目)或运行时处理(如 @WebServlet 用于 servlet 或 @ManagedBean 来自 JSF)。

标签: java tomcat servlets


【解决方案1】:

它会扫描您的Web应用部署的lib目录下的所有jar文件和classes目录下的类文件,使用clazz = Class.forName(theClassName)之类的代码获取类,然后调用clazz.getDeclaredAnnotations()clazz.getAnnotation(WebServlet.class)。然后它读取注释的属性以提取 servlet 映射。

容器通过这种方式查找所有 servlet、过滤器等及其 URL 映射。这也是引入此基于注解的 API 时应用程序部署需要更多时间的原因之一。

显然代码并不像我解释的那么简单。例如,它在 Web 应用程序的专有类加载器的上下文中加载类。它也没有真正调用Class.forName(),而是将类加载为字节数组并将其传递给类加载器。

【讨论】:

  • 感谢您的信息。您是否知道任何提供有关此详细信息的链接或书籍。
  • 表示注解被tomcat转成web.xml映射??
  • 不。即使您的非简单解释也大有可为。 Web 应用程序类加载器根本不参与加载过程。
  • @sumant.raj,注解用于提取从web.xml中提取的相同(或相似)信息
【解决方案2】:

Tomcat 扫描 Web 应用程序以查找类文件(在 WEB-INF/classes 和 JAR 中)。然后将类文件传递到经过大量编辑的包重命名的 Apache Commons Byte Code Engineering Library (BCEL) 本地副本。 Tomcat 的 BCEL 版本经过优化,只处理 Tomcat 感兴趣的字节码部分(注解、超类(如果有的话)、实现的接口),并尽可能快地跳过其余​​部分。 BCEL 直接从磁盘读取类文件。

Tomcat 对来自 BCEL 的结果进行了一些仔细的缓存,因此即使对于最复杂的类层次结构,每个类也只处理一次,并且如果注释(包括从 super 继承的那些)则不需要后处理来获取完整列表类)适用于任何类。

注释扫描还检查与 SCI 的 @HandlesTypes 注释是否匹配。

扫描每个类的注释是很昂贵的,但是你这样做(这也是我不喜欢这个特殊功能的原因之一)。 Tomcat 的实现在达到它现在使用的高效实现之前经历了多次迭代。

【讨论】:

  • 感谢托马斯提供更简短的信息。我在谷歌上浏览了很多帖子,但没有找到令人满意的描述。你知道我可以找到关于它的完整解释的任何文档吗?
  • 有意思……真不知道tomcat用的是BCEL而不是反射API来做注解解析。
  • @sumant.raj 它被称为 open 源是有原因的。你想要 org.apache.catalina.startup.ContextConfig 类。
猜你喜欢
  • 2017-09-09
  • 1970-01-01
  • 2021-03-15
  • 1970-01-01
  • 2012-07-25
  • 1970-01-01
  • 2021-06-22
  • 2014-05-24
  • 1970-01-01
相关资源
最近更新 更多