day12-Servlet02( 四 )


10.2注解方式是如何完成Servlet配置的?一个疑问:web.xml文件是通过dom4j来获取数据,然后进行反射 。那注解为什么也能进行Servlet的调用或者是初始化等操作的呢?它的原理是什么?

day12-Servlet02

文章插图
根据上图:Tomcat得到http请求的工作如下
详见Servlet01--浏览器调用Servlet流程分析
  1. 如果是注解的方式,就对包进行扫描,如果发现某个类是用@WebServlet注解过的,就说明该类是一个Servlet,就会读取@WebServlet的urlPatterns的值
  2. 看看浏览器请求的资源 /XxxServlet 有没有在包配置过
  3. 如果找到对应的urlPatterns,就会得到对应的servletname
  4. Tomcat维护了一个大的HashMap<id,Servlet>,查询该HashMap,看看有没有这个Servlet实例
  5. 如果没有查询到该servlet-name对应的id,即没有这个Servlet实例时
  6. 就去得到servlet类的全路径(之前扫描包的时候就可以获取全路径)
  7. 使用反射技术,将servlet实例化(同时调用init方法),并将该实例放入到Tomcat维护的HashMap<id,Servlet>中
注解方式开发Servlet和web.xml配置Servlet,本质上机制是一样的
不要同时配置注解和web.xml 。即不要配置了该Servlet的web.xml,又在该Servlet类上添加注解
下面模拟一下Tomcat是如何通过@WebServlet(urlPatterns = {"/ok1", "/ok2"})来装载一个Servlet的:
反射+注解+IO+集合
package com.li.servlet.annotation;import javax.servlet.annotation.WebServlet;import java.util.HashMap;/** * 模拟一下Tomcat是如何通过@WebServlet(urlPatterns = {"/ok1", "/ok2"}) * 来装载一个Servlet的 */public class TestAnnotationServlet {private static final HashMap<String, Object> hm = new HashMap<>();public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {//1.首先要得到扫描的包 路径(IO),进而得到类的全路径(如何扫描包的过程暂时略过)String classAllPath = "com.li.servlet.annotation.OkServlet";//2.得到OkServlet的class对象Class<?> aclass = Class.forName(classAllPath);//3.通过class对象,得到annotationWebServlet annotation = aclass.getAnnotation(WebServlet.class);//4.获取annotation的属性System.out.println(annotation);String[] strings = annotation.urlPatterns();for (String url : strings) {System.out.println("url=" + url);}//如果匹配url,如果是第一次请求tomcat,tomcat就会创建一个OkServlet实例,放入HashMap中Object instance = aclass.newInstance();System.out.println(instance);//instance就是一个OkServlet的实例对象//简单地模拟hm.put("OkServlet", instance);System.out.println(hm);//如果是第二次及以后请求tomcat,就会直接去HashMap中去查找OkServlet的实例对象}}10.3@WebServlet注解参数说明我们可以根据@interface WebServlet 源码知道可以配置哪些信息
http://c.biancheng.net/servlet2/webservlet.html
10.4Servlet urlPattern配置【day12-Servlet02】

经验总结扩展阅读