简体   繁体   English

DelegatingFilterProxy 和 GenericFilterBean 有什么区别?

[英]Whats the difference between DelegatingFilterProxy and GenericFilterBean?

  • DelegatingFilterProxy enables you to use a Spring Bean as a servlet filter. DelegatingFilterProxy使您能够使用 Spring Bean 作为 servlet 过滤器。 So you can use the spring context inside the filter, inject other beans and so on.所以你可以使用过滤器内部的spring上下文,注入其他bean等等。 It extends GenericFilterBean in order to gain this functionality.它扩展了GenericFilterBean以获得此功能。
  • GenericFilterBean enables you to do the same. GenericFilterBean使您能够做同样的事情。

Both classes seem to claim to provide the same functionality in the end.这两个类似乎都声称最终提供了相同的功能。 Both classes seem to be able to be wired directly in the web.xml .这两个类似乎都可以直接连接到web.xml中。 The code of DelegatingFilterProxy seems to be just a thin layer of indirection. DelegatingFilterProxy的代码似乎只是一层薄薄的间接。

But why is this even necessary, where you could just extend GenericFilterBean instead?但是为什么这甚至是必要的,你可以只扩展GenericFilterBean呢? Why, for example, does Spring Security use a DelegatingFilterProxy in order to call the FilterChainProxy , although the latter already extends GenericFilterBean ?例如,为什么 Spring Security 使用DelegatingFilterProxy来调用FilterChainProxy ,尽管后者已经扩展了GenericFilterBean

It extends GenericFilterBean in order to gain this functionality.它扩展了GenericFilterBean以获得此功能。

I think I'd word that differently.我想我会换一种说法。 According to GenericFilterBean 's JavaDoc :根据GenericFilterBean的 JavaDoc

/**
 * This generic filter base class has no dependency on the Spring  
 * org.springframework.context.ApplicationContext concept. Filters usually 
 * don't load their own context but rather access service beans from the 
 * Spring root application context, accessible via the filter's 
 * ServletContext
 **/

Note also from GenericFilterBean 's JavaDoc:还要注意GenericFilterBean的 JavaDoc:

/**
 * This filter leaves actual filtering to subclasses, which have to implement 
 * the Filter.doFilter method.
 **/

Or, IOW, GenericFilterBean picks up init-param s, registers them as Spring bean properties, and applies those properties to the filter.或者,IOW, GenericFilterBean获取init-param ,将它们注册为 Spring bean 属性,并将这些属性应用于过滤器。 init-param s are limited in their capacity and also doFilter still needs implementing either way. init-param的容量有限,并且doFilter仍然需要实现任何一种方式。

This is where DelegatingFilterProxy comes in. It looks up a bean of type Filter from the application context and proxies to it in its own doFilter method.这就是DelegatingFilterProxy的用武之地。它从应用程序上下文中查找Filter类型的 bean,并在它自己的doFilter方法中代理它。 This proxy allows applications to specify a bean of type Filter that relies on Spring's lifecycle instead of the servlet container's.这个代理允许应用程序指定一个Filter类型的 bean,它依赖于 Spring 的生命周期而不是 servlet 容器的生命周期。

You can see this detailed in DelegatingFilterProxy 's JavaDoc :您可以在DelegatingFilterProxy的 JavaDoc中查看详细信息:

/**
  * This approach is particularly useful for Filter implementation with 
  * complex setup needs, allowing to apply the full Spring bean definition 
  * machinery to Filter instances.
  */

NOTE : Spring Boot applications can alternatively publish beans of type FilterRegistrationBean to specify both the underlying filter, its order and dispatcher types.注意:Spring 引导应用程序可以选择发布FilterRegistrationBean类型的 bean 来指定底层过滤器、其顺序和调度程序类型。

Both classes seem to be able to be wired directly in the web.xml这两个类似乎都可以直接连接到web.xml

What gives you this impression?是什么让你有这样的印象? Given that GenericFilterBean is abstract , I'm not clear on how it could be referenced in a web.xml file.鉴于GenericFilterBeanabstract ,我不清楚如何在web.xml文件中引用它。 The Servlet container would not be able to construct it. Servlet 容器将无法构造它。

does Spring Security use a DelegatingFilterProxy in order to call the FilterChainProxy Spring Security 是否使用DelegatingFilterProxy来调用FilterChainProxy

Yes . 的。

Spring Security chooses to use the Filter API instead of inventing its own. Spring 安全选择使用Filter API 而不是自己发明。 Because of that, it fits nicely inside the purpose of DelegatingFilterProxy .因此,它非常适合DelegatingFilterProxy的目的。 (You can imagine how limiting it might be for folks to configure Spring Security though web.xml init-param s alone, for example.) (例如,您可以想象人们通过web.xml init-param单独配置 Spring Security 可能会有多大限制。)

Hypothetically, if Spring Security had decided to create its own filter-like API, it would have its own implementation of GenericFilterBean that implements doFilter differently.假设,如果 Spring Security 决定创建自己的类似过滤器的 API,它将拥有自己的GenericFilterBean实现,以不同的方式实现doFilter

although the latter already extends GenericFilterBean尽管后者已经扩展了GenericFilterBean

I think this part of your question is asking "couldn't FilterChainProxy just be specified as a filter to the servlet container since it implements GenericFilterBean ?".我认为您问题的这一部分是在问“不能将FilterChainProxy指定为 servlet 容器的过滤器,因为它实现了GenericFilterBean ?”。 And the answer is "no" .答案是“不” From Spring Security's docs:来自 Spring Security 的文档:

Another benefit of DelegatingFilterProxy is that it allows delaying looking Filter bean instances. DelegatingFilterProxy的另一个好处是它允许延迟查找Filter bean 实例。 This is important because the container needs to register the Filter instances before the container can startup.这很重要,因为容器需要在容器启动之前注册Filter实例。 However, Spring typically uses a ContextLoaderListener to load the Spring Beans which will not be done until after the Filter instances need to be registered.但是,Spring 通常使用ContextLoaderListener来加载 Spring Bean,直到需要注册过滤器实例之后才会完成。

Why does it extend GenericFilterBean , then?那它为什么要扩展GenericFilterBean呢? Most Spring filters extend GenericFilterBean because it allows more flexibility for applications to use them like building blocks.大多数 Spring 过滤器扩展了GenericFilterBean ,因为它允许应用程序更灵活地像构建块一样使用它们。 Like its JavaDoc says:就像它的 JavaDoc 说的:

/**
  * A handy superclass for any type of filter.
  */

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM