3
votes

Before servlet 3.0, the servlet needs to be configured in the web.xml by providing url pattern and servlet class. Whenever request for the servlet is sent, tomcat search the servlet class in the web.xml and calls the doget or dopost based on type of the request. In servlet 3.0 we can configure servlet in servlet class itself using annotations like @WebServlet. My question is how tomcat identifies the the servlet class in this case as in web.xml there is no mapping specified for the servlet.

Thanks in Advance.

2
Try googling 'annotation scanning'Evan Knowles
By implementing Processor interface.Luiggi Mendoza
@LuiggiMendoza Is that invoked at runtime? I had understood it was a compile-only facility.chrylis -cautiouslyoptimistic-
@chrylis annotations can be processed at compile time (check project Lombok) or at runtime (like @WebServlet for servlets or @ManagedBean from JSF).Luiggi Mendoza

2 Answers

8
votes

Tomcat scans the web application for class files (both under WEB-INF/classes and in JARs). The class files are then passed to a heavily edited, package renamed local copy of the Apache Commons Byte Code Engineering Library (BCEL). Tomcat's version of BCEL is optimised to process only those parts of the byte code Tomcat is interested in (annotations, super class if any, implemented interfaces) and to skip over the rest as fast as possible. BCEL reads the class files directly from disk.

Tomcat does some careful caching of the results from BCEL so that even for the most complex of class hierarchies each class is only ever processed once and no post-processing is required to get the full list if annotations (including those inherited from super classes) for any class.

The annotation scan also checks for matches to the @HandlesTypes annotation for SCIs.

Scanning every class for annotations is expensive however you do it (and one of the reasons I'm not a fan of this particular feature). Tomcat's implementation went through several iterations before arriving at the efficient implementation it now uses.

5
votes

It scans all jar files under lib directory and class files in classes directory of your web application deployment, gets classes using code like clazz = Class.forName(theClassName), then calls clazz.getDeclaredAnnotations() or clazz.getAnnotation(WebServlet.class). Than it reads the annotation's attribute to extract the servlet mapping.

This way container finds all servlets, filters etc and their URL mappings. This is one of the reasons that when this annotation based API was introduced the application deployments takes more time.

Obviously the code is not as simple as I explained. It for example loads classes in context of proprietary class loader of the web application. It also does not really call Class.forName() but rather loads the class as byte array and passes it to the classloader.