在Spring集成第三方时,通常会提供以下方式的配置来作为第三方引入的入口:
<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> <!-- 默认是false -->
</init-param>
</filter>
<filter-mapping>
< filter-name>shiroFilter</filter-name>
< url-pattern>/*</url-pattern>
</filter-mapping>
从配置上来看,只是增加了一个filter,与引入的第三方框架没有什么关系。实际上DelegatingFilterProxy是org.springframework.web.filter中的一个特殊类,对于servlet filter进行代理,其好处在于可以通过spring容器来管理servlet filter对象及其生命周期。既然由spring容器进行管理,那和普通的bean就没有区别,也可以使用依赖注入机制、属性文件的操作等特性。
那么DelegatingFilterProxy是如何实现filter的代理?
protected void initFilterBean() throws ServletException {
synchronized (this.delegateMonitor) {
if(this.delegate == null){
// If no target bean name specified, use filter name.
if (this.targetBeanName == null) {
this.targetBeanName = getFilterName();
}
// Fetch Spring root application context and initialize the delegate early,
// if possible. If the root application context will be started after this
// filter proxy, we'll have to resort to lazy initialization.
WebApplicationContext wac = findWebApplicationContext();
if (wac != null) {
this.delegate = initDelegate(wac);
}
}
}
}
从上述代码可以看出,如果没有提供初始化参数targetBeanName,就用filterName替代(
必须与spring中定义的bean name对应),然后在spring IOC容器中获取该bean,下面看一下获取bean的代码initDelegate:
protected Filter initDelegate(WebApplicationContext wac) throws ServletException{
Filter delegate = wac.getBean(getTargetBeanName(), Filter.class);
if (isTargetFilterLifecycle()) {
delegate.init(getFilterConfig());
}
return delegate;
}
从容器中获取bean对象,通过判断isTargetFilterLifecycle决定是否调用init(),默认为false。从代码中Filter.class看出,该类必须实现Filter接口。在Shiro对应的bean为ShiroFilterFactoryBean,该类是一个工厂类,并没有实现Filter接口,表面上看与上面的原则相违背。实际情况ShiroFilterFactoryBean是一个Filter工厂,其有一个内部类SpringShiroFilter,继承于AbstractShiroFilter,实现了Filter接口。getObject()、getObjectType()两个方法返回的也都是SpringShiroFilter类型,因此getBean实际返回的是SpringShiroFilter。Shiro源码分析可以参考:
引用
获取Filter对象获取并执行init后,就需要关注doFilter,代码如下:
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
// Lazily initialize the delegate if necessary.
Filter delegateToUse = null;
synchronized (this.delegateMonitor) {
if (this.delegate == null) {
WebApplicationContext wac = findWebApplicationContext();
if (wac == null) {
throw new IllegalStateException("No WebApplicationContext found: no ContextLoaderListener registered?");
}
this.delegate = initDelegate(wac);
}
delegateToUse = this.delegate;
}
// Let the delegate perform the actual doFilter operation.
invokeDelegate(delegateToUse, request, response, filterChain);
}
以上代码,需要重点关注invokeDelegate,Lazily initialize只有在init未调用delegate未初始化时执行。invokeDelegate代码:
protected void invokeDelegate(
Filter delegate, ServletRequest request, ServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
delegate.doFilter(request, response, filterChain);
}
delegate为从spring容器中获取到的Filter,执行了doFilter方法。从上述代码可以看出DelegatingFilterProxy就是一个代理模式的应用,把servlet容器的filter与spring容器中bean有效的结合,综合了两者的特性。
分享到:
相关推荐
在Spring框架中,`DelegatingFilterProxy`是一个非常有用的工具,它允许我们将Spring的Bean作为Servlet过滤器(Filter)来使用。这个组件是Spring MVC的一部分,主要用于将Spring的AOP(面向切面编程)能力引入到Web...
SSH_test_2.0这个压缩包文件可能包含了一些示例代码或测试项目,用于演示如何在SSH集成代理2.0版中使用DelegatingActionProxy和Struts.xml配置。解压后,开发者可以深入研究这些示例,了解具体实现细节和最佳实践。 ...
1. DelegatingFilterProxy:这是一个Spring框架提供的过滤器,它作为代理来调用实际的Filter。在web.xml中,filter-name设置为"springSecurityFilterChain"的原因在于,SpringSecurity的配置约定是将核心过滤器链的...
在Spring框架中,我们通常使用DelegatingFilterProxy来整合Spring的AOP(面向切面编程)功能与Servlet过滤器。 1. **DelegatingFilterProxy**: 这是Spring提供的一个特殊Filter,它的主要作用是将过滤器的职责委托...
这些过滤器按顺序执行,每个都有特定的职责,如`DelegatingFilterProxy`、`FilterSecurityInterceptor`等。 接下来,我们来看看实例部分。在提供的资源中,`security_3.sql`包含了创建数据库表和初始化数据的SQL...
`DelegatingFilterProxy` 类使得 Spring Security 可以利用 Spring IoC 容器管理过滤器实例。 2. **定义安全配置**:创建一个继承自 `WebSecurityConfigurerAdapter` 的类,并覆盖其方法来指定认证和授权规则。例如...
在web.xml文件中,我们需要添加一个名为`springSecurityFilterChain`的过滤器,其类为`org.springframework.web.filter.DelegatingFilterProxy`,URL模式为`/*`。这个配置使得Spring Security的web机制可以处理所有...
例如,`DelegatingFilterProxy` 会委托到Spring Security 的 `FilterSecurityInterceptor` 进行安全检查。 2. **认证(Authentication)**:Spring Security 提供了多种认证方式,如基于表单的登录、HTTP基本认证、...
**Spring Security 3 配置使用详解** Spring Security 是一个强大的、高度可定制的身份验证和访问控制框架,广泛应用于Java企业级应用中。在Spring Security 3版本中,它提供了许多改进和新特性,旨在简化安全配置...
在配置文件中,我们需要设置`springSecurityFilterChain`过滤器,通过`DelegatingFilterProxy`将请求转发到Spring Security进行处理。`ContextLoaderListener`监听器确保Spring容器在应用启动时加载。在`security...
在web.xml文件中,我们需要配置Acegi Security提供的过滤器,如`DelegatingFilterProxy`,它会代理到Spring的Bean,即我们的`FilterSecurityInterceptor`。 在提供的“acegi-lib1”压缩包中,可能包含了Acegi ...
这里使用的是XML配置,而官方文档中的例子使用了Spring Security的`<http>`元素,它提供了更简洁的声明式配置,并且可以自动配置一些过滤器。 3. **Filter Ordering**: 过滤器的顺序至关重要,因为它们的执行顺序...
本资源提供了基于Spring 4.1和Java 8 (JDK1.8) 的过滤器实现,包括必要的jar包和实例代码,这对于理解如何在实际项目中使用过滤器具有很高的参考价值。 首先,我们需要了解过滤器的基本工作原理。过滤器是实现了 ...
Spring Security通过一系列过滤器构成过滤链,如`DelegatingFilterProxy`指向Spring Security的`FilterChainProxy`。每个过滤器都有特定的任务,如`UsernamePasswordAuthenticationFilter`处理表单认证。 9. **...
在Spring MVC框架中,可以使用Spring的DelegatingFilterProxy来代理Spring的Bean,这样可以利用Spring的依赖注入和AOP特性。 9. **动态过滤** 通过编程方式动态地添加、删除过滤器,可以实现更加灵活的过滤策略。...
<filter-class>org.springframework.web.filter.DelegatingFilterProxy <filter-name>springSecurityFilterChain <url-pattern>/* <listener-class>org.springframework.web.context....
文档中示例了如何配置springSecurityFilterChain过滤器,该过滤器使用DelegatingFilterProxy代理,从而将请求委托给Spring Security提供的过滤器链处理。 #### 5. 命名空间配置 在Spring Security 3.0.5中,通过在...
在 `spring-security.xml` 中,你可以使用 `<http>` 元素定义 URL 的安全策略,使用 `<authentication-manager>` 配置认证机制,以及使用 `<access-denied-handler>` 处理权限拒绝的情况。此外,还可以通过 `...