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对象的方法解决了这一问题。