在servlet 3.0之前,需要通过提供url模式和servlet类在web.xml中配置servlet。每当发送对servlet的请求时,tomcat都会在web.xml中搜索servlet类,并根据请求的类型调用doget或dopost。 在servlet 3.0中,我们可以使用@WebServlet之类的注释在servlet类本身中配置servlet。 我的问题是tomcat如何在这种情况下识别servlet类,因为在web.xml中没有为servlet指定映射。
先谢谢。
答案 0 :(得分:7)
Tomcat扫描Web应用程序中的类文件(在WEB-INF / classes和JAR中)。然后将类文件传递给Apache Commons Byte Code Engineering Library(BCEL)的经过大量编辑的包重命名的本地副本。 Tomcat的BCEL版本经过优化,只处理Tomcat感兴趣的字节代码部分(注释,超级类,如果有的话,实现了接口),并尽可能快地跳过其余部分。 BCEL直接从磁盘读取类文件。
Tomcat对BCEL的结果进行了一些仔细的缓存,因此即使对于最复杂的类层次结构,每个类只处理一次,如果注释(包括从super继承的那些注释)不需要后处理来获取完整列表任何班级的课程。
注释扫描还会检查与SCI的@HandlesTypes注释的匹配。
扫描每个类的注释是很昂贵的,但是你这样做(这也是我不喜欢这个特殊功能的原因之一)。在实现它现在使用的高效实现之前,Tomcat的实现经历了几次迭代。
答案 1 :(得分:5)
它扫描lib
目录下的所有jar文件和Web应用程序部署的classes
目录中的类文件,使用clazz = Class.forName(theClassName)
之类的代码获取类,然后调用clazz.getDeclaredAnnotations()
或clazz.getAnnotation(WebServlet.class)
。比它读取注释的属性以提取servlet映射。
这样容器可以找到所有servlet,过滤器等及其URL映射。这是引入基于注释的API时,应用程序部署需要更多时间的原因之一。
显然代码并不像我解释的那么简单。例如,它在Web应用程序的专有类加载器的上下文中加载类。它也没有真正调用Class.forName()
,而是将类加载为字节数组并将其传递给类加载器。