org.springframework.web.filter.DelegatingFilterProxy的作用
一、类结构

DelegatingFilterProxy类存在与spring-web包中,其作用就是一个filter的代理,用这个类的好处是可以通过spring容器来管理filter的生命周期,还有就是,可以通过spring注入的形式,来代理一个filter执行,如shiro,下面会说到;有上图我们可以看到,DelegatingFilterProxy类继承GenericFilterBean,间接实现了Filter这个接口,故而该类属于一个过滤器。那么就会有实现Filter中init、doFilter、destroy三个方法。
二、代理具体实现
首先我们看init方法,我们知道当filter初始化时会执行init方法,从源码中我们可以找到具体代码,该方法在GenericFilterBean类中实现,具体功能是,将该类封装成spring特有形式的类,方便spring维护,并且调用initFilterBean方法,该方法放在子类(DelegatingFilterProxy)实现,该方法主要目的是,找到在spring中维护的目标filter,具体实现看下面代码:
/**
* Standard way of initializing this filter.
* Map config parameters onto bean properties of this filter, and
* invoke subclass initialization.
* @param filterConfig the configuration for this filter
* @throws ServletException if bean properties are invalid (or required
* properties are missing), or if subclass initialization fails.
* @see #initFilterBean
*/
@Override
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 {
//将该类封装成spring特有的bean形式,方便spring维护
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);
} // 该方法在子类中实现,我们可以到DelegatingFilterPoxy中去看看,具体完成了那些工作?
//1、找到要代理bean的id--》targetBeanName
//2、在spring,bean容器中找到具体被代理的filter--》delegate
initFilterBean(); if (logger.isDebugEnabled()) {
logger.debug("Filter '" + filterConfig.getFilterName() + "' configured successfully");
}
}
initFilterBean()该方法主要完成两个功能:
1、找到被代理类在spring中配置的id并赋值给targetBeanName。
2、使用找到的id从spring容器中找到具体被代理的类,并赋值给delegate
@Override
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) {
//找到要被代理的filter在spring中配置的id
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) {
//找到具体被代理的filter
this.delegate = initDelegate(wac);
}
}
}
}
getFilterName()该方法的作用是,获取被代理的filter在spring中配置的id
protected final String getFilterName() {
//找到被代理filter在spring中配置的id
return (this.filterConfig != null ? this.filterConfig.getFilterName() : this.beanName);
}
initDelegate()该方法的作用是,从spring容器中获取到具体被代理的filter
//找到被代理的filter
protected Filter initDelegate(WebApplicationContext wac) throws ServletException {
Filter delegate = wac.getBean(getTargetBeanName(), Filter.class);
if (isTargetFilterLifecycle()) {
delegate.init(getFilterConfig());
}
return delegate;
}
到这里我们可以看出来,我们要代理的filter其实就是我们配置filter中的filter-name标签中的filterName了
<filter-name>filterName</filter-name> 我们在来看看doFilter方法具体实现,该方法主要是使用被代理的filter,并调用invokeDelegate方法,
执行被代理filter的doFilter方法,具体实现,请看下面源码:
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws ServletException, IOException { // 得到被代理的filter
Filter delegateToUse = this.delegate;
if (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;
}
} // 执行被代理filter的doFilter方法
invokeDelegate(delegateToUse, request, response, filterChain);
}
invokeDelegate方法的作用就是执行被代理filter的doFilter方法
protected void invokeDelegate(
Filter delegate, ServletRequest request, ServletResponse response, FilterChain filterChain)
throws ServletException, IOException { delegate.doFilter(request, response, filterChain);
}
看到这里我相信大家都明白DelegatingFilterPoxy是怎么回事了吧。下面我们看看spring+shiro是如何运用这个类的 三、运用
首先我们看web.xml具体配置,注意<filter-name>中配置的name,以name为id在spring的bean配置中找得到对应的bean
<!-- Shiro Security filter-->
<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>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
spring对于代理filter配置
<bean id="shiroFilter" class="com.auth.SpringShiroFilter"/>
第一次写博客,存在很多不足,希望大家见谅。
org.springframework.web.filter.DelegatingFilterProxy的作用的更多相关文章
- org.springframework.web.filter.DelegatingFilterProxy的理解
org.springframework.web.filter.DelegatingFilterProxy可以将filter交给spring管理. 我们web.xml中配置filter时一般采用下面这种 ...
- Spring管理过滤器:org.springframework.web.filter.DelegatingFilterProxy
配置web.xml <filter> <filter-name>springSecurityFilterChain</filter-name> ...
- org.springframework.web.filter.CharacterEncodingFilter
感谢:http://blog.csdn.net/heidan2006/article/details/3075730 很简单很实用的一个过滤器,当前台JSP页面和JAVA代码中使用了不同的字符集进行编 ...
- java.lang.ClassNotFoundException: org.springframework.web.filter.CharacterEncodingFilter
今天在用git merge 新代码后报了如下错误:java.lang.ClassNotFoundException: org.springframework.web.filter.CharacterE ...
- 通过org.springframework.web.filter.CharacterEncodingFilter定义Spring web请求的编码
通过类org.springframework.web.filter.CharacterEncodingFilter,定义request和response的编码.具体做法是,在web.xml中定义一个F ...
- java.lang.ClassCastException: org.springframework.web.filter.CharacterEncodingFilter cannot be cast to javax.servlet.Filter
java.lang.ClassCastException: org.springframework.web.filter.CharacterEncodingFilter cannot be cast ...
- SpringMVC(四):@RequestMapping结合org.springframework.web.filter.HiddenHttpMethodFilter实现REST请求
1)REST具体表现: --- /account/1 HTTP GET 获取id=1的account --- /account/1 HTTP DELETE 删除id=1的account ...
- Caused by: java.lang.ClassNotFoundException: org.springframework.web.filter.FormContentFilter
又是一个报错,我写代码真的是可以,所有的bug都会被我遇到,所有的问题我都能踩一遍,以前上学的时候同学就喜欢问我问题,因为他们遇到的问题,我早就遇到了......... 看看报错内容: 2019-04 ...
- SpringMVC------报错:java.lang.ClassNotFoundException: org.springframework.web.filter.CharacterEncodingFilter
详细信息: java.lang.ClassNotFoundException: org.springframework.web.filter.CharacterEncodingFilter 严重: E ...
随机推荐
- wpf值转换器IValueConverter例子
转载:http://blog.163.com/wangzhenguo2005@126/blog/static/37140526201085113430862/ 值转换器可以把一种类型转换成另一种类型. ...
- C# TextBlock 上标
我需要做一个函数,显示 ,但是看起来用 TextBlock 做的不好看. 我用 WPF 写的上标看起来不好看,但是最后有了一个简单方法让他好看. 本文告诉大家如何做一个好看的上标. 一开始做的方法: ...
- Python和SQL 2017的强大功能
Python和SQL Server 2017的强大功能 原文来自:https://www.red-gate.com/simple-talk/sql/sql-development/power-py ...
- 工信部:我国4G用户近9.5亿 用户平均使用流量近2G
刚刚沿着广场转了一圈,我竟发现自己离他只有几步之遥,又在那条人行道上,刚才催促我前进的自豪感突然之间被惊慌代替.陌生人看着我,脸上流露出一种遗憾的表情,他向我靠近,轻轻摇着脑袋,像是为某个不受人控制的 ...
- Python并发编程__多进程
Python并发编程_多进程 multiprocessing模块介绍 python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu_count()查看),在python中大 ...
- Python线程的常见的lock
IO阻塞分析: 下面该需求很简单将一个数值100做自减处到0.主函数中有0.1秒的IO阻塞 import threading import time def sub(): global num # 掌 ...
- MySQL数据库主从复制实践
MySQL 主从(MySQL Replication),主要用于 MySQL 的实时备份.高可用HA.读写分离.在配置主从复制之前需要先准备 2 台 MySQL 服务器. 一.MySQL主从原 ...
- OOAD-设计模式(二)之GRASP模式与GOF设计模式概述
一.GRASP模式(通用责任分配软件模式)概述 1.1.理解责任 1)什么是责任 责任是类间的一种合约或义务,也可以理解成一个业务功能,包括行为.数据.对象的创建等 知道责任——表示知道什么 行为责任 ...
- GET_DDL提取目标元数据:ddl
创建对象的语句就是了 提取表 set line 200 pages 50000 wrap on long 999999 serveroutput on SQL> select dbms_meta ...
- Yii2之AR类的坑与总结
本文主要记录本人从学习yii2到使用yii2开发项目过程中遇到的一些问题以及解决方法和知识点总结. 1. AR类关联哪个数据表? 默认情况下,AR类会根据类名称关联和类名相关的数据表,如:类名为Cou ...