spring security源码分析_DelegatingFilterProxy

SpringSecurity3源码分析

web.xml中的过滤器:DelegatingFilterProxy

<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类位于spring-web-3.0.5.RELEASE.jar下面,说明这个类本身是和springSecurity无关。DelegatingFilterProxy类继承于抽象类GenericFilterBean,间接地实现了javax.servlet.Filter接口,Servlet容器在启动时,首先会调用Filter的init方法, GenericFilterBean的作用主要是可以把Filter的初始化参数自动地set到继承于GenericFilterBean类的Filter中去。在其init方法的如下代码就是做了这件事:

public final void init(FilterConfig filterConfig) throws ServletException {

                   Assert.notNull(filterConfig,”FilterConfig must not be null”);

                   if (logger.isDebugEnabled()) {

                            logger.debug(“Initializingfilter ‘” + filterConfig.getFilterName() + “‘”);

                   }

 

                   this.filterConfig = filterConfig;

 

                   // Set bean properties frominit parameters.

                   try {

                            PropertyValues pvs = newFilterConfigPropertyValues(filterConfig, this.requiredProperties);

                            BeanWrapperbw = PropertyAccessorFactory.forBeanPropertyAccess(this);

                            ResourceLoaderresourceLoader = newServletContextResourceLoader(filterConfig.getServletContext());

                            bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, this.environment));

                            initBeanWrapper(bw);

                            bw.setPropertyValues(pvs,true);

                   }

                   catch (BeansException ex) {

                            String msg = “Failedto set bean properties on filter ‘” +

                                     filterConfig.getFilterName()+ “‘: ” + ex.getMessage();

                            logger.error(msg,ex);

                            throw new NestedServletException(msg, ex);

                   }

 

                   // Let subclasses do whateverinitialization they like.

                   initFilterBean();

 

                   if (logger.isDebugEnabled()) {

                            logger.debug(“Filter'” + filterConfig.getFilterName() + “‘ configured successfully”);

                   }

         }

另外在init方法中调用了initFilterBean()方法,该方法是GenericFilterBean类是特地留给子类扩展用的:

@Override

         protected voidinitFilterBean() throws ServletException {

                   synchronized (this.delegateMonitor){

                            if (this.delegate== null) {

                                     // If notarget bean name specified, use filter name.

                                     if (this.targetBeanName== null) {

                                               this.targetBeanName= getFilterName();

                                     }

                                     // FetchSpring root application context and initialize the delegate early,

                                     // ifpossible. If the root application context will be started after this

                                     // filterproxy, we’ll have to resort to lazy initialization.

                                     WebApplicationContextwac = findWebApplicationContext();

                                     if(wac != null) {

                                               this.delegate= initDelegate(wac);

                                     }

                            }

                   }

         }

可以看出上述代码首先看Filter是否提供了targetBeanName初始化参数,如果没有提供则直接使用filter的name做为beanName,产生了beanName后,由于我们在web.xml的filter的name是springSecurityFilterChain,从spring的IOC容器中取出bean的代码是initDelegate方法,下面是该方法代码:

protected FilterinitDelegate(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方法。这个FilterChainProxybean实例最终被保存在DelegatingFilterProxy类的delegate属性里

下面看一下DelegatingFilterProxy类的doFilter方法:

public voiddoFilter(ServletRequest request, ServletResponse response, FilterChainfilterChain)

                            throwsServletException, IOException {

 

                   //Lazily initialize the delegate if necessary.

                   FilterdelegateToUse = this.delegate;

                   if(delegateToUse == null) {

                            synchronized(this.delegateMonitor) {

                                     if(this.delegate == null) {

                                               WebApplicationContextwac = findWebApplicationContext();

                                               if(wac == null) {

                                                        thrownew IllegalStateException(“No WebApplicationContext found: noContextLoaderListener 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方法来响应请求。

protected voidinvokeDelegate(

         Filterdelegate, ServletRequest request, ServletResponse response, FilterChainfilterChain)

         throwsServletException, IOException {

                   delegate.doFilter(request, response, filterChain);

         }

以上就是
DelegatingFilterProxy类的一些内部运行机制,其实主要作用就是一个代理模式的应用,可以把servlet 容器中的filter同spring容器中的bean关联起来。

    原文作者:Spring Cloud
    原文地址: https://blog.csdn.net/crazygeek_/article/details/41316507
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞