springSecurity源码分析——DelegatingFilterProxy类的作用
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类的作用相关推荐
- spring Quartz 源码分析--触发器类CronTriggerBean源码剖析
前面我们讲到了Quartz框架在项目中的实现,在Quartz中的重要API有两个重要的触发器类:CronTrigger 和SimpleTrigger 在Quartz框架中这两个触发器都继承了一个抽象基 ...
- springSecurity源码分析-spring-security.xml文件配置
在spring-security.xml文件中配置 在配置文件中我们主要使用标签来过多成配置 <!-- 配置不拦截的资源 --> <security:http pattern=&qu ...
- springSecurity源码分析-springSecurityFilterChain
在web.xml文件中配置 问题:为什么DelegatingFilterProxy的filter-name必须是springSecurityFilterChain? DelegatingFilterP ...
- MariaDB源码分析——CONNECT类
当主线程accept新连接之后,会调用handle_accepted_socket函数,申请CONNECT类对象,调用create_new_thread函数,该函数为CONNECT类对象的thread ...
- Hadoop3.2.1 【 HDFS 】源码分析 :FSDirectory类解析
Table of Contents 一.前言. 二.构造方法 三.常量 四.方法 一.前言. Namenode最重要的两个功能之一就是维护整个文件系统的目录树(即命名空间namesystem) . H ...
- 【Groovy】闭包 Closure ( 闭包类 Closure 简介 | this、owner、delegate 成员赋值及源码分析 )
文章目录 总结 一.闭包类 Closure 简介 二.闭包类 Closure 中 this.owner.delegate 成员 源码分析 三.分析编译后的字节码文件内容 总结 在闭包中 , 打印 th ...
- 这篇文章绝对让你深刻理解java类的加载以及ClassLoader源码分析
前言 package com.jvm.classloader;class Father2{public static String strFather="HelloJVM_Father&qu ...
- ElasticSearch-hadoop saveToEs源码分析
ElasticSearch-hadoop saveToEs源码分析: 类的调用路径关系为: EsSpark -> EsRDDWriter -> RestService -> Rest ...
- DialogFragment源码分析
2019独角兽企业重金招聘Python工程师标准>>> 目录介绍 1.最简单的使用方法 1.1 官方建议 1.2 最简单的使用方法 1.3 DialogFragment做屏幕适配 2 ...
最新文章
- c++ 头文件 .h 理解与实践
- centos7 安装rabbitMq
- hdu1010(小狗逃迷宫)
- CF1139D-Steps to One【期望dp,莫比乌斯反演】
- 表格在首行,添加空行
- 洛谷P2851 [USACO06DEC]最少的硬币The Fewest Coins(完全背包+多重背包)
- 一个网站大概多少钱_建一个外贸网站大概需要多少钱?角点科技总结建外贸网站的费用...
- Python多态原理与示例演示
- tensorflow实战学习笔记(1)
- 服务器电源维修哪里便宜,服务器电源维修
- [转载] python3基础:异常处理及python常见异常类型总结
- python product函数
- Dropout 丢弃法 动手学深度学习v2 pytorch
- 操作系统课程设计任务书
- 一个中国码农在硅谷求职的实用经历
- pr导入无法打开磁盘上的文件_为什么用pr导入视频显示文件导入失败?
- concurrent.futures:线程池,让你更加高效、并发的处理任务
- Java+Springmvc+velement实现高校学科竞赛项目系统+Lw
- 在excel/wps中如何实现批量翻译
- 【Reproduced】C language program of MODBUS RTU MASTER
热门文章
- iOS之深入解析对象isa的底层原理
- 104. Maximum Depth of Binary Tree 二叉树的最大深度
- 高级指引——概念解释——图形 Shape 及其属性
- 【Linux系统编程】IO多路复用之select
- 【Linux系统编程】线程的基本操作
- 【Linux】一步一步学Linux——visudo命令(104)
- 【C++】 C++标准模板库(一) Vector
- 【Ubuntu】通过虚拟机安装系统( ubuntu )
- html使用js的变量_JS变异小技巧:使用JavaScript全局变量绕过XSS过滤器
- 数据结构-----AVL树的旋转操作