(1). 概述

在分析:DelegatingFilterProxy时,发现,内部又引用了一个Bean(springSecurityFilterChain),所以,要了解下:springSecurityFilterChain是在什么时候初始化的.                
我在分析SecurityAutoConfiguration时,只提了一嘴说:它导入了一堆的Bean,实际:springSecurityFilterChain的初始化就在这三个Import的Bean(SpringBootWebSecurityConfiguration/WebSecurityEnablerConfiguration/SecurityDataConfiguration)里定义的,只是定义比较深而已.            

(2). WebSecurityEnablerConfiguration

不拉出一些没有用的代码了,其实,最终的关注点是在这个注解上@EnableWebSecurity,你会发现:这个注解又导入了其它的Bean,我们重点关注:WebSecurityConfiguration

@Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@Target(value = { java.lang.annotation.ElementType.TYPE })
@Documented
// *******************************************************************************
// 导入了其它的Bean(WebSecurityConfiguration/SpringWebMvcImportSelector)
// *******************************************************************************
@Import({ WebSecurityConfiguration.class, SpringWebMvcImportSelector.class })
@EnableGlobalAuthentication
@Configuration
public @interface EnableWebSecurity {
	boolean debug() default false;
}

(3). WebSecurityConfiguration

WebSecurityConfiguration的职责如下:

  • 创建:AutowiredWebSecurityConfigurersIgnoreParents,通过它,可以获得,Spring中自定义的所有:WebSecurityConfigurer集合.
  • 新创建一个WebSecurity,把上一步所有的WebSecurityConfigurer中的配置,设置到新创建的:WebSecurity上.
  • 委托给WebSecurity去创建:springSecurityFilterChain(Filter),这个过程,放到下一小节,进行剖析.
@Configuration
public class WebSecurityConfiguration implements ImportAware, BeanClassLoaderAware {
	private WebSecurity webSecurity;

	private Boolean debugEnabled;

	private List<SecurityConfigurer<Filter, WebSecurity>> webSecurityConfigurers;

	private ClassLoader beanClassLoader;

	@Autowired(required = false)
	private ObjectPostProcessor<Object> objectObjectPostProcessor;
	

    // ****************************************************************************************************
	//  1. AutowiredWebSecurityConfigurersIgnoreParents的作用在于:从Spring容器中,找出:WebSecurityConfigurer的实现.
	//  beanFactory.getBeansOfType(WebSecurityConfigurer.class);
	// ****************************************************************************************************
	@Bean
	public static AutowiredWebSecurityConfigurersIgnoreParents autowiredWebSecurityConfigurersIgnoreParents(
			ConfigurableListableBeanFactory beanFactory) {
		return new AutowiredWebSecurityConfigurersIgnoreParents(beanFactory);
	} // end AutowiredWebSecurityConfigurersIgnoreParents
	
	
	// ****************************************************************************************************
	// 2. setFilterChainProxySecurityConfigurer方法,用于获取所有的:WebSecurityConfigurer,并设置到:new出来的:WebSecurity对象上面.
	// ****************************************************************************************************
	@Autowired(required = false)
	public void setFilterChainProxySecurityConfigurer(
			// 
			ObjectPostProcessor<Object> objectPostProcessor,
			// ************************************************************************************
			// 3. 调用:autowiredWebSecurityConfigurersIgnoreParents.getWebSecurityConfigurers()方法
			//    获得所有的:SecurityConfigurer集合
			//    这也是为了什么,Spring Security支持配置:SecurityConfigurer
			// ************************************************************************************
			@Value("#{@autowiredWebSecurityConfigurersIgnoreParents.getWebSecurityConfigurers()}") List<SecurityConfigurer<Filter, WebSecurity>> webSecurityConfigurers) throws Exception {
		
		// *************************************************************************************
		// 4. new WebSecurity
		//    把WebSecurity交给:AutowireBeanFactoryObjectPostProcessor,目的在于,让WebSecurity支持Spring的生命周期(DisposableBean/SmartInitializingSingleton).
		// *************************************************************************************
		webSecurity = objectPostProcessor.postProcess(new WebSecurity(objectPostProcessor));
		if (debugEnabled != null) {
			webSecurity.debug(debugEnabled);
		}
		
		// 对List集合进行排序.
		Collections.sort(webSecurityConfigurers, AnnotationAwareOrderComparator.INSTANCE);
		
		
		Integer previousOrder = null;
		Object previousConfig = null;
		for (SecurityConfigurer<Filter, WebSecurity> config : webSecurityConfigurers) {
			Integer order = AnnotationAwareOrderComparator.lookupOrder(config);
			if (previousOrder != null && previousOrder.equals(order)) {
				throw new IllegalStateException(
						"@Order on WebSecurityConfigurers must be unique. Order of " + order + " was already used on " + previousConfig + ", so it cannot be used on " + config + " too.");
			}
			previousOrder = order;
			previousConfig = config;
		}
		
		// *************************************************************************************
		// 5. 遍历容器中所有的:SecurityConfigurer,并设置到刚new出来的:WebSecurity上
		// *************************************************************************************
		for (SecurityConfigurer<Filter, WebSecurity> webSecurityConfigurer : webSecurityConfigurers) {
			webSecurity.apply(webSecurityConfigurer);
		}
		this.webSecurityConfigurers = webSecurityConfigurers;
	} // end setFilterChainProxySecurityConfigurer
	
		
	// 6. 实例化一个事件监听器(不重要)	
	@Bean
	public static DelegatingApplicationListener delegatingApplicationListener() {
		return new DelegatingApplicationListener();
	} //end delegatingApplicationListener
	
    
	// *************************************************************************************
	// 7. 创建一个Bean(Filter),Bean名称为:springSecurityFilterChain
	// *************************************************************************************
	@Bean(name = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME)
	public Filter springSecurityFilterChain() throws Exception {
		boolean hasConfigurers = webSecurityConfigurers != null && !webSecurityConfigurers.isEmpty();
		if (!hasConfigurers) {
			WebSecurityConfigurerAdapter adapter = objectObjectPostProcessor.postProcess(new WebSecurityConfigurerAdapter() {});
			webSecurity.apply(adapter);
		}
		// *************************************************************************************
		// 通过:WebSecurity.build方法,构建出:springSecurityFilterChain=Filter
		//     springSecurityFilterChain是什么?有什么?留到下一小节去剖析.   
		// *************************************************************************************
		return webSecurity.build();
	}// end springSecurityFilterChain
}

(4). 总结

SecurityConfigurer是Spring Secruity预留出来给我们进行配置的,最终会把SecurityConfigurer向核心的:WebSecurity靠扰,至于:WebSecurity是如何构建出:springSecurityFilterChain(Filter),留到下一小节来剖析.