DelegatingFilterProxy过滤器和它代理的FilterChainProxy过滤器

DelegatingFilterProxy过滤器和它代理的FilterChainProxy过滤器

SpringSecurity需要导入的依赖

在这里插入图片描述

理解几个单词的意思:

​ delegate:代表,委托

​ DelegatingFilterProxy:委托过滤器代理

​ FilterChainProxy:过滤器链代理

​ security:安全

web.xml配置

先要在web.xml文件中配置DelegatingFilterProxy过滤器的信息:

<filter>
		<filter-name>filter</filter-name>
		<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
		<init-param>
			<param-name>targetFilterLifecycle</param-name>
			<param-value>true</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>filter</filter-name>
		<url-pattern>/admin/*</url-pattern>
	</filter-mapping>

疑惑

用过Spring Security的人都会熟悉以上代码,一般教程上都会说明,使用Spring Security就需要在web.xml中指定以上代码。从这个配置中,可能会给我们造成一个错觉,以为DelegatingFilterProxy类就是springSecurity的入口,但其实这个类位于spring-web这个jar下面,说明这个类本身是和springSecurity无关,那么问题来了,既然这个过滤器类本身和SpringSecurity无关,那么为什么还需要在web.xml中配置这个过滤器类的相关信息呢,为什么不直接配置FilterChainProxy的配置信息呢?

DelegatingFilterProxy类的位置如下图:

在这里插入图片描述

与SpringSecurity框架关系最密切的是FilterChainProxy这个过滤器,它的位置是在org.springframework.security.web中,如下图

在这里插入图片描述

解决疑惑

主要是因为DelegatingFilterProxy可以代理FilterChainProxy。

因为SpringSecurity的核心过滤器链主要是在SpringApplication容器里面,过滤器链的名字是FilterChainProxy,过滤器链也可以看成一个大的过滤器,然后IOC容器中的这个bean会交给DelegatingFilterProxy代理,相当于在DelegatingFilterProxy中实现了FilterChainProxy这个类,于是只需要在web.xml文件中配置DelegatingFilterProxy的相关信息就可以通过此过滤器来代理SpringSecurity中最重要的过滤器FilterChainProxy。

DelegatingFilterProxy相当于一个代理类,它会通过web.xml配置中的DelegatingFilterProxy对应的filter-name去spring的IOC容器中寻找id是filter-name的过滤器,也即是FilterChainProxy,找到之后执行DelegatingFilterProxy中对应的过滤逻辑。

那么上面的使用web.xml中配置的DelegatingFilterProxy去代理spring的IOC容器中的FilterChainProxy在源码中是怎样实现的呢?下面来分析源码:

分析源码

DelegatingFilterProxy类继承于抽象类GenericFilterBean,间接地implement 了javax.servlet.Filter接口,Servlet容器在启动时,首先会调用Filter的init方法,GenericFilterBean的作用主要是可以把Filter的初始化参数自动地set到继承于GenericFilterBean类的Filter中去。在其init方法的如下代码就是做了这个事:

首先来看一下DelegatingFilterProxy这个类的继承:

在这里插入图片描述

在这里插入图片描述

可以看出DelegatingFilterProxy继承了GenericFilterBean抽象类,而GenericFilterBean抽象类实现了javax.servlet.Filter接口,因此相当于DelegatingFilterProxy间接实现了javax.servlet.Filter接口,因此DelegatingFilterProxy也是一个过滤器。

其次就是在Sevlet容器启动的时候,也就是web.xml文件开始加载的时候会自动找到里面的DelegatingFilterProxy配置,然后调用此过滤器的init方法,但是此过滤器是没有init方法的,因此会调用父类GenericFilterBean的抽象方法给DelegatingFilterProxy初始化赋值,父类GenericFilterBean中的init方法中有一个initFilterBean方法,此方法其实是去调用DelegatingFilterProxy中的initFilterBean方法。

在这里插入图片描述

接下来就是回到DelegatingFilterProxy类中查看initFilterBean的源码,如下图

在这里插入图片描述

通过上图中的源码可以的出DelegatingFilterProxy类中的属性delegate代表的就是spring的IOC容器中的FilterChainProxy对象。

接下来查看DelegatingFilterProxy类中的initDelegate方法的源码,如下图:

在这里插入图片描述

然后会执行DelegatingFilterProxy的doFilter方法,doFilter方法的源码如下图:

在这里插入图片描述

最后是invokeDelegate的源码:

在这里插入图片描述

DelegatingFilterProxy过滤器的属性

在这里插入图片描述

在web.xml配置中

<filter>
		<filter-name>filter</filter-name>
		<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
		<init-param>
			<param-name>targetFilterLifecycle</param-name>
			<param-value>true</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>filter</filter-name>
		<url-pattern>/admin/*</url-pattern>
	</filter-mapping>

有一个初始化参数是targetFilterLifecycle并且值设置成了true,targetFilterLifecycle也是DelegatingFilterProxy中的属性,有什么作用呢?targetFilterLifecycle可以让DelegatingFilterProxy代理的filter bean里init和destroy方法生效。

在这里插入图片描述

在这里插入图片描述

上面的两张图片是让DelegatingFilterProxy代理的filter也即是FilterChainProxy的init方法生效。

在这里插入图片描述

在这里插入图片描述

上面的两张图片是让DelegatingFilterProxy代理的filter也即是FilterChainProxy的destroy方法生效。

FilterChainProxy过滤器

在这里插入图片描述

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_45950109/article/details/111312162