ObjectPostProcessor
介绍
笔者在学习Spring Security,调试HeaderWriterFilter源码时,遇到了一个比较困惑的问题,HeaderWriterFilter在往请求头写入信息时,通过shouldWriteHeadersEagerly这个变量来控制,在调用过滤器之前写入还是调用doFilter()之后将信息写入到请求头当中,默认是过滤链执行后写入。笔者以为可以在ResourceServerConfig#configure()方法中,调用HttpSecurity.headers()进行配置,但并没有找到配置方法。笔者把Spring Security源码给下到了本地,在官方的测试用例中找到了答案,而且与这篇文章要介绍的 ObjectPostProcessor有关,代码如下:
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
if (this.shouldWriteHeadersEagerly) {
doHeadersBefore(request, response, filterChain);
} else {
doHeadersAfter(request, response, filterChain);
}
}
@EnableWebSecurity
public static class HeadersAtTheBeginningOfRequestConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
//@ formatter:off
http
.headers()
.addObjectPostProcessor(new ObjectPostProcessor<HeaderWriterFilter>() {
@Override
public HeaderWriterFilter postProcess(HeaderWriterFilter filter) {
filter.setShouldWriteHeadersEagerly(true);
return filter;
}
});
//@ formatter:on
}
}
我们在学习Spring Security Filter源码的时候,会发现,相关的Filter都是以new的形式创建的,作为Java服务端开发,我们知道,new出来的对象是不受Spring Bean生命周期管控的。为了使这些Filter实例能够被Spring Bean容器管理,Spring Security定义了一个接口ObjectPostProcessor,AutowireBeanFactoryObjectPostProcessor实现了这个接口,通过postProcess方法手把Bean注入到spring容器进行管理。
代码分析
步骤1:AutowireBeanFactoryObjectPostProcessor
AutowireBeanFactoryObjectPostProcessor注册到Spring Bean容器,是通过@EnableWebSecurity注解一步步@Import实现的,代码如下:
// @EnableWebSecurity 注解代码片段,可以看到该注解隐含使用了@EnableGlobalMethodSecurity
@EnableGlobalAuthentication
@Configuration
public @interface EnableWebSecurity {
/**
* Controls debugging support for Spring Security. Default is false.
* @return if true, enables debug support with Spring Security
*/
boolean debug() default false;
}
// @EnableGlobalAuthentication 注解代码片段,可以看到它导入了类 AuthenticationConfiguration
@Import(AuthenticationConfiguration.class)