(1). 概述
通过前面的源码分析,能得出一个结论:Spring Security会向Spring注册一个Filter(DelegatingFilterProxy),在这一小节,剖析:DelegatingFilterProxy的初始化过程.
(2). 看下DelegatingFilterProxy类关系图
从类的关系图上能得出以下几个结论(从结论来看,可以分成两步来分析,分析启动时的初始化,然后,再分析http请求):
- 实现了InitializingBean接口,所以,在容器初始化时,会回调:afterPropertiesSet.
- 实现了Filter接口,所以,在发起http请求时,会触发:doFilter方法(注意:这个优先级可比Spring MVC的DispatcherServlet还要早).
(3). DelegatingFilterProxy.doFilter
@Nullable
// FilterChainProxy
private volatile Filter delegate;
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws ServletException, IOException {
Filter delegateToUse = this.delegate;
if (delegateToUse == null) { // true
synchronized (this.delegateMonitor) { // 并发,控制代码块,同一时间,只有一个线程能运行.
delegateToUse = this.delegate;
if (delegateToUse == null) {
// 获取ApplicationContext
WebApplicationContext wac = findWebApplicationContext();
// 获取不到的情况下,抛出异常
if (wac == null) {
throw new IllegalStateException("No WebApplicationContext found: " + "no ContextLoaderListener or DispatcherServlet registered?");
}
// ****************************************************************************
// 从Spring容器中,获得Bean名称为:springSecurityFilterChain的Filter
// ****************************************************************************
delegateToUse = initDelegate(wac);
}
this.delegate = delegateToUse;
}
}
// *********************************************************************************
// 委派给:FilterChainProxy进行处理.
// *********************************************************************************
// Let the delegate perform the actual doFilter operation.
invokeDelegate(delegateToUse, request, response, filterChain);
}
(4). DelegatingFilterProxy.initDelegate
// 从Spring容器中,获得bean名称(springSecurityFilterChain)的Bean出来
protected Filter initDelegate(WebApplicationContext wac) throws ServletException {
// targetBeanName = springSecurityFilterChain
String targetBeanName = getTargetBeanName();
Assert.state(targetBeanName != null, "No target bean name set");
// 从Spring容器中获得
Filter delegate = wac.getBean(targetBeanName, Filter.class);
if (isTargetFilterLifecycle()) {
// 调用:FilterChainProxy.init方法,传递配置文件
delegate.init(getFilterConfig());
}
return delegate;
}
(5). DelegatingFilterProxy.invokeDelegate
// delegate = FilterChainProxy
protected void invokeDelegate(Filter delegate, ServletRequest request, ServletResponse response, FilterChain filterChain) throws ServletException, IOException {
delegate.doFilter(request, response, filterChain);
}
(6). 总结
DelegatingFilterProxy从Spring容器中拿出名称为:springSecurityFilterChain的对象(FilterChainProxy),最终:会把请求委派给了FilterChainProxy进行处理,其实,后面要关注的是那一堆的Filter.
FilterChainProxy的创建实则是在:WebSecurityConfiguration类里定义的.