spring security源码分析_DelegatingFilterProxy

扫码关注公众号:Java 技术驿站

发送:vip
将链接复制到本浏览器,永久解锁本站全部文章

【公众号:Java 技术驿站】 【加作者微信交流技术,拉技术群】
免费领取10G资料包与项目实战视频资料

SpringSecurity3源码分析

web.xml中的过滤器:DelegatingFilterProxy

springSecurityFilterChain org.springframework.web.filter.DelegatingFilterProxy springSecurityFilterChain /\*

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关联起来。


来源:http://ddrv.cn/a/88268

赞(0) 打赏
版权归原创作者所有,任何形式的转载请联系博主:daming_90:Java 技术驿站 » spring security源码分析_DelegatingFilterProxy

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏