http://www.cnblogs.com/hzhuxin/archive/2011/12/19/2293730.html

使用过springSecurity的朋友都知道,首先需要在web.xml进行以下配置,

<filter>
  <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方法的如下代码就是做了这个事:

?
1
2
3
4
5
6
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));
initBeanWrapper(bw);
bw.setPropertyValues(pvs, true);

另外在init方法中调用了initFilterBean()方法,该方法是GenericFilterBean类是特地留给子类扩展用的,

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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方法,下面是该方法代码:

?
1
2
3
4
5
6
7
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方法

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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方法来响应请求。

?
1
2
3
4
5
6
protected void invokeDelegate(
            Filter delegate, ServletRequest request, ServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
  
        delegate.doFilter(request, response, filterChain);
    }

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

springSecurity源码分析——DelegatingFilterProxy类的作用相关推荐

  1. spring Quartz 源码分析--触发器类CronTriggerBean源码剖析

    前面我们讲到了Quartz框架在项目中的实现,在Quartz中的重要API有两个重要的触发器类:CronTrigger 和SimpleTrigger 在Quartz框架中这两个触发器都继承了一个抽象基 ...

  2. springSecurity源码分析-spring-security.xml文件配置

    在spring-security.xml文件中配置 在配置文件中我们主要使用标签来过多成配置 <!-- 配置不拦截的资源 --> <security:http pattern=&qu ...

  3. springSecurity源码分析-springSecurityFilterChain

    在web.xml文件中配置 问题:为什么DelegatingFilterProxy的filter-name必须是springSecurityFilterChain? DelegatingFilterP ...

  4. MariaDB源码分析——CONNECT类

    当主线程accept新连接之后,会调用handle_accepted_socket函数,申请CONNECT类对象,调用create_new_thread函数,该函数为CONNECT类对象的thread ...

  5. Hadoop3.2.1 【 HDFS 】源码分析 :FSDirectory类解析

    Table of Contents 一.前言. 二.构造方法 三.常量 四.方法 一.前言. Namenode最重要的两个功能之一就是维护整个文件系统的目录树(即命名空间namesystem) . H ...

  6. 【Groovy】闭包 Closure ( 闭包类 Closure 简介 | this、owner、delegate 成员赋值及源码分析 )

    文章目录 总结 一.闭包类 Closure 简介 二.闭包类 Closure 中 this.owner.delegate 成员 源码分析 三.分析编译后的字节码文件内容 总结 在闭包中 , 打印 th ...

  7. 这篇文章绝对让你深刻理解java类的加载以及ClassLoader源码分析

    前言 package com.jvm.classloader;class Father2{public static String strFather="HelloJVM_Father&qu ...

  8. ElasticSearch-hadoop saveToEs源码分析

    ElasticSearch-hadoop saveToEs源码分析: 类的调用路径关系为: EsSpark -> EsRDDWriter -> RestService -> Rest ...

  9. DialogFragment源码分析

    2019独角兽企业重金招聘Python工程师标准>>> 目录介绍 1.最简单的使用方法 1.1 官方建议 1.2 最简单的使用方法 1.3 DialogFragment做屏幕适配 2 ...

最新文章

  1. c++ 头文件 .h 理解与实践
  2. centos7 安装rabbitMq
  3. hdu1010(小狗逃迷宫)
  4. CF1139D-Steps to One【期望dp,莫比乌斯反演】
  5. 表格在首行,添加空行
  6. 洛谷P2851 [USACO06DEC]最少的硬币The Fewest Coins(完全背包+多重背包)
  7. 一个网站大概多少钱_建一个外贸网站大概需要多少钱?角点科技总结建外贸网站的费用...
  8. Python多态原理与示例演示
  9. tensorflow实战学习笔记(1)
  10. 服务器电源维修哪里便宜,服务器电源维修
  11. [转载] python3基础:异常处理及python常见异常类型总结
  12. python product函数
  13. Dropout 丢弃法 动手学深度学习v2 pytorch
  14. 操作系统课程设计任务书
  15. 一个中国码农在硅谷求职的实用经历
  16. pr导入无法打开磁盘上的文件_为什么用pr导入视频显示文件导入失败?
  17. concurrent.futures:线程池,让你更加高效、并发的处理任务
  18. Java+Springmvc+velement实现高校学科竞赛项目系统+Lw
  19. 在excel/wps中如何实现批量翻译
  20. 【Reproduced】C language program of MODBUS RTU MASTER

热门文章

  1. iOS之深入解析对象isa的底层原理
  2. 104. Maximum Depth of Binary Tree 二叉树的最大深度
  3. 高级指引——概念解释——图形 Shape 及其属性
  4. 【Linux系统编程】IO多路复用之select
  5. 【Linux系统编程】线程的基本操作
  6. 【Linux】一步一步学Linux——visudo命令(104)
  7. 【C++】 C++标准模板库(一) Vector
  8. 【Ubuntu】通过虚拟机安装系统( ubuntu )
  9. html使用js的变量_JS变异小技巧:使用JavaScript全局变量绕过XSS过滤器
  10. 数据结构-----AVL树的旋转操作