Spring启动 - 对每个请求运行检查并存储生命周期的对象

时间:2016-08-01 17:49:27

标签: spring spring-boot

我有一个场景,我需要在每个Web请求开始时运行一些db检查,并且在成功的情况下我需要存储对象以供控制器稍后在请求中使用,或者在失败我需要渲染错误页面。

一个非常类似的现实世界的例子是SaaS应用程序根据虚荣网址检查和加载帐户,然后存储帐户供控制器使用以避免多个数据库请求。

在Spring启动应用中实现此目的的最佳方法是什么?我已经尝试了过滤器,但我认为拦截器可能在任务上更好,包括运行检查但是如何存储对象供以后使用?是否存在某种我可以存储的请求生命周期上下文?

2 个答案:

答案 0 :(得分:1)

Spring supports request scope for beans。您可以使用它们来存储请求执行期间使用的数据。

答案 1 :(得分:1)

根据我的经验,我做过类似工作的最好方法是HandlerMethodArgumentResolver

基本上假设您有自定义类型,我们将其称为UserContext,您可以在其中存储请求所需的信息。你有一个UserContextService让我们说它有一个方法getUserContext(HttServletRequest),它用于根据请求检索上下文,你可以根据请求参数调用你的数据库/ header / path-variable等。您可以根据需要进行优化。但基于这个简单的假设,您可以拥有一个如下所示的控制器:

@RequestMapping("/some/url")
public SomeResponse someMethod(UserContext userContext, ...) {
    //do something here with UserContext
}

Spring会将此UserContext注入您的控制器的方式是使用这样的自定义HandlerMethodArgumentResolver

@Component
public class UserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {

    @Autowired
    UserContextService

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameterType().equals(UserContext.class);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        HttpServletRequest req = (HttpServletRequest)webRequest.getNativeRequest();
        UserContext userContext = userContextService.getUserContext(req);
        if (userContext != null) {
            return userContext;
        } else {
            return WebArgumentResolver.UNRESOLVED;
            //Or throw exception
        }
    }
}

您将通过覆盖WebMvcConfigurer.addArgumentResolvers bean / config-class中的WebMvcConfigurer方法进行注册。

此机制与@PathVariable@RequestParam等使用的机制相同......