spring的过滤器——DelegatingFilterProxy

DelegatingFilterProxy是spring定义的一个Filter,它的作用是代理我们自己自定义的Filter。

这是啥意思?在讲为什么之前,我们先来认识一下Tomcat中web应用的初始化流程

Tomcat读取应用目录下面WEB-INF目录里面的web.xml文件,然后建立属于每一个应用特有的ServletContext对象,然后初始话实现了ServletContextListener接口的监听器类,并调用其public void contextInitialized ( ServletContextEvent sce );;然后初始化实现类Filter接口的类,并调用其public void init(FilterConfig filterConfig) throws ServletException;进行初始化,初始化顺序按照定义的顺序;然后是初始化应该在web应用启动时就应该初始化的Servlet类,然后调用其 public void init(ServletConfig config) throws ServletException;方法进行初始化

知道了上面的知识,再来看看一个web.xml文件的配置

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	id="WebApp_ID" version="2.5">
	
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:applicationContext.xml</param-value>
	</context-param>
	
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	
	<servlet>
		<servlet-name>spring</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>spring</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>
	
	<!-- 
	1. 配置  Shiro 的 shiroFilter.  
	2. DelegatingFilterProxy 实际上是 Filter 的一个代理对象. 默认情况下, Spring 会到 IOC 容器中查找和 
	<filter-name> 对应的 filter bean. 也可以通过 targetBeanName 的初始化参数来配置 filter bean 的 id. 
	-->
    <filter>
        <filter-name>shiroFilter</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>shiroFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

上面DelegatingFilterProxy对象代理的是下面applicationContext.xml的bean

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager"/>
        <property name="loginUrl" value="/login.jsp"/>
        <property name="successUrl" value="/list.jsp"/>
        <property name="unauthorizedUrl" value="/unauthorized.jsp"/>
        <property name="filterChainDefinitionMap" ref="filterChainDefinitionMap"></property>
        <!--  
        	配置哪些页面需要受保护. 
        	以及访问这些页面需要的权限. 
        	1). anon 可以被匿名访问
        	2). authc 必须认证(即登录)后才可能访问的页面. 
        	3). logout 登出.
        	4). roles 角色过滤器
        -->
    </bean>

因为在上面web.xml文件中配置了ContextLoaderListener,所以spring父容器会最先被初始化,也就是说ShiroFilterFactoryBean会先被初始化,然后再到DelegatingFilterProxy对象初始化,为什么要这样做呢?如果不是这样作而是将过滤器直接放到web.xml中定义,那么它就不能获得依赖注入的特性。有人可能会说,使ShiroFilterFactoryBean能够被扫描到不久可以了嘛?这很显然是冲突,你想它放在web.xml文件里面定义又想它可以被注入IOC容器这是不可能的,所以spring采取了代理Filter对象的方法解决了这一问题。

猜你喜欢

转载自blog.csdn.net/weixin_42002747/article/details/103739514