在我的 Spring Boot 应用程序中,对于应用程序服务的每个请求,我需要像
timezone, locale, language
等数据。
目前,每个控制器/处理程序负责自行获取此信息。有没有办法将这些信息放在某种上下文中,这样我们就不必每次在不同的地方查询这些信息?我不希望流程像这样:
MyContext
上设置这些值。这些值应该可以在下游的任何地方访问。MyContext.getTimeZone
等从问题看来,每个请求需要存储的信息都是不同的。为此,我将使用
request
作用域 bean。 Spring 作用域文档这里。
我将提供最小的例子。我们需要创建一个 bean,然后配置应用程序以在到达控制器层之前调用它的一些方法。
首先我们创建一个带有请求上下文的 bean。
@Service
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class MyContext {
// ...
}
将为每个请求创建此类的新实例。
@Service
@Slf4j
public class MyHandlerInterceptor implements HandlerInterceptor {
private final MyContext myContext;
@Autowired
public MyHandlerInterceptor(MyContext myContext) {
this.myContext = myContext;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// your logic to set context
myContext.setAnything();
return true;
}
// ...
}
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private MyHandlerInterceptor myHandlerInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(myHandlerInterceptor).addPathPatterns("/**");
}
}
这将注册您定义的拦截器,并确保在执行到达您的控制器之前调用
preHandle
。
除了 HandlerInterceptors,你可以使用 filters 来实现基本相同的效果。