`

DelegatingFilterProxy 分析

 
阅读更多

 

protected Filter initDelegate(WebApplicationContext wac) throws ServletException {
        Filter delegate = wac.getBean(getTargetBeanName(), Filter.class);
        if (isTargetFilterLifecycle()) {
            delegate.init(getFilterConfig());
        }
        return delegate;
}
 使用过springSecurity的朋友都知道,首先需要在web.xml进行以下配置,

 

 <filter>
  <description>登录验证,访问权限控制。</description>
  <filter-name>springSecurityFilterChain</filter-name>
  <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
  <filter-name>springSecurityFilterChain</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>

 从这个配置中,可能会给我们造成一个错觉,以为DelegatingFilterProxy类就是springSecurity的入口,但其实这个类位于spring-web-3.0.5.RELEASE.jar这个jar下面,说明这个类本身是和springSecurity无关。DelegatingFilterProxy类继承于抽象类GenericFilterBean,间接地implement 了javax.servlet.Filter接口,Servlet容器在启动时,首先会调用Filter的init方法,GenericFilterBean的作用主要是可以把Filter的初始化参数自动地set到继承于GenericFilterBean类的Filter中去。在其init方法的如下代码就是做了这个事:

public final void init(FilterConfig filterConfig) throws ServletException {
		Assert.notNull(filterConfig, "FilterConfig must not be null");
		if (logger.isDebugEnabled()) {
			logger.debug("Initializing filter '" + filterConfig.getFilterName() + "'");
		}

		this.filterConfig = filterConfig;

		// Set bean properties from init parameters.
		try {
			PropertyValues pvs = new FilterConfigPropertyValues(filterConfig, this.requiredProperties);
			BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
			ResourceLoader resourceLoader = new ServletContextResourceLoader(filterConfig.getServletContext());
			bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, this.environment));
			initBeanWrapper(bw);
			bw.setPropertyValues(pvs, true);
		}
		catch (BeansException ex) {
			String msg = "Failed to set bean properties on filter '" +
			    filterConfig.getFilterName() + "': " + ex.getMessage();
			logger.error(msg, ex);
			throw new NestedServletException(msg, ex);
		}

		// 这个方法留给子类来扩展
		initFilterBean();

		if (logger.isDebugEnabled()) {
			logger.debug("Filter '" + filterConfig.getFilterName() + "' configured successfully");
		}
	}

 DelegatingFilterProxy  initFilterBean方法的代码如下:

 

protected void initFilterBean() throws ServletException {
        // 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.
        synchronized (this.delegateMonitor) {
            WebApplicationContext wac = findWebApplicationContext();
            if (wac != null) {
                this.delegate = initDelegate(wac);
            }
        }
    }
 可以看出上述代码首先看Filter是否提供了targetBeanName初始化参数,如果没有提供则直接使用filter的name做为beanName,产生了beanName后,由于我们在web.xml的filter的name是springSecurityFilterChain,从spring的IOC容器中取出bean的代码是initDelegate方法,下面是该方法代码
protected Filter initDelegate(WebApplicationContext wac) throws ServletException {
        Filter delegate = wac.getBean(getTargetBeanName(), Filter.class);
        if (isTargetFilterLifecycle()) {
            delegate.init(getFilterConfig());
        }
        return delegate;
}
 

 

通过跟踪代码,发现取出的bean是org.springframework.security.FilterChainProxy,该类也是继承于GenericFilterBean,取出bean后,判断targetFilterLifecycle属性是false还是true,决定是否调用该类的init方法。这个FilterChainProxy bean实例最终被保存在DelegatingFilterProxy类的delegate属性里

下面看一下DelegatingFilterProxy类的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(delegateToUse, request, response, filterChain);这句代码,在下面可以看出DelegatingFilterProxy类实际是用其delegate属性即org.springframework.security.FilterChainProxy实例的doFilter方法来响应请求

protected void invokeDelegate(
            Filter delegate, ServletRequest request, ServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
 
        delegate.doFilter(request, response, filterChain);
    }

 以上就是DelegatingFilterProxy类的一些内部运行机制,其实主要作用就是一个代理模式的应用,可以把servlet 容器中的filter同spring容器中的bean关联起来

分享到:
评论

相关推荐

    DelegatingFilterProxy示例

    通过上述分析,我们可以看出`DelegatingFilterProxy`在Spring MVC应用中的重要性,它使得过滤器可以充分利用Spring框架的优势,提高了代码的可维护性和可扩展性。同时,结合提供的代码示例,我们可以更好地理解和...

    3.springSecurity源码分析1

    在深入分析SpringSecurity源码之前,我们先了解一些基础概念。 1. DelegatingFilterProxy:这是一个Spring框架提供的过滤器,它作为代理来调用实际的Filter。在web.xml中,filter-name设置为...

    Spring Security 3 源码分析文档

    4. **过滤器链(Filter Chain)**:Spring Security通过一系列过滤器处理HTTP请求,如DelegatingFilterProxy、ChannelProcessingFilter、SecurityContextPersistenceFilter等。理解过滤器链的工作原理,能帮助优化...

    Spring_Security3_源码分析

    Spring Security的核心在于Filter Chain,它由多个安全相关的过滤器组成,如DelegatingFilterProxy、ChannelProcessingFilter、SecurityContextHolderAwareRequestFilter等。每个过滤器都有特定职责,如检查HTTP请求...

    springsecurity3 学习笔记源码分析所得

    1. **Filter Chain**: Spring Security的核心在于其过滤器链,它由多个安全过滤器组成,如`DelegatingFilterProxy`、`ChannelProcessingFilter`、`UsernamePasswordAuthenticationFilter`等。这些过滤器按照特定顺序...

    尚硅谷Shiro视频教程

    尚硅谷_Shiro_DelegatingFilterProxy · 06. 尚硅谷_Shiro_权限 URL 配置细节 · 07. 尚硅谷_Shiro_认证思路分析 · 08.尚硅谷_Shiro_实现认证流程 · 09.尚硅谷_Shiro_实现认证 Realm · 10.尚硅谷_Shiro_密码...

    Spring整合Shiro做权限控制模块详细案例分析

    这里定义了一个名为 `shiroFilter` 的过滤器,使用 `DelegatingFilterProxy` 类来代理 Shiro 的 Filter。`filter-mapping` 配置表明所有的请求都将通过 Shiro 过滤器进行处理。 然后,为了实现自定义的权限控制,...

    Spring Security中的Servlet过滤器体系代码分析

    从`DelegatingFilterProxy` 将Filter纳入Spring管理,到`FilterChainProxy` 根据请求路由到合适的`SecurityFilterChain`,整个流程展示了Spring Security如何巧妙地结合Servlet规范和Spring框架的优势,实现高效、可...

    Spring Security二

    - `DelegatingFilterProxy`:将请求委托给Spring Security的`FilterSecurityInterceptor`。 - `SecurityContextPersistenceFilter`:在HTTP请求之间保持`SecurityContext`。 - `ConcurrentSessionFilter`:管理并发...

    单点登录SpringSsession

    在Spring Session的配置中,`DelegatingFilterProxy`将通过指定的名字(如`springSessionRepositoryFilter`)去查找Spring容器中对应的Bean,并将其转换为过滤器进行工作。 - **Cookie跨域问题**:在多域名的环境中...

    springsecurity源码(鉴权有缺陷)

    核心组件是`DelegatingFilterProxy`,它是一个Servlet过滤器,用于代理其他Spring Bean(如`SecurityContextPersistenceFilter`和`ConcurrentSessionFilter`)。 2. **鉴权流程**: - **身份验证(Authentication...

    spring-security-3.2.9的jar包和源码包

    Spring Security Filter Chain 包括了如`DelegatingFilterProxy`、`ChannelProcessingFilter`、`SecurityContextHolderAwareRequestFilter`、`AnonymousAuthenticationFilter`、`SessionManagementFilter`、`...

    springsecurity

    - `DelegatingFilterProxy`: 用于代理Spring Security的Filter对象。 - `SecurityContextPersistenceFilter`: 保存和恢复用户的Security Context(安全上下文)。 - `UsernamePasswordAuthenticationFilter`: ...

    Spring Security3 配置使用

    6. **源码分析**:对于深入理解Spring Security的工作原理,阅读源码是十分有帮助的。可以研究`AuthenticationManager`、`FilterSecurityInterceptor`、`AbstractAuthenticationProcessingFilter`等关键类的实现。 ...

    过滤器.zip

    7. **Spring框架中的Filter**:在Spring MVC中,虽然可以使用传统的Servlet Filter,但Spring也提供了DelegatingFilterProxy,它可以用来代理Spring的Bean,这样过滤器也能享受到Spring的依赖注入。 通过分析和实践...

    spring-security-web-3 source code

    - **Filter的注册与配置**:理解Spring Security如何通过`DelegatingFilterProxy`将Spring Bean注册为Servlet Filter,并配置过滤链。 - **SecurityContextHolder**:查看如何在应用程序中设置和获取安全上下文,...

    Sring security 简单案例

    通过分析案例中的代码和配置,我们可以学习如何设置基本的安全规则,处理用户认证和授权,以及如何自定义Spring Security的行为以适应我们的应用程序需求。这个案例是深入学习Spring Security和实践安全控制的一个...

    JAVAEE过滤器的使用

    在Spring MVC框架中,可以使用Spring的DelegatingFilterProxy来代理Spring的Bean,这样可以利用Spring的依赖注入和AOP特性。 9. **动态过滤** 通过编程方式动态地添加、删除过滤器,可以实现更加灵活的过滤策略。...

    SpringSecurity3框架

    1. **DelegatingFilterProxy**:这是一个Spring框架的过滤器,它将请求委托给Spring容器中的Bean,通常是`FilterSecurityInterceptor`。 2. **ChannelProcessingFilter**:处理HTTP和HTTPS之间的切换,确保敏感操作...

    springsecurity教学代码.zip

    例如,`DelegatingFilterProxy`用于代理Spring Security的配置,`UsernamePasswordAuthenticationFilter`处理表单登录请求。 4. **会话管理(Session Management)**:Spring Security可以管理用户的会话,包括会话...

Global site tag (gtag.js) - Google Analytics