我正在构建一个Spring Boot Web应用程序,并且我有一个请求范围的bean。
我正在使用spring安全性,并且需要访问过滤器链中的请求范围bean(pre DispatcherServlet
),所以我已注册RequestContextListener
以使其可用 - 这一切都正常:我可以将请求范围的bean自动装入我的过滤器链并使用它。但是,似乎请求作用域bean在spring安全过滤器链之后被重新初始化。
以下日志:
May 18 06:19:40 DEBUG [org.springframework.security.web.FilterChainProxy] /app/test at position 4 of 12 in additional filter chain; firing Filter: 'LogoutFilter'
May 18 06:19:40 DEBUG [org.springframework.security.web.util.matcher.AntPathRequestMatcher] Checking match of request : '/app/test'; against '/logout'
May 18 06:19:40 DEBUG [org.springframework.security.web.FilterChainProxy] /app/test at position 5 of 12 in additional filter chain; firing Filter: 'SystemSecurityFilter'
May 18 06:19:40 DEBUG [org.springframework.security.web.util.matcher.AntPathRequestMatcher] Checking match of request : '/app/test'; against '/________site-memory-status'
May 18 06:19:40 DEBUG [org.springframework.security.web.util.matcher.AntPathRequestMatcher] Checking match of request : '/app/test'; against '/________site-monitor'
May 18 06:19:40 DEBUG [org.springframework.security.web.FilterChainProxy] /app/test at position 6 of 12 in additional filter chain; firing Filter: 'RequestScopeFilter'
May 18 06:19:40 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] Creating instance of bean 'scopedTarget.requestScopedBean'
May 18 06:19:40 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] Returning cached instance of singleton bean 'application'
May 18 06:19:40 INFO [com.test.app] Creating RequestScopedBean.
May 18 06:19:40 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] Finished creating instance of bean 'scopedTarget.requestScopedBean'
May 18 06:19:40 DEBUG [org.springframework.security.web.FilterChainProxy] /app/test at position 7 of 12 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
May 18 06:19:40 DEBUG [org.springframework.security.web.FilterChainProxy] /app/test at position 8 of 12 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
May 18 06:19:40 DEBUG [org.springframework.security.web.FilterChainProxy] /app/test at position 9 of 12 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
May 18 06:19:40 DEBUG [org.springframework.security.web.FilterChainProxy] /app/test at position 10 of 12 in additional filter chain; firing Filter: 'SessionManagementFilter'
May 18 06:19:40 DEBUG [org.springframework.security.web.authentication.session.CompositeSessionAuthenticationStrategy] Delegating to org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy
May 18 06:19:40 DEBUG [org.springframework.security.web.FilterChainProxy] /app/test at position 11 of 12 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
May 18 06:19:40 DEBUG [org.springframework.security.web.FilterChainProxy] /app/test at position 12 of 12 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
May 18 06:19:40 DEBUG [org.springframework.security.web.access.intercept.FilterSecurityInterceptor] Secure object: FilterInvocation: URL: /app/test; Attributes: [permitAll]
May 18 06:19:40 DEBUG [org.springframework.security.access.vote.AffirmativeBased] Voter: org.springframework.security.web.access.expression.WebExpressionVoter, returned: 1
May 18 06:19:40 DEBUG [org.springframework.security.web.access.intercept.FilterSecurityInterceptor] Authorization successful
May 18 06:19:40 DEBUG [org.springframework.security.web.access.intercept.FilterSecurityInterceptor] RunAsManager did not change Authentication object
May 18 06:19:40 DEBUG [org.springframework.security.web.FilterChainProxy] /app/test reached end of additional filter chain; proceeding with original chain
May 18 06:19:40 INFO [com.test.app] Creating RequestScopedBean.
May 18 06:19:40 DEBUG [org.springframework.web.servlet.DispatcherServlet] DispatcherServlet with name 'dispatcherServlet' processing GET request for [/app/test]
May 18 06:19:40 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] Returning cached instance of singleton bean 'AppController'
您将看到" Creating RequestScopedBean" - 这是在我的请求范围bean的构造函数中记录的,并且被调用两次 - 一次调用我的自定义过滤器(RequestScopeFilter
),然后在过滤器链之后再次调用{{1 }}。这是预期的行为吗?看起来很奇怪它可以提前使用,但仍然可以在DispatchServlet
重新初始化 - 假设它只是可配置的,但无法在RequestContextListener上看到任何选项。我想也许我应该换成DispatcherServlet
并使用RequestContextFilter
方法来看看它是否达到了我想要的效果,但却无法找到关于何时使用其中一个的明确建议。 / p>
更新
好吧,这是一周内我第二次在SO上做了一个白痴 - 实际上Spring并没有两次初始化bean,这是我的过滤器被执行了两次而且我对请求范围bean所做的更改是记录同样的消息。
接下来的问题是为什么过滤器执行两次?我唯一的猜测是因为我已将过滤器注册为Spring setThreadContextInheritable
并将其明确添加到我的Spring过滤器链中。我应该更改为实现@Bean
还是有其他配置来阻止它作为我的Spring Security过滤器链的一部分执行?
答案 0 :(得分:1)
问题是由于我在过滤器中明确初始化了请求范围的bean(我在bean中设置了特定于请求的某些状态)并且愚蠢地记录了相同的消息。
根本原因是我的Filter被执行了两次,一次是作为Spring Security链的一部分,然后是Spring,因为我还将Filter注册为Spring bean,因此也自动添加为普通的Filter。