java吧 关注:1,249,419贴子:12,730,947
  • 1回复贴,共1

Servlet执行原理Filter执行原理

只看楼主收藏回复

  web容器存在两个Map
  这两个Map的key均为Servlet注册时的<url-parrent>
  但value的值不同
  第一个Map的key的value的值是Servlet实例对象的引用
  第二个Map的key的value的值是为<filter-class>的值
  为Servlet的全限定类名
  Servlet执行原理:
  当对Servlet的请求达到Servlet容器时,会先对请求进行解析
  使用解析出的uri作为比较对象
  uri就是<url-parrent>的值 比如 /SomeServlet
  然后从第一个Map里面找有没有key的值等于/SomeServlet
  没找到
  说明SomeServlet这个对象还没创建 第一个Map的key是<url-parrent>的值 比如 /SomeServlet
  value是SomeServlet实例对象
  没找到就要创建
  然后去第二个Map里面找key的值等于/SomeServlet
  就找到了 其value的值为 SomeServlet的全限定名
  读取这个vaulue的值 com.atuguigu.servlet.SomeServlet
  利用反射 ClassForName("com.atuguigu.servlet.SomeServlet").newInstance();
  创建SomeServlet对象
  再将key=/SomeServlet
  value=创建好的SomeServlet对象
  放到第一个Map中
  一会又来了一个请求 请求SomeServlet
  去第一个Map里面找key的值等于/SomeServlet
  就找到了 value的值为SomeServlet实例化对象
  ================================================
  Filter创建时机不一样
  Servlet是访问的时候创建
  Filter是容器启动后就创建
  所以Filter不存在第二个Map
  Filter存在一个数组和一个Map
  一个Map:key的值Filter在web.xml注册信息的<url-parrent>的值
  也就是Filter过滤的路径
  value为Filter实例对象的引用
  一个数组:存放与请求所匹配的所有的Filter对象 也就是过滤规则一致的Filter对象
  这个属租的元素就是Filter对象
  执行原理:
  当对Servlet的请求达到Servlet容器时,先对请求进行解析
  使用解析出的uri作为比较对象
  uri就是<url-parrent>的值 比如 /SomeServlet
  然后从第一个Map里面找有没有key的值等于/SomeServlet
  若存在 读取其value,即Filter的对象的引用,将该引用存入到数组里面
  因为Filter是容器启动后就创建
  肯定能找到
  然后继续向后查找,直到将该Map的key查找完毕
  这样就会在数组中存在,按照查找顺序 排好序的Filter
  数组初始化完毕,所有过滤器路径匹配上的Filter都放进数组了
  开始按照数组元素顺序进行执行,所有数组中的过滤器执行完毕
  再跳到请求的目标资源


IP属地:陕西1楼2021-08-03 23:27回复
    代码如下:
    ApplicationFilterConfig[] filters = new ApplicationFilterConfig[0];
    int pos 当前过滤器在过滤器链中的位置 正在执行的是第几个filter
    int n 数组中存放了几个filter
    void addFilter(ApplicationFilterConfig filterConfig){
    //遍历filter数组
    for((ApplicationFilterConfig filter:filters ){
    //如果要添加的filter(filterConfig))和当前正在遍历的这个filter 相等
    if(filter == filterConfig){
    //终止程序
    return;
    }
    }
    //如果数组越界
    if(n == filters.length){ //如果当前的filter的值等于数组filters的长度
    //表示数组已经越界
    //数组扩容 扩容到当前数组元素的个数 + 10
    //新建数组
    ApplicationFilterConfig[] newFilters = new ApplicationFilterConfig[n + 10];
    //直接使用系统的方法拷贝一个数组到新数组
    System.arraycopy(filters, 0, newFilters, 0, n );
    //再将拷贝好的数组赋值给原数组的引用
    filters = newFilters;
    }
    //如果没有存在重复添加元素以及数组扩容的情况
    //直接将数组的实际存在的元素的个数的值 + 1 作为新元素的索引,并赋值
    filters[n + 1] = filterConfig;
    }


    IP属地:陕西2楼2021-08-04 00:02
    回复