java - Spring MVC 的 DelegatingFilterProxy 有什么意义?

标签 java spring spring-mvc spring-security

我在 Spring MVC 应用程序的 web.xml 中看到了这一点:

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

我正试图弄清楚它为什么存在以及它是否真的需要。

我找到了 this explanation in the Spring docs但这并不能帮助我理解它:

似乎暗示这个组件是web.xml中定义的servlet和Spring applicationContext.xml中定义的组件之间的“粘合剂”。

7.1 DelegatingFilterProxy

When using servlet filters, you obviously need to declare them in your web.xml, or they will be ignored by the servlet container. In Spring Security, the filter classes are also Spring beans defined in the application context and thus able to take advantage of Spring's rich dependency-injection facilities and lifecycle interfaces. Spring's DelegatingFilterProxy provides the link between web.xml and the application context.

When using DelegatingFilterProxy, you will see something like this in the web.xml file:

<filter>
   <filter-name>myFilter</filter-name>
   <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
   <filter-name>myFilter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

Notice that the filter is actually a DelegatingFilterProxy, and not the class that will actually implement the logic of the filter. What DelegatingFilterProxy does is delegate the Filter's methods through to a bean which is obtained from the Spring application context. This enables the bean to benefit from the Spring web application context lifecycle support and configuration flexibility. The bean must implement javax.servlet.Filter and it must have the same name as that in the filter-name element. Read the Javadoc for DelegatingFilterProxy for more information

那么,如果我把它从我的 web.xml 中取出,会发生什么?我的 servlet 将无法与 Spring 容器通信?**

最佳答案

这里有某种魔法,但归根结底,一切都是确定性程序。

DelegatingFilterProxy 是一个如上所述的过滤器,其目标是“委派给实现过滤器接口(interface)的 Spring 管理的 bean”,也就是说,它会在您的 Spring 应用程序上下文中找到一个 bean(“目标 bean”或“委托(delegate)”)并调用它。这怎么可能?因为这个bean实现了javax.servlet.Filter,所以调用了它的doFilter方法。

调用哪个bean? DelegatingFilterProxy “支持“targetBeanName” [...],指定 Spring 应用程序上下文中目标 bean 的名称。”

正如您在 web.xml 中看到的,bean 的名称是“springSecurityFilterChain

因此,在 Web 应用程序的上下文中,Filter 在应用程序上下文中实例化一个名为“springSecurityFilterChain”的 bean,然后通过 doFilter() 方法委托(delegate)给它。

请记住,您的应用程序上下文是使用所有应用程序上下文 (XML) 文件定义的。例如:applicationContext.xml 和 applicationContext-security.xml。

所以尝试在后者中找到一个名为“springSecurityFilterChain”的bean...

...并且可能您不能(例如,如果您按照教程进行操作,或者如果您使用 Roo 配置了安全性)

神奇之处在于:有一个用于配置安全性的新元素,类似于

<http auto-config="true" use-expressions="true"> 

http://www.springframework.org/schema/security/spring-security-3.0.xsd 允许,会成功的。

Spring 使用 XML 文件加载应用上下文时,如果找到一个元素,它会尝试设置 HTTP 安全性,即过滤器堆栈和 protected URL,并注册名为“springSecurityFilterChain”的 FilterChainProxy。

或者,你可以用经典的方式定义bean,即:

<beans:bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">

但不太推荐,因为您需要进行大量配置(您将要使用的所有过滤器。而且有十几个)

关于java - Spring MVC 的 DelegatingFilterProxy 有什么意义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6725234/

相关文章:

java - Spring @Value 注释返回 null

java - spring文件下载 Controller 中返回类型的意义

java - Eclipse (ADT) 中的内存错误 - 错误的 Java 版本?

java - 为不同的 sso 票据重用 jco 3 连接池

java - 在自定义 Controller 中接受 Spring Data REST URI

java - 错误注入(inject) : org. jvnet.mjiip.v_2.XJC2Mojo java.lang.NoClassDefFoundError: com/sun/xml/bind/api/ErrorListener

java - Spring Controller 返回不同的日期格式

java - struts2的迭代器标签

java - UTF-8编码和Struts 2.1.7

java - response.sendError 使用自定义过滤器抛出异常