代理过滤器

栏目: Java · 发布时间: 6年前

内容简介:DelegatingFilterProxy这个东西太熟悉了,在类似shiro和springsecurity的权限认证框架都有见到它的身影,但又陌生,印象似乎只停留在DelegatingFilterProxy把servlet 容器中的filter同spring容器中的bean关联起来,交由spring容器管理。DelegatingFilterProxy代理类把filter和IOC容器进行了结合在一起,从spring上下文寻找要代理的过滤类,执行初始化,过滤和销毁过程。下面结合springsecurity就翻翻

DelegatingFilterProxy这个东西太熟悉了,在类似shiro和springsecurity的权限认证框架都有见到它的身影,但又陌生,印象似乎只停留在DelegatingFilterProxy把servlet 容器中的filter同spring容器中的bean关联起来,交由spring容器管理。DelegatingFilterProxy代理类把filter和IOC容器进行了结合在一起,从spring上下文寻找要代理的过滤类,执行初始化,过滤和销毁过程。下面结合springsecurity就翻翻源码:

获取filter配置参数

DelegatingFilterProxy 继承了 GenericFilterBean ,父类实现了一堆接口:

public abstract class GenericFilterBean implements Filter, BeanNameAware, EnvironmentAware, EnvironmentCapable, ServletContextAware, InitializingBean, DisposableBean 
复制代码
  • BeanNameAware //返回当前的beanName
  • EnvironmentAware//读取配置文件
  • EnvironmentCapable//检查接受了BeanFactory接口的框架方法
  • ServletContextAware//获取ServletContext
  • InitializingBean//初始化bean对象
  • DisposableBean //销毁bean

父类中 init 方法将过滤器的参数配置传递给代理对象 源码如下:

public final void init(FilterConfig filterConfig) throws ServletException {
        Assert.notNull(filterConfig, "FilterConfig must not be null");
        this.filterConfig = filterConfig;
        PropertyValues pvs = new GenericFilterBean.FilterConfigPropertyValues(filterConfig, this.requiredProperties);
        if (!pvs.isEmpty()) {
            try {
                BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
                ResourceLoader resourceLoader = new ServletContextResourceLoader(filterConfig.getServletContext());
                Environment env = this.environment;
                if (env == null) {
                    env = new StandardServletEnvironment();
                }

                bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, (PropertyResolver)env));
                this.initBeanWrapper(bw);
                bw.setPropertyValues(pvs, true);
            } catch (BeansException var6) {
                String msg = "Failed to set bean properties on filter '" + filterConfig.getFilterName() + "': " + var6.getMessage();
                this.logger.error(msg, var6);
                throw new NestedServletException(msg, var6);
            }
        }
复制代码

bean对象初始化

获取目标对象的name。

protected void initFilterBean() throws ServletException {
        synchronized(this.delegateMonitor) {
            if (this.delegate == null) {
                if (this.targetBeanName == null) {
                    this.targetBeanName = this.getFilterName();
                }

                WebApplicationContext wac = this.findWebApplicationContext();
                if (wac != null) {
                    this.delegate = this.initDelegate(wac);
                }
            }

        }
    }
复制代码

初始化代理对象

在web.xml文件中配置的 org.springframework.web.context.ContextLoaderListener 实现加载Sping的上下文环境 (由XmlWebApplicationContent来装载)。 通过initDelegate(wac)得到代理过滤器

protected Filter initDelegate(WebApplicationContext wac) throws ServletException {
        String targetBeanName = this.getTargetBeanName();
        Assert.state(targetBeanName != null, "No target bean name set");
        Filter delegate = (Filter)wac.getBean(targetBeanName, Filter.class);
        if (this.isTargetFilterLifecycle()) {
            delegate.init(this.getFilterConfig());
        }

        return delegate;
    }
复制代码

代理执行过滤方法

在执行过滤方法之前,通过 invokeDelegate 调用delegate执行过滤方法

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

过滤方法

public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        Filter delegateToUse = this.delegate;
        if (delegateToUse == null) {
            synchronized(this.delegateMonitor) {
                delegateToUse = this.delegate;
                if (delegateToUse == null) {
                    WebApplicationContext wac = this.findWebApplicationContext();
                    if (wac == null) {
                        throw new IllegalStateException("No WebApplicationContext found: no ContextLoaderListener or DispatcherServlet registered?");
                    }

                    delegateToUse = this.initDelegate(wac);
                }

                this.delegate = delegateToUse;
            }
        }
复制代码

以上所述就是小编给大家介绍的《代理过滤器》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

追踪Linux TCP/IP代码运行

追踪Linux TCP/IP代码运行

秦健 / 北京航空航天大学出版社 / 2010-4-1 / 69.00元

本书以应用程序为线索,详细描述了数据包在协议栈的分段、重组、发送、接收过程,同时分析了路由的初始化和设置过程,主要包括socket应用程序、 TCP/IP协议、路由、通知链、邻居子系统等内容。全书涵盖了协议栈的全部知识点,对于广大的读者来说这是一本极其难得的技术资料。同时,书中论述了网络设备的工作原理,解释了RTL8169和嵌入式CS8900、DM9000网卡设备的核心过程。一起来看看 《追踪Linux TCP/IP代码运行》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

随机密码生成器
随机密码生成器

多种字符组合密码

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具