在SpringBoot中配置RequestContextListener

时间:2015-05-15 07:38:08

标签: spring spring-mvc spring-security spring-boot

我有一个使用Spring-Security的Spring-Boot应用程序。我有一个请求范围的bean,我想自动装入安全过滤器链中的一个自定义过滤器,但目前它不工作。

我知道在DispatcherServlet之外使用请求范围的bean需要一些配置,并且已经读过这个http://docs.spring.io/spring/docs/4.0.x/spring-framework-reference/html/beans.html#beans-factory-scopes-other但是还没有取得任何成功:

  

对于Servlet 3.0+,可以通过以编程方式完成   WebApplicationInitializer接口。

(我正在使用最新的Tomcat,因此是servlet 3 +)

我尝试过同时使用RequestContextListener和RequestContextFilter(文档说它们和DispatcherServlet完全相同),但在这两种情况下我仍然会收到错误,因为我的自动对象是空的:

我尝试注册过滤器

@Configuration
@ComponentScan
@EnableAutoConfiguration
class Application extends SpringBootServletInitializer  {

    @Override protected SpringApplicationBuilder configure( SpringApplicationBuilder application ) {
        application.sources( Application )
    }

    @Override public void onStartup( ServletContext servletContext ) throws ServletException {
        super.onStartup( servletContext )
        servletContext.addFilter("requestContextFilter", new RequestContextFilter() ).addMappingForUrlPatterns(null, false, "/*")
    }

我尝试注册听众

@Configuration
@ComponentScan
@EnableAutoConfiguration
class Application extends SpringBootServletInitializer  {

    @Override protected SpringApplicationBuilder configure( SpringApplicationBuilder application ) {
        application.sources( Application )
    }

    @Override public void onStartup( ServletContext servletContext ) throws ServletException {
        super.onStartup( servletContext )
        servletContext.addListener( new RequestContextListener() ) 
    }

我错过了一些明显的东西吗?我已经看过Spring Boot的自动配置源代码了,还没有找到任何东西。

更新

我是个白痴,我在我的SpringSecurity配置中添加了我的过滤器,在configure()方法中:

http.addFilterBefore( new PreAuthFilter(), BasicAuthenticationFilter )

但尚未将新过滤器注册为Bean。根据M. Denium在下面的评论,我并不需要所有额外的配置显式添加监听器/过滤器,只需注册bean就足够了。

1 个答案:

答案 0 :(得分:46)

如更新/评论中所详述,这是由我自己的愚蠢造成的。

Spring-Boot能够将请求/会话范围的bean自动装配到DispatcherServlet之外的过滤器中。根据Spring的文档,我们需要添加RequestContextListenerRequestContextFilter来启用此功能:

  

支持请求,会话和全局bean的范围   会话级别(web-scoped beans),一些次要的初始配置是   在定义bean之前需要。 (这个初始设置不是   标准示波器,单件和原型所需。)   ...

     

如果你在Spring Web MVC中访问scoped bean,实际上是在一个   由Spring DispatcherServlet处理的请求,或   DispatcherPortlet,则无需特殊设置:   DispatcherServlet和DispatcherPortlet已公开所有相关内容   状态。

为了解决这个问题,我需要注册一个RequestContextListener bean:

@Bean public RequestContextListener requestContextListener(){
    return new RequestContextListener();
} 

如果您没有注册该bean,您将收到一条错误消息,指出您正在尝试访问DispatcherServlet之外的Request范围。

我遇到的问题(自动对象没有被注入)是由于我只是将自定义过滤器注册为标准类实例,而不是Spring托管bean:

http.addFilterBefore( new PreAuthFilter(), BasicAuthenticationFilter )

要解决这个问题,我只是将PreAuthFilter的创建移到了一个sepearte @Bean方法,然后@Autowired功能正常运行。