shiro(3)-DelegatingFilterProxy的作用

目录
shiro(1)-架构
shiro(2)-有状态身份认证和无状态身份认证
shiro(3)-DelegatingFilterProxy的作用
shiro(4)-有状态认证-sessionManager会话
shiro(5)-有状态认证-Realm认证的实现
Shiro(6)-有状态认证-会话管理(整合Redis实现共享Session)
shiro(7)-有状态认证-会话管理(单处登录-改进版)

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();
}

而DelegatingFilterProxy是一个servlet filter的代理。它的优点如下:

  1. 通过spring容器来管理servlet filter的生命周期。
  2. 如果filter中需要Spring容器的实例,可以通过spring直接注入。
  3. 读取配置文件这些便利操作都可以通过Spring来配置实现。

首先在web.xml中配置:

<filter>
   <filter-name>myFilter</filter-name>
   <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
   <filter-name>myFilter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

然后再Spring的配置文件中,配置具体的Filter类的实例。

<bean name="myFilter"class="com.*.MyFilter"></bean>

需要注意的是:在Spring中配置的bean的name要和web.xml中的<filter-name>保持相同。

1. filter的配置

  1. 若不和<filter-name>保持相同

可以在DelegatingFilterProxy的filter配置初始化参数:targetBeanName,对应到Spring配置中的beanName。

   <filter>
        <filter-name>shiroFilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
        <!-- 设置spring容器filter的bean id,如果不设置则找与filter-name一致的bean-->
        <init-param>
            <param-name>targetBeanName</param-name>
            <param-value>shiroFilter</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>shiroFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
  1. 若保留Filter原有的init,destory方法调用

如果保留Filter原有的init、destory方法的调用,还需要配置初始化参数targetFilterLifecycle为true,该参数默认为false。

<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>
  </filter-mapping>

2. shiro的配置

一般情况下,创建一个Filter是交给自己来实现的。但是shiro的操作方式来看,这个反过来:spring提供了DelegatingFilterProxy作为通用Filter代理类,shiro以factoryBean的形式来构造自己的filter。

  • 利用初始化方法获取被代理的对象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);
    }
//以factoryBean的形式来构造自己的filter。
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。

转载于:https://www.jianshu.com/p/a7cd47f38d0c

猜你喜欢

转载自blog.csdn.net/weixin_34122548/article/details/91146398