Tomcat是如何为每个请求应用过滤器的?

image

image

image

image

image

image

image


image

image

image

image

image

image

image

image

image

image

image

image


image

image

image

image

image

image


兜兜转转,一个SessionRepositoryFilter从声明出来到最后应用到每个请求上也是经历了千山万水。

先是按照SpringBoot的注解方式,声明它自己为Bean,然后再把注册它的上下文初始化类注解为Bean。

应用启动,通过SpringBoot的自动化配置将注册Bean放入Spring容器中等待被使用。

SpringBoot启动内置Tomcat,由容器初始化器把它们从Spring容器中一个个提留出来,然后启动。

这些上下文初始化器启动的过程就是把一个个过滤器放入容器上下文的过程。

先用滤器构建滤器定义FilterDef,再将其加入到上下文的过滤器集合中,这个过滤器定义包含过滤器名字和过滤器自身,这样就能通过名字查找了。

然后再根据这些定义对过虑器一一设置匹配规则,主要就是设置一下适用于过滤器的DispatcherType、servletNames、urlPatterns,这样就可以在处理请求时先根据这些规则判断下是否适用。先用这些匹配规则构建一个FilterMap,再将其存入上下文中的过滤器匹配规则数组中。

这样,上下文中就存在了过滤器的定义和适用规则。

这之后还有一个上下文的操作,叫做过滤器启动。过程就是把所有的过滤器定义和上下文一一绑定形成过滤器配置,并保存到上下文中以过滤器名字为key的配置集合中。

这个过滤器配置的作用除了将上下文和过滤器绑定外,还在构造时完成过滤器的自身初始化,即执行方法init()。但也只有部分过滤器的初始化方法中存在内容,像Session过滤器的父类OncePerRequestFilter的init()方法内容为空,也就不需要初始化。

当外部请求到来时,先通过遍历过滤器规则数组过滤出符合条件的规则,再根据规则中的过滤器名称找到过滤器配置,最后将这些配置收集起来形成过滤器配置链。

将请求和返回对象传入这个配置链中进行链式过滤处理。过程就是将各个配置中的真正过滤器对象取出,并应用到请求和返回对象上。这样就进入到了过滤器内部执行真正的业务操作。

经过上面的梳理和分析得出对于过滤器是否应用到一个请求上,可以通过两种方式实现,一是在内部通过内置匹配器判断,另外还可以通过在注册过滤器时通过DispatcherType、servletNames、urlPatterns来指定,但这种方式比较简陋,只能设置这三种类型的匹配规则。

image

1604488883

image

原文地址:https://www.cnblogs.com/StarkBrothers/p/13925001.html