DelegatingFilterProxy干了什么?

org.springframework.web.filter.DelegatingFilterProxy

一般情况,创建一个Filter是交给自己来实现的。基于servlet规范,在web.xml中配置,自定义filter实现Filter接口:

public interface Filter {
    void init(FilterConfig var1) throws ServletException;

    void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;

    void destroy();
}

但是从shiro的操作方式来看,这个反过来了:spring提供了DelegatingFilterProxy作为通用Filter代理类,shiro以factoryBean的形式来构造自己的filter。

那么这个DelegatingFilterProxy究竟干了些什么?

  • 利用初始化方法获取被代理的对象delegate
protected Filter initDelegate(WebApplicationContext wac) throws ServletException {
    Filter delegate = wac.getBean(getTargetBeanName(), Filter.class);
    if (isTargetFilterLifecycle()) {
        delegate.init(getFilterConfig());
    }
    return delegate;
}
  • 通过doFilter方法来调用目标过滤器的doFilter方法
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {

        // Lazily initialize the delegate if necessary.
        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;
            }
        }

        // Let the delegate perform the actual doFilter operation.
        invokeDelegate(delegateToUse, request, response, filterChain);
    }

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

    delegate.doFilter(request, response, filterChain);
}
  • 通过destory方法来释放一些资源
@Override
public void destroy() {
    Filter delegateToUse = this.delegate;
    if (delegateToUse != null) {
        destroyDelegate(delegateToUse);
    }
}

protected void destroyDelegate(Filter delegate) {
    if (isTargetFilterLifecycle()) {
        delegate.destroy();
    }
}

这个三个操作就完全将详细的实现转移到被代理的Filter。因为spring是所有bean的容器,这个filter的实际创建就交给了其它框架,但是前提是,这些框架必须要实现FactoryBean接口。所以有了shiro的ShiroFilterFactoryBean(springSecurity原理应该跟这个差不多)。

原文地址:https://www.cnblogs.com/lucare/p/8679135.html